├── element-admin ├── 管理端文档.txt ├── src │ ├── App.vue │ ├── assets │ │ ├── logo.png │ │ ├── test.png │ │ ├── password-icon.png │ │ └── username-icon.png │ ├── plugins │ │ └── element.js │ ├── http.js │ ├── main.js │ ├── views │ │ ├── setting │ │ │ ├── pay.vue │ │ │ ├── printer.vue │ │ │ ├── store.vue │ │ │ └── freight.vue │ │ ├── login │ │ │ ├── login.vue │ │ │ └── reg.vue │ │ ├── main.vue │ │ ├── data │ │ │ ├── price.vue │ │ │ ├── wx_user.vue │ │ │ └── category.vue │ │ └── promotion │ │ │ ├── hot.vue │ │ │ ├── recommend.vue │ │ │ ├── coupon.vue │ │ │ └── seckilling.vue │ └── router │ │ └── index.js ├── babel.config.js ├── public │ ├── favicon.ico │ └── index.html ├── .gitignore ├── README.md └── package.json ├── uni-wxmp-catering ├── 说明文档.txt ├── .DS_Store ├── static │ ├── time.png │ ├── arrow-right.png │ ├── public │ │ ├── add.png │ │ ├── empty.png │ │ ├── order.png │ │ ├── share.png │ │ ├── search.png │ │ ├── cart-dot.png │ │ └── subtract.png │ ├── search │ │ ├── del.png │ │ └── search_empty.png │ ├── tabbar │ │ ├── my-on.png │ │ ├── home-on.png │ │ ├── my-off.png │ │ ├── finish-off.png │ │ ├── finish-on.png │ │ └── home-off.png │ ├── personal │ │ ├── call.png │ │ ├── order.png │ │ ├── user.png │ │ ├── coupons.png │ │ ├── message.png │ │ ├── neworder.png │ │ ├── region.png │ │ ├── scancode.png │ │ └── empty_goods.png │ ├── create-order │ │ ├── add.png │ │ ├── change.png │ │ ├── addr-line.png │ │ ├── location.png │ │ └── location-off.png │ ├── order-details │ │ ├── 已关闭.png │ │ ├── 已完成.png │ │ ├── 待付款.png │ │ ├── 待发货.png │ │ └── 待收货.png │ ├── order-list │ │ └── no-order.png │ └── components │ │ ├── dialog │ │ └── close.png │ │ └── navigation │ │ └── back.png ├── uni_modules │ ├── uni-popup │ │ ├── components │ │ │ ├── uni-popup │ │ │ │ ├── i18n │ │ │ │ │ ├── zh-Hans.json │ │ │ │ │ ├── zh-Hant.json │ │ │ │ │ ├── en.json │ │ │ │ │ └── index.js │ │ │ │ ├── popup.js │ │ │ │ └── keypress.js │ │ │ ├── uni-popup-dialog │ │ │ │ ├── keypress.js │ │ │ │ └── uni-popup-dialog.vue │ │ │ ├── uni-popup-message │ │ │ │ └── uni-popup-message.vue │ │ │ └── uni-popup-share │ │ │ │ └── uni-popup-share.vue │ │ ├── changelog.md │ │ ├── package.json │ │ └── readme.md │ └── uni-transition │ │ ├── changelog.md │ │ ├── package.json │ │ ├── components │ │ └── uni-transition │ │ │ ├── createAnimation.js │ │ │ └── uni-transition.vue │ │ └── readme.md ├── utils │ ├── addmul.wxs │ ├── dateUtil.wxs │ ├── util.js │ └── wxTimer.js ├── index.html ├── .hbuilderx │ └── launch.json ├── api │ └── api.js ├── pages.json ├── uni.scss ├── components │ ├── navigation │ │ └── navigation.vue │ └── dialog │ │ └── dialog.vue ├── manifest.json ├── main.js ├── App.vue └── pages │ └── coupon-list │ └── index.vue ├── node-api-serve ├── 安装命令和目录结构.txt ├── models │ ├── hot.js │ ├── recommend.js │ ├── category.js │ ├── user.js │ ├── wx_setting.js │ ├── feie_setting.js │ ├── dada_setting.js │ ├── seckilling.js │ ├── banner.js │ ├── wx_user.js │ ├── coupon.js │ ├── goods.js │ ├── order.js │ └── setting.js ├── plugins │ └── db.js ├── package.json ├── cert │ └── 证书使用说明.txt ├── utils │ ├── dada │ │ └── signature.js │ ├── WXBizDataCrypt.js │ ├── utils.js │ └── wxpay.js └── index.js └── README.md /element-admin/管理端文档.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/element-admin/管理端文档.txt -------------------------------------------------------------------------------- /uni-wxmp-catering/说明文档.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/说明文档.txt -------------------------------------------------------------------------------- /element-admin/src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /node-api-serve/安装命令和目录结构.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/node-api-serve/安装命令和目录结构.txt -------------------------------------------------------------------------------- /uni-wxmp-catering/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/.DS_Store -------------------------------------------------------------------------------- /element-admin/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /element-admin/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/element-admin/public/favicon.ico -------------------------------------------------------------------------------- /element-admin/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/element-admin/src/assets/logo.png -------------------------------------------------------------------------------- /element-admin/src/assets/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/element-admin/src/assets/test.png -------------------------------------------------------------------------------- /uni-wxmp-catering/static/time.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/static/time.png -------------------------------------------------------------------------------- /uni-wxmp-catering/static/arrow-right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/static/arrow-right.png -------------------------------------------------------------------------------- /uni-wxmp-catering/static/public/add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/static/public/add.png -------------------------------------------------------------------------------- /uni-wxmp-catering/static/public/empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/static/public/empty.png -------------------------------------------------------------------------------- /uni-wxmp-catering/static/public/order.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/static/public/order.png -------------------------------------------------------------------------------- /uni-wxmp-catering/static/public/share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/static/public/share.png -------------------------------------------------------------------------------- /uni-wxmp-catering/static/search/del.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/static/search/del.png -------------------------------------------------------------------------------- /uni-wxmp-catering/static/tabbar/my-on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/static/tabbar/my-on.png -------------------------------------------------------------------------------- /element-admin/src/assets/password-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/element-admin/src/assets/password-icon.png -------------------------------------------------------------------------------- /element-admin/src/assets/username-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/element-admin/src/assets/username-icon.png -------------------------------------------------------------------------------- /uni-wxmp-catering/static/personal/call.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/static/personal/call.png -------------------------------------------------------------------------------- /uni-wxmp-catering/static/personal/order.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/static/personal/order.png -------------------------------------------------------------------------------- /uni-wxmp-catering/static/personal/user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/static/personal/user.png -------------------------------------------------------------------------------- /uni-wxmp-catering/static/public/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/static/public/search.png -------------------------------------------------------------------------------- /uni-wxmp-catering/static/tabbar/home-on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/static/tabbar/home-on.png -------------------------------------------------------------------------------- /uni-wxmp-catering/static/tabbar/my-off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/static/tabbar/my-off.png -------------------------------------------------------------------------------- /uni-wxmp-catering/static/create-order/add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/static/create-order/add.png -------------------------------------------------------------------------------- /uni-wxmp-catering/static/order-details/已关闭.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/static/order-details/已关闭.png -------------------------------------------------------------------------------- /uni-wxmp-catering/static/order-details/已完成.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/static/order-details/已完成.png -------------------------------------------------------------------------------- /uni-wxmp-catering/static/order-details/待付款.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/static/order-details/待付款.png -------------------------------------------------------------------------------- /uni-wxmp-catering/static/order-details/待发货.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/static/order-details/待发货.png -------------------------------------------------------------------------------- /uni-wxmp-catering/static/order-details/待收货.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/static/order-details/待收货.png -------------------------------------------------------------------------------- /uni-wxmp-catering/static/personal/coupons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/static/personal/coupons.png -------------------------------------------------------------------------------- /uni-wxmp-catering/static/personal/message.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/static/personal/message.png -------------------------------------------------------------------------------- /uni-wxmp-catering/static/personal/neworder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/static/personal/neworder.png -------------------------------------------------------------------------------- /uni-wxmp-catering/static/personal/region.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/static/personal/region.png -------------------------------------------------------------------------------- /uni-wxmp-catering/static/personal/scancode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/static/personal/scancode.png -------------------------------------------------------------------------------- /uni-wxmp-catering/static/public/cart-dot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/static/public/cart-dot.png -------------------------------------------------------------------------------- /uni-wxmp-catering/static/public/subtract.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/static/public/subtract.png -------------------------------------------------------------------------------- /uni-wxmp-catering/static/tabbar/finish-off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/static/tabbar/finish-off.png -------------------------------------------------------------------------------- /uni-wxmp-catering/static/tabbar/finish-on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/static/tabbar/finish-on.png -------------------------------------------------------------------------------- /uni-wxmp-catering/static/tabbar/home-off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/static/tabbar/home-off.png -------------------------------------------------------------------------------- /uni-wxmp-catering/static/create-order/change.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/static/create-order/change.png -------------------------------------------------------------------------------- /uni-wxmp-catering/static/order-list/no-order.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/static/order-list/no-order.png -------------------------------------------------------------------------------- /uni-wxmp-catering/static/search/search_empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/static/search/search_empty.png -------------------------------------------------------------------------------- /uni-wxmp-catering/static/create-order/addr-line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/static/create-order/addr-line.png -------------------------------------------------------------------------------- /uni-wxmp-catering/static/create-order/location.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/static/create-order/location.png -------------------------------------------------------------------------------- /uni-wxmp-catering/static/personal/empty_goods.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/static/personal/empty_goods.png -------------------------------------------------------------------------------- /uni-wxmp-catering/static/components/dialog/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/static/components/dialog/close.png -------------------------------------------------------------------------------- /uni-wxmp-catering/static/components/navigation/back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/static/components/navigation/back.png -------------------------------------------------------------------------------- /uni-wxmp-catering/static/create-order/location-off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sword2022/super-shop/HEAD/uni-wxmp-catering/static/create-order/location-off.png -------------------------------------------------------------------------------- /element-admin/src/plugins/element.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Element from 'element-ui' 3 | import 'element-ui/lib/theme-chalk/index.css' 4 | 5 | Vue.use(Element) 6 | -------------------------------------------------------------------------------- /element-admin/src/http.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | //服务端域名 3 | const http = axios.create({ 4 | baseURL:'https://www123456789.qicp.vip/api/admin' 5 | }) 6 | 7 | export default http 8 | -------------------------------------------------------------------------------- /uni-wxmp-catering/uni_modules/uni-popup/components/uni-popup/i18n/zh-Hans.json: -------------------------------------------------------------------------------- 1 | { 2 | "uni-popup.cancel": "取消", 3 | "uni-popup.ok": "确定", 4 | "uni-popup.placeholder": "请输入", 5 | "uni-popup.title": "提示", 6 | "uni-popup.shareTitle": "分享到" 7 | } 8 | -------------------------------------------------------------------------------- /uni-wxmp-catering/uni_modules/uni-popup/components/uni-popup/i18n/zh-Hant.json: -------------------------------------------------------------------------------- 1 | { 2 | "uni-popup.cancel": "取消", 3 | "uni-popup.ok": "確定", 4 | "uni-popup.placeholder": "請輸入", 5 | "uni-popup.title": "提示", 6 | "uni-popup.shareTitle": "分享到" 7 | } 8 | -------------------------------------------------------------------------------- /node-api-serve/models/hot.js: -------------------------------------------------------------------------------- 1 | const mongoose=require('mongoose') 2 | const schema=new mongoose.Schema({ 3 | sort:{type:Number},//排序 4 | parent:{type:mongoose.SchemaTypes.ObjectId,ref:'Goods'}//父级 5 | }) 6 | 7 | module.exports = mongoose.model('Hot',schema) -------------------------------------------------------------------------------- /uni-wxmp-catering/uni_modules/uni-popup/components/uni-popup/i18n/en.json: -------------------------------------------------------------------------------- 1 | { 2 | "uni-popup.cancel": "cancel", 3 | "uni-popup.ok": "ok", 4 | "uni-popup.placeholder": "pleace enter", 5 | "uni-popup.title": "Hint", 6 | "uni-popup.shareTitle": "Share to" 7 | } 8 | -------------------------------------------------------------------------------- /uni-wxmp-catering/uni_modules/uni-popup/components/uni-popup/i18n/index.js: -------------------------------------------------------------------------------- 1 | import en from './en.json' 2 | import zhHans from './zh-Hans.json' 3 | import zhHant from './zh-Hant.json' 4 | export default { 5 | en, 6 | 'zh-Hans': zhHans, 7 | 'zh-Hant': zhHant 8 | } 9 | -------------------------------------------------------------------------------- /node-api-serve/models/recommend.js: -------------------------------------------------------------------------------- 1 | const mongoose=require('mongoose') 2 | const schema=new mongoose.Schema({ 3 | sort:{type:Number},//排序 4 | parent:{type:mongoose.SchemaTypes.ObjectId,ref:'Goods'}//父级 5 | }) 6 | 7 | module.exports = mongoose.model('Recommend',schema) -------------------------------------------------------------------------------- /node-api-serve/models/category.js: -------------------------------------------------------------------------------- 1 | const mongoose=require('mongoose') 2 | const schema=new mongoose.Schema({ 3 | name:{type:String}, 4 | image:{type:String}, 5 | parent:{type:mongoose.SchemaTypes.ObjectId,ref:'Category'},//父级 6 | }) 7 | 8 | module.exports = mongoose.model('Category',schema) -------------------------------------------------------------------------------- /node-api-serve/models/user.js: -------------------------------------------------------------------------------- 1 | const mongoose=require('mongoose') 2 | const schema=new mongoose.Schema({ 3 | username:{type:String}, 4 | password:{ 5 | type:String,set(val){ 6 | return require('bcrypt').hashSync(val,10) 7 | }} 8 | }) 9 | module.exports=mongoose.model('User',schema) -------------------------------------------------------------------------------- /node-api-serve/plugins/db.js: -------------------------------------------------------------------------------- 1 | module.exports = app=>{ 2 | const mongoose=require('mongoose') 3 | mongoose.connect('mongodb://127.0.0.1:27017/myshop-db',{ 4 | useNewUrlParser:true, 5 | useUnifiedTopology:true, 6 | useCreateIndex:true, 7 | useFindAndModify:false 8 | }) 9 | } -------------------------------------------------------------------------------- /node-api-serve/models/wx_setting.js: -------------------------------------------------------------------------------- 1 | const mongoose=require('mongoose') 2 | const schema=new mongoose.Schema({ 3 | // 微信小程序 4 | appid:{type:String}, 5 | secret:{type:String}, 6 | //微信商户信息 7 | mchid:{type:String}, 8 | mchkey:{type:String}, 9 | }) 10 | 11 | module.exports = mongoose.model('WxSetting',schema) -------------------------------------------------------------------------------- /element-admin/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw? 22 | -------------------------------------------------------------------------------- /node-api-serve/models/feie_setting.js: -------------------------------------------------------------------------------- 1 | const mongoose=require('mongoose') 2 | const schema=new mongoose.Schema({ 3 | user:{type:String},//飞鹅云 www.feieyun.cn后台注册的账号名 4 | ukey:{type:String},//飞鹅云后台注册账号后生成的UKEY 5 | printer_sn:{type:String},//打印机SN 6 | printer_key:{type:String},//打印机KEY 7 | }) 8 | 9 | module.exports = mongoose.model('FeiESetting',schema) -------------------------------------------------------------------------------- /node-api-serve/models/dada_setting.js: -------------------------------------------------------------------------------- 1 | const mongoose=require('mongoose') 2 | const schema=new mongoose.Schema({ 3 | // 达达商户信息 4 | source_id:{type:String},//达达商户SourceID 5 | shop_no:{type:String},//门店编号 6 | //达达开发者信息 7 | app_key:{type:String}, 8 | app_sercret:{type:String}, 9 | }) 10 | 11 | module.exports = mongoose.model('DaDaSetting',schema) -------------------------------------------------------------------------------- /node-api-serve/models/seckilling.js: -------------------------------------------------------------------------------- 1 | const mongoose=require('mongoose') 2 | const schema=new mongoose.Schema({ 3 | sort:{type:Number},//排序 4 | image:{type:String},//图片 5 | start_time:{type:String},//秒杀开始 6 | end_time:{type:String},//秒杀结束 7 | parent:{type:mongoose.SchemaTypes.ObjectId,ref:'Goods'}//父级 8 | }) 9 | 10 | module.exports = mongoose.model('Seckilling',schema) -------------------------------------------------------------------------------- /element-admin/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | import './plugins/element.js' 4 | import router from './router' 5 | import http from './http' 6 | import Croppa from 'vue-croppa'; 7 | 8 | Vue.use(Croppa); 9 | 10 | Vue.config.productionTip = false 11 | Vue.prototype.$http = http 12 | 13 | new Vue({ 14 | router, 15 | render: h => h(App) 16 | }).$mount('#app') 17 | -------------------------------------------------------------------------------- /node-api-serve/models/banner.js: -------------------------------------------------------------------------------- 1 | const mongoose=require('mongoose') 2 | const schema=new mongoose.Schema({ 3 | sort:{type:Number},//排序 4 | type:{type:Number},//商品或分类 5 | parent_goods:{type:mongoose.SchemaTypes.ObjectId,ref:'Goods'},//父级 6 | parent_category:{type:mongoose.SchemaTypes.ObjectId,ref:'Category'},//父级 7 | image:{type:String},//图片 8 | }) 9 | module.exports = mongoose.model('Banner',schema) -------------------------------------------------------------------------------- /node-api-serve/models/wx_user.js: -------------------------------------------------------------------------------- 1 | const mongoose=require('mongoose') 2 | const schema=new mongoose.Schema({ 3 | phone:{type:String}, 4 | openid:{type:String}, 5 | session_key:{type:String}, 6 | nick_name:{type:String}, 7 | avatar:{type:String}, 8 | coupons:{type:Array}, 9 | neworder_subscribe_message:{type:Boolean},//新订单订阅消息 10 | }) 11 | module.exports=mongoose.model('WxUser',schema) -------------------------------------------------------------------------------- /uni-wxmp-catering/utils/addmul.wxs: -------------------------------------------------------------------------------- 1 | var filters = { 2 | toFix2: function (value) { 3 | return value.toFixed(2); //此处2为保留两位小数 4 | }, 5 | toFix1: function (value) { 6 | return value.toFixed(1); //此处1为保留一位小数 7 | }, 8 | toFix: function (value) { 9 | return value.toFixed(0); //此处0为取整数 10 | } 11 | }; 12 | module.exports = { 13 | toFix2: filters.toFix2, 14 | toFix1: filters.toFix1, 15 | toFix: filters.toFix 16 | }; -------------------------------------------------------------------------------- /uni-wxmp-catering/uni_modules/uni-transition/changelog.md: -------------------------------------------------------------------------------- 1 | ## 1.2.0(2021-07-30) 2 | - 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) 3 | ## 1.1.1(2021-05-12) 4 | - 新增 示例地址 5 | - 修复 示例项目缺少组件的Bug 6 | ## 1.1.0(2021-04-22) 7 | - 新增 通过方法自定义动画 8 | - 新增 custom-class 非 NVUE 平台支持自定义 class 定制样式 9 | - 优化 动画触发逻辑,使动画更流畅 10 | - 优化 支持单独的动画类型 11 | - 优化 文档示例 12 | ## 1.0.2(2021-02-05) 13 | - 调整为uni_modules目录规范 14 | -------------------------------------------------------------------------------- /uni-wxmp-catering/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /element-admin/README.md: -------------------------------------------------------------------------------- 1 | # myshop-admin 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Run your tests 19 | ``` 20 | npm run test 21 | ``` 22 | 23 | ### Lints and fixes files 24 | ``` 25 | npm run lint 26 | ``` 27 | 28 | ### Customize configuration 29 | See [Configuration Reference](https://cli.vuejs.org/config/). 30 | -------------------------------------------------------------------------------- /uni-wxmp-catering/uni_modules/uni-popup/components/uni-popup/popup.js: -------------------------------------------------------------------------------- 1 | 2 | export default { 3 | data() { 4 | return { 5 | 6 | } 7 | }, 8 | created(){ 9 | this.popup = this.getParent() 10 | }, 11 | methods:{ 12 | /** 13 | * 获取父元素实例 14 | */ 15 | getParent(name = 'uniPopup') { 16 | let parent = this.$parent; 17 | let parentName = parent.$options.name; 18 | while (parentName !== name) { 19 | parent = parent.$parent; 20 | if (!parent) return false 21 | parentName = parent.$options.name; 22 | } 23 | return parent; 24 | }, 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /uni-wxmp-catering/.hbuilderx/launch.json: -------------------------------------------------------------------------------- 1 | { // launch.json 配置了启动调试时相关设置,configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/ 2 | // launchtype项可配置值为local或remote, local代表前端连本地云函数,remote代表前端连云端云函数 3 | "version": "0.0", 4 | "configurations": [{ 5 | "default" : 6 | { 7 | "launchtype" : "local" 8 | }, 9 | "h5" : 10 | { 11 | "launchtype" : "local" 12 | }, 13 | "mp-weixin" : 14 | { 15 | "launchtype" : "local" 16 | }, 17 | "type" : "uniCloud" 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /node-api-serve/models/coupon.js: -------------------------------------------------------------------------------- 1 | const mongoose=require('mongoose') 2 | const schema=new mongoose.Schema({ 3 | name:{type:String},//优惠卷名称 4 | mode:{type:String},//优惠方式,1:满减,2:立减 5 | satisfy:{type:Number},//需满足金额 6 | reduce:{type:Number},//优惠金额 7 | total:{type:Number},//优惠卷总数 8 | gets:{type:Number},//已领取数量 9 | used:{type:Number},//已使用数量 10 | release_start_time:{type:String},//发卷开始时间 11 | release_end_time:{type:String},//发卷结束时间时间 12 | use_start_time:{type:String},//使用开始时间 13 | use_end_time:{type:String},//使用结束时间 14 | create_time:{type:String},//创建时间 15 | }) 16 | 17 | module.exports = mongoose.model('Coupon',schema) -------------------------------------------------------------------------------- /node-api-serve/models/goods.js: -------------------------------------------------------------------------------- 1 | const mongoose=require('mongoose') 2 | const schema=new mongoose.Schema({ 3 | name:{type:String},//商品名 4 | barcode:{type:Number},//条码 5 | detail:{type:String},//详情 6 | weight:{type:Number},//重量 7 | price:{type:Number},//价格 8 | line_price:{type:Number},//价格 9 | inventory:{type:Number},//库存 10 | image:{type:String},//主图片 11 | sales:{type:Number},//销量 12 | score:{type:Number},//评分 13 | parent:{type:mongoose.SchemaTypes.ObjectId,ref:'Category'},//父级 14 | enable_sale:{type:Boolean},//允许销售 15 | images:{type:Array},//图片组 16 | }) 17 | 18 | module.exports = mongoose.model('Goods',schema) -------------------------------------------------------------------------------- /uni-wxmp-catering/utils/dateUtil.wxs: -------------------------------------------------------------------------------- 1 | var formatTime = function(date) { 2 | var date = getDate(date); //返回当前时间对象 3 | var year = date.getFullYear() 4 | var month = fixz(date.getMonth() + 1) 5 | var day = fixz(date.getDate()) 6 | 7 | var hour = fixz(date.getHours()) 8 | var minute = fixz(date.getMinutes()) 9 | var second = fixz(date.getSeconds()) 10 | 11 | return [year, month, day].join('-') + ' ' + [hour, minute, second].join(':') 12 | } 13 | 14 | var fixz = function(num) { 15 | if (num < 10) { 16 | return '0' + num 17 | } 18 | return num 19 | } 20 | 21 | module.exports = { 22 | formatTime: formatTime 23 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # super-shop 2 | 点餐/自提/外卖/团购微信小程序配送方式自由选择(单店版),支持飞鹅外卖打印机,微信新订单提醒,服务端node.js+express+mongodb,管理端vue+elementui,小程序uni-app 3 | # 效果展示 4 | 无法显示图片可使用自由海添加域名raw.githubusercontent.com 刷新页面即可显示图片 5 | ![image](https://github.com/sword2022/images/blob/8683c95d2b0f11cb12d7a9dfd4d31fc3510532b2/0.jpg) 6 | ![image](https://github.com/sword2022/images/blob/8683c95d2b0f11cb12d7a9dfd4d31fc3510532b2/1.jpg) 7 | ![image](https://github.com/sword2022/images/blob/8683c95d2b0f11cb12d7a9dfd4d31fc3510532b2/2.jpg) 8 | ![image](https://github.com/sword2022/images/blob/8683c95d2b0f11cb12d7a9dfd4d31fc3510532b2/3.jpg) 9 | ![image](https://github.com/sword2022/images/blob/8683c95d2b0f11cb12d7a9dfd4d31fc3510532b2/5.jpg) 10 | 代码很多注释而且完全开源,不懂的查必应. 11 | 12 | -------------------------------------------------------------------------------- /node-api-serve/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-api-serve", 3 | "version": "2.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "bcrypt": "^5.0.1", 14 | "bcrypt-nodejs": "0.0.3", 15 | "cors": "^2.8.5", 16 | "crypto": "^1.0.1", 17 | "express": "^5.0.0-alpha.7", 18 | "inflection": "^1.12.0", 19 | "jsonwebtoken": "^8.5.1", 20 | "mongoose": "^5.13.8", 21 | "multer": "^1.4.2", 22 | "node-gyp": "^8.4.1", 23 | "request": "^2.88.2", 24 | "request-promise-native": "^1.0.9", 25 | "xmlreader": "^0.2.3" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /node-api-serve/cert/证书使用说明.txt: -------------------------------------------------------------------------------- 1 | 欢迎使用微信支付! 2 | 附件中的三份文件(证书pkcs12格式、证书pem格式、证书密钥pem格式),为接口中强制要求时需携带的证书文件。 3 | 证书属于敏感信息,请妥善保管不要泄露和被他人复制。 4 | 不同开发语言下的证书格式不同,以下为说明指引: 5 | 证书pkcs12格式(apiclient_cert.p12) 6 | 包含了私钥信息的证书文件,为p12(pfx)格式,由微信支付签发给您用来标识和界定您的身份 7 | 部分安全性要求较高的API需要使用该证书来确认您的调用身份 8 | windows上可以直接双击导入系统,导入过程中会提示输入证书密码,证书密码默认为您的商户号(如:1900006031) 9 | 证书pem格式(apiclient_cert.pem) 10 | 从apiclient_cert.p12中导出证书部分的文件,为pem格式,请妥善保管不要泄漏和被他人复制 11 | 部分开发语言和环境,不能直接使用p12文件,而需要使用pem,所以为了方便您使用,已为您直接提供 12 | 您也可以使用openssl命令来自己导出:openssl pkcs12 -clcerts -nokeys -in apiclient_cert.p12 -out apiclient_cert.pem 13 | 证书密钥pem格式(apiclient_key.pem) 14 | 从apiclient_cert.p12中导出密钥部分的文件,为pem格式 15 | 部分开发语言和环境,不能直接使用p12文件,而需要使用pem,所以为了方便您使用,已为您直接提供 16 | 您也可以使用openssl命令来自己导出:openssl pkcs12 -nocerts -in apiclient_cert.p12 -out apiclient_key.pem 17 | 备注说明: 18 | 由于绝大部分操作系统已内置了微信支付服务器证书的根CA证书, 2018年3月6日后, 不再提供CA证书文件(rootca.pem)下载 -------------------------------------------------------------------------------- /uni-wxmp-catering/utils/util.js: -------------------------------------------------------------------------------- 1 | const formatTime = date => { 2 | const year = date.getFullYear(); 3 | const month = date.getMonth() + 1; 4 | const day = date.getDate(); 5 | const hour = date.getHours(); 6 | const minute = date.getMinutes(); 7 | const second = date.getSeconds(); 8 | return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':'); 9 | }; 10 | 11 | const formatNumber = n => { 12 | n = n.toString(); 13 | return n[1] ? n : '0' + n; 14 | }; 15 | 16 | function formatLocation(longitude, latitude) { 17 | if (typeof longitude === 'string' && typeof latitude === 'string') { 18 | longitude = parseFloat(longitude); 19 | latitude = parseFloat(latitude); 20 | } 21 | 22 | longitude = longitude.toFixed(2); 23 | latitude = latitude.toFixed(2); 24 | return { 25 | longitude: longitude.toString().split('.'), 26 | latitude: latitude.toString().split('.') 27 | }; 28 | } 29 | 30 | module.exports = { 31 | formatTime, 32 | formatLocation 33 | }; 34 | -------------------------------------------------------------------------------- /node-api-serve/utils/dada/signature.js: -------------------------------------------------------------------------------- 1 | var crypto = require('crypto') 2 | 3 | var signature = { 4 | //签名 5 | dada_sign: function (body, format, timestamp, app_key, v, source_id, app_secret) { 6 | var ret = { 7 | body: body, 8 | format: format, 9 | timestamp: timestamp, 10 | app_key: app_key, 11 | v: v, 12 | source_id: source_id 13 | }; 14 | var string = raw(ret); 15 | string = app_secret + string + app_secret; 16 | // console.log(string); 17 | var sign = crypto.createHash('md5').update(string, 'utf8').digest('hex'); 18 | return sign.toUpperCase() 19 | }, 20 | } 21 | function raw(args) { 22 | var keys = Object.keys(args); 23 | keys = keys.sort() 24 | var newArgs = {}; 25 | keys.forEach(function (key) { 26 | newArgs[key] = args[key]; 27 | }); 28 | var string = ''; 29 | for (var k in newArgs) { 30 | string += k + newArgs[k]; 31 | } 32 | return string; 33 | } 34 | 35 | module.exports = signature; -------------------------------------------------------------------------------- /node-api-serve/utils/WXBizDataCrypt.js: -------------------------------------------------------------------------------- 1 | var crypto = require('crypto') 2 | 3 | function WXBizDataCrypt(appId, sessionKey) { 4 | this.appId = appId 5 | this.sessionKey = sessionKey 6 | } 7 | 8 | WXBizDataCrypt.prototype.decryptData = function (encryptedData, iv) { 9 | // base64 decode 10 | var sessionKey = Buffer.from(this.sessionKey, 'base64') 11 | console.log(encryptedData) 12 | encryptedData = Buffer.from(encryptedData, 'base64') 13 | iv = Buffer.from(iv, 'base64') 14 | 15 | try { 16 | // 解密 17 | var decipher = crypto.createDecipheriv('aes-128-cbc', sessionKey, iv) 18 | // 设置自动 padding 为 true,删除填充补位 19 | decipher.setAutoPadding(true) 20 | var decoded = decipher.update(encryptedData, 'binary', 'utf8') 21 | decoded += decipher.final('utf8') 22 | 23 | decoded = JSON.parse(decoded) 24 | 25 | } catch (err) { 26 | throw new Error('Illegal Buffer') 27 | } 28 | 29 | if (decoded.watermark.appid !== this.appId) { 30 | throw new Error('Illegal Buffer') 31 | } 32 | 33 | return decoded 34 | } 35 | 36 | module.exports = WXBizDataCrypt 37 | -------------------------------------------------------------------------------- /uni-wxmp-catering/uni_modules/uni-popup/changelog.md: -------------------------------------------------------------------------------- 1 | ## 1.6.2(2021-08-24) 2 | - 新增 支持国际化 3 | ## 1.6.1(2021-07-30) 4 | - 优化 vue3下事件警告的问题 5 | ## 1.6.0(2021-07-13) 6 | - 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) 7 | ## 1.5.0(2021-06-23) 8 | - 新增 mask-click 遮罩层点击事件 9 | ## 1.4.5(2021-06-22) 10 | - 修复 nvue 平台中间弹出后,点击内容,再点击遮罩无法关闭的Bug 11 | ## 1.4.4(2021-06-18) 12 | - 修复 H5平台中间弹出后,点击内容,再点击遮罩无法关闭的Bug 13 | ## 1.4.3(2021-06-08) 14 | - 修复 错误的 watch 字段 15 | - 修复 safeArea 属性不生效的问题 16 | - 修复 点击内容,再点击遮罩无法关闭的Bug 17 | ## 1.4.2(2021-05-12) 18 | - 新增 组件示例地址 19 | ## 1.4.1(2021-04-29) 20 | - 修复 组件内放置 input 、textarea 组件,无法聚焦的问题 21 | ## 1.4.0 (2021-04-29) 22 | - 新增 type 属性的 left\right 值,支持左右弹出 23 | - 新增 open(String:type) 方法参数 ,可以省略 type 属性 ,直接传入类型打开指定弹窗 24 | - 新增 backgroundColor 属性,可定义主窗口背景色,默认不显示背景色 25 | - 新增 safeArea 属性,是否适配底部安全区 26 | - 修复 App\h5\微信小程序底部安全区占位不对的Bug 27 | - 修复 App 端弹出等待的Bug 28 | - 优化 提升低配设备性能,优化动画卡顿问题 29 | - 优化 更简单的组件自定义方式 30 | ## 1.2.9(2021-02-05) 31 | - 优化 组件引用关系,通过uni_modules引用组件 32 | ## 1.2.8(2021-02-05) 33 | - 调整为uni_modules目录规范 34 | ## 1.2.7(2021-02-05) 35 | - 调整为uni_modules目录规范 36 | - 新增 支持 PC 端 37 | - 新增 uni-popup-message 、uni-popup-dialog扩展组件支持 PC 端 38 | -------------------------------------------------------------------------------- /element-admin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "myshop-admin", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "axios": "^0.19.2", 12 | "core-js": "^3.6.5", 13 | "element-ui": "^2.13.2", 14 | "vue": "^2.6.11", 15 | "vue-croppa": "^1.3.8", 16 | "vue-router": "^3.3.2" 17 | }, 18 | "devDependencies": { 19 | "@vue/cli-plugin-babel": "^4.4.1", 20 | "@vue/cli-plugin-eslint": "^4.4.1", 21 | "@vue/cli-service": "^4.4.1", 22 | "babel-eslint": "^10.1.0", 23 | "eslint": "^5.16.0", 24 | "eslint-plugin-vue": "^5.0.0", 25 | "vue-cli-plugin-element": "^1.0.1", 26 | "vue-template-compiler": "^2.6.11" 27 | }, 28 | "eslintConfig": { 29 | "root": true, 30 | "env": { 31 | "node": true 32 | }, 33 | "extends": [ 34 | "plugin:vue/essential", 35 | "eslint:recommended" 36 | ], 37 | "rules": {}, 38 | "parserOptions": { 39 | "parser": "babel-eslint" 40 | } 41 | }, 42 | "browserslist": [ 43 | "> 1%", 44 | "last 2 versions" 45 | ] 46 | } 47 | -------------------------------------------------------------------------------- /node-api-serve/utils/utils.js: -------------------------------------------------------------------------------- 1 | var utils = { 2 | isNdefOrNull: function (variable) { 3 | let x; 4 | try { 5 | x = variable; 6 | } catch (e) { 7 | console.log(e.message);//sojson is undefined 8 | } 9 | }, 10 | timeFn: function (d1) { 11 | var dateBegin = new Date(d1.toString().replace(/-/g, "/"));//将-转化为/,使用new Date 12 | var dateEnd = new Date();//获取当前时间 13 | var dateDiff = dateEnd.getTime() - dateBegin.getTime();//时间差的毫秒数 14 | var dayDiff = Math.floor(dateDiff / (24 * 3600 * 1000));//计算出相差天数 15 | var leave1 = dateDiff % (24 * 3600 * 1000) //计算天数后剩余的毫秒数 16 | var hours = Math.floor((dayDiff * 24) + (leave1 / (3600 * 1000)))//计算出小时数 17 | //计算相差分钟数 18 | var leave2 = leave1 % (3600 * 1000) //计算小时数后剩余的毫秒数 19 | var minutes = Math.floor((hours * 60) + (leave2 / (60 * 1000)))//计算相差分钟数 20 | //计算相差秒数 21 | // var leave3 = leave2%(60*1000) //计算分钟数后剩余的毫秒数 22 | // var seconds = Math.round(leave3/1000) 23 | //console.log("相差 " + dayDiff + "天,相差 " + hours + "小时,相差 " + minutes + " 分钟") 24 | return minutes 25 | } 26 | } 27 | module.exports = utils; -------------------------------------------------------------------------------- /element-admin/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | myshop-admin 9 | 10 | 25 | 26 | 29 | 30 | 31 |
32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /node-api-serve/models/order.js: -------------------------------------------------------------------------------- 1 | const mongoose=require('mongoose') 2 | const schema=new mongoose.Schema({ 3 | order_id:{type:String},//订单ID 4 | openid:{type:String},//订单创建者的openid 5 | goods_list:{type:Array},//商品对象数组 6 | coupon:{type:Object},//优惠卷对象 7 | reduce:{type:Number},//优惠金额 8 | freight:{type:Number},//运费 9 | pay_type:{type:String},//支付方式 10 | total_price:{type:Number},//商品总金额 11 | amount_real:{type:Number},//实际金额 12 | goods_weight:{type:Number},//货物重量 13 | receiver_lng:{type:Number},//收货人经度 14 | receiver_lat:{type:Number},//收货人纬度 15 | remark:{type:String},//备注 16 | status:{type:String},//状态 待付款->已付款->待接单->已接单->配送中->已完成||已关闭 17 | create_time:{type: Date},//创建时间 18 | pay_time:{type:String},//付款时间 19 | send_time:{type:String},//发货时间 20 | take_time:{type:String},//收货时间 21 | pickup_date:{type:String},//团购取货日期 22 | refund_time:{type:String},//退款时间 23 | delivery_method:{type:String},//交货方式 自取/外卖/团购 24 | accepter:{type:String},//接单员 25 | deliveryman:{type:Object},//配送员 26 | log:{type:Array},//日志 27 | userDetails:{type:Object},//用户信息{userName,telNumber,countyName,cityName,detailInfo,} 28 | today_no:{type:Number},//当日编号 29 | }) 30 | 31 | module.exports = mongoose.model('Order',schema) -------------------------------------------------------------------------------- /node-api-serve/models/setting.js: -------------------------------------------------------------------------------- 1 | const mongoose=require('mongoose') 2 | const schema=new mongoose.Schema({ 3 | opening:{type:Boolean},//店铺营业中 4 | store_name:{type:String},//店铺名称 5 | address:{type:String},//店铺地址 6 | telephone:{type:String},//店铺电话 7 | longitude:{type:Number},//店铺经度 8 | latitude:{type:Number},//店铺纬度 9 | autoplay:{type:Boolean},//自动播放横幅广告 10 | interval:{type:String},//横幅广告间隔时间 11 | duration:{type:String},//横幅广告切换速度 12 | opening_times:{type:Array},//店铺营业时间段 13 | show_seckilling:{type:Boolean},//显示秒杀 14 | show_recommend:{type:Boolean},//显示推荐商品 15 | show_hot:{type:Boolean},//显示热卖商品 16 | freight:{type:Number},//设置运费 17 | max_distance:{type:Number},//设置最大距离 18 | pay_expire:{type:Number},//设置支付过期时间 19 | minimum_fee:{type:Number},//最低消费 20 | show_sales:{type:Boolean},//显示已售 21 | self_pickup_method:{type:Boolean},//自取 22 | takeout_method:{type:Boolean},//外卖 23 | groupon_method:{type:Boolean},//团购 24 | store_self_send:{type:Boolean},// 商家自送 25 | showPopup:{type:Boolean},//显示弹出层 26 | pickup_date:{type:String},//团购送货时间 27 | auto_update_pickup_date:{type:Boolean},//启用自动更新团购送货日期 28 | update_time:{type:Number},//团购送货日期更新时间 29 | print:{type:Boolean},//是否打印 30 | }) 31 | 32 | module.exports = mongoose.model('Setting',schema) -------------------------------------------------------------------------------- /uni-wxmp-catering/uni_modules/uni-popup/components/uni-popup-dialog/keypress.js: -------------------------------------------------------------------------------- 1 | // #ifdef H5 2 | export default { 3 | name: 'Keypress', 4 | props: { 5 | disable: { 6 | type: Boolean, 7 | default: false 8 | } 9 | }, 10 | mounted () { 11 | const keyNames = { 12 | esc: ['Esc', 'Escape'], 13 | tab: 'Tab', 14 | enter: 'Enter', 15 | space: [' ', 'Spacebar'], 16 | up: ['Up', 'ArrowUp'], 17 | left: ['Left', 'ArrowLeft'], 18 | right: ['Right', 'ArrowRight'], 19 | down: ['Down', 'ArrowDown'], 20 | delete: ['Backspace', 'Delete', 'Del'] 21 | } 22 | const listener = ($event) => { 23 | if (this.disable) { 24 | return 25 | } 26 | const keyName = Object.keys(keyNames).find(key => { 27 | const keyName = $event.key 28 | const value = keyNames[key] 29 | return value === keyName || (Array.isArray(value) && value.includes(keyName)) 30 | }) 31 | if (keyName) { 32 | // 避免和其他按键事件冲突 33 | setTimeout(() => { 34 | this.$emit(keyName, {}) 35 | }, 0) 36 | } 37 | } 38 | document.addEventListener('keyup', listener) 39 | this.$once('hook:beforeDestroy', () => { 40 | document.removeEventListener('keyup', listener) 41 | }) 42 | }, 43 | render: () => {} 44 | } 45 | // #endif 46 | -------------------------------------------------------------------------------- /uni-wxmp-catering/uni_modules/uni-popup/components/uni-popup/keypress.js: -------------------------------------------------------------------------------- 1 | // #ifdef H5 2 | export default { 3 | name: 'Keypress', 4 | props: { 5 | disable: { 6 | type: Boolean, 7 | default: false 8 | } 9 | }, 10 | mounted () { 11 | const keyNames = { 12 | esc: ['Esc', 'Escape'], 13 | tab: 'Tab', 14 | enter: 'Enter', 15 | space: [' ', 'Spacebar'], 16 | up: ['Up', 'ArrowUp'], 17 | left: ['Left', 'ArrowLeft'], 18 | right: ['Right', 'ArrowRight'], 19 | down: ['Down', 'ArrowDown'], 20 | delete: ['Backspace', 'Delete', 'Del'] 21 | } 22 | const listener = ($event) => { 23 | if (this.disable) { 24 | return 25 | } 26 | const keyName = Object.keys(keyNames).find(key => { 27 | const keyName = $event.key 28 | const value = keyNames[key] 29 | return value === keyName || (Array.isArray(value) && value.includes(keyName)) 30 | }) 31 | if (keyName) { 32 | // 避免和其他按键事件冲突 33 | setTimeout(() => { 34 | this.$emit(keyName, {}) 35 | }, 0) 36 | } 37 | } 38 | document.addEventListener('keyup', listener) 39 | // this.$once('hook:beforeDestroy', () => { 40 | // document.removeEventListener('keyup', listener) 41 | // }) 42 | }, 43 | render: () => {} 44 | } 45 | // #endif 46 | -------------------------------------------------------------------------------- /uni-wxmp-catering/api/api.js: -------------------------------------------------------------------------------- 1 | const app = getApp(); 2 | 3 | const request = (url, options) => { 4 | return new Promise((resolve, reject) => { 5 | uni.request({ 6 | url: `${app.globalData.host}${url}`, 7 | method: options.method, 8 | data: options.method === 'GET' ? options.data : JSON.stringify(options.data), 9 | header: { 10 | 'Content-Type': 'application/json; charset=UTF-8', 11 | 'x-token': 'x-token' // 看自己是否需要 12 | }, 13 | 14 | success(request) { 15 | resolve(request.data); // if (request.data.code === 2000) { 16 | // resolve(request.data) 17 | // } else { 18 | // reject(request.data) 19 | // } 20 | }, 21 | 22 | fail(error) { 23 | reject(error.data); 24 | } 25 | 26 | }); 27 | }); 28 | }; 29 | 30 | const get = (url, options = {}) => { 31 | return request(url, { 32 | method: 'GET', 33 | data: options 34 | }); 35 | }; 36 | 37 | const post = (url, options) => { 38 | return request(url, { 39 | method: 'POST', 40 | data: options 41 | }); 42 | }; 43 | 44 | const put = (url, options) => { 45 | return request(url, { 46 | method: 'PUT', 47 | data: options 48 | }); 49 | }; 50 | 51 | const remove = (url, options) => { 52 | return request(url, { 53 | method: 'DELETE', 54 | data: options 55 | }); 56 | }; 57 | 58 | module.exports = { 59 | get, 60 | post, 61 | put, 62 | remove 63 | }; -------------------------------------------------------------------------------- /uni-wxmp-catering/pages.json: -------------------------------------------------------------------------------- 1 | { 2 | "pages": [ 3 | { 4 | "path": "pages/index/index", 5 | "style": {} 6 | }, 7 | { 8 | "path": "pages/personal/index", 9 | "style": {} 10 | }, 11 | { 12 | "path": "pages/create-order/index", 13 | "style": {} 14 | }, 15 | { 16 | "path": "pages/search/index", 17 | "style": {} 18 | }, 19 | { 20 | "path": "pages/order-list/index", 21 | "style": {} 22 | }, 23 | { 24 | "path": "pages/order-detail/index", 25 | "style": {} 26 | }, 27 | { 28 | "path": "pages/coupon-list/index", 29 | "style": {} 30 | } 31 | ], 32 | "globalStyle": { 33 | "navigationBarTextStyle": "black", 34 | "navigationBarTitleText": "uni-app", 35 | "navigationBarBackgroundColor": "#F8F8F8", 36 | "backgroundColor": "#F8F8F8" 37 | }, 38 | "tabBar": { 39 | "color": "#838383", 40 | "selectedColor": "#b4282d", 41 | "borderStyle": "black", 42 | "backgroundColor": "#ffffff", 43 | "list": [ 44 | { 45 | "pagePath": "pages/index/index", 46 | "iconPath": "/static/tabbar/home-off.png", 47 | "selectedIconPath": "/static/tabbar/home-on.png", 48 | "text": "首页" 49 | }, 50 | { 51 | "pagePath": "pages/order-list/index", 52 | "iconPath": "/static/tabbar/finish-off.png", 53 | "selectedIconPath": "/static/tabbar/finish-on.png", 54 | "text": "订单" 55 | }, 56 | { 57 | "pagePath": "pages/personal/index", 58 | "iconPath": "/static/tabbar/my-off.png", 59 | "selectedIconPath": "/static/tabbar/my-on.png", 60 | "text": "个人" 61 | } 62 | ] 63 | }, 64 | "globalStyle": { 65 | "navigationStyle": "custom", 66 | "navigationBarTextStyle": "black" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /uni-wxmp-catering/uni_modules/uni-popup/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "uni-popup", 3 | "displayName": "uni-popup 弹出层", 4 | "version": "1.6.2", 5 | "description": " Popup 组件,提供常用的弹层", 6 | "keywords": [ 7 | "uni-ui", 8 | "弹出层", 9 | "弹窗", 10 | "popup", 11 | "弹框" 12 | ], 13 | "repository": "https://github.com/dcloudio/uni-ui", 14 | "engines": { 15 | "HBuilderX": "" 16 | }, 17 | "directories": { 18 | "example": "../../temps/example_temps" 19 | }, 20 | "dcloudext": { 21 | "category": [ 22 | "前端组件", 23 | "通用组件" 24 | ], 25 | "sale": { 26 | "regular": { 27 | "price": "0.00" 28 | }, 29 | "sourcecode": { 30 | "price": "0.00" 31 | } 32 | }, 33 | "contact": { 34 | "qq": "" 35 | }, 36 | "declaration": { 37 | "ads": "无", 38 | "data": "无", 39 | "permissions": "无" 40 | }, 41 | "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui" 42 | }, 43 | "uni_modules": { 44 | "dependencies": [ 45 | "uni-transition" 46 | ], 47 | "encrypt": [], 48 | "platforms": { 49 | "cloud": { 50 | "tcb": "y", 51 | "aliyun": "y" 52 | }, 53 | "client": { 54 | "App": { 55 | "app-vue": "y", 56 | "app-nvue": "y" 57 | }, 58 | "H5-mobile": { 59 | "Safari": "y", 60 | "Android Browser": "y", 61 | "微信浏览器(Android)": "y", 62 | "QQ浏览器(Android)": "y" 63 | }, 64 | "H5-pc": { 65 | "Chrome": "y", 66 | "IE": "y", 67 | "Edge": "y", 68 | "Firefox": "y", 69 | "Safari": "y" 70 | }, 71 | "小程序": { 72 | "微信": "y", 73 | "阿里": "y", 74 | "百度": "y", 75 | "字节跳动": "y", 76 | "QQ": "y" 77 | }, 78 | "快应用": { 79 | "华为": "u", 80 | "联盟": "u" 81 | }, 82 | "Vue": { 83 | "vue2": "y", 84 | "vue3": "u" 85 | } 86 | } 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /uni-wxmp-catering/uni_modules/uni-transition/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "uni-transition", 3 | "displayName": "uni-transition 过渡动画", 4 | "version": "1.2.0", 5 | "description": "元素的简单过渡动画", 6 | "keywords": [ 7 | "uni-ui", 8 | "uniui", 9 | "动画", 10 | "过渡", 11 | "过渡动画" 12 | ], 13 | "repository": "https://github.com/dcloudio/uni-ui", 14 | "engines": { 15 | "HBuilderX": "" 16 | }, 17 | "directories": { 18 | "example": "../../temps/example_temps" 19 | }, 20 | "dcloudext": { 21 | "category": [ 22 | "前端组件", 23 | "通用组件" 24 | ], 25 | "sale": { 26 | "regular": { 27 | "price": "0.00" 28 | }, 29 | "sourcecode": { 30 | "price": "0.00" 31 | } 32 | }, 33 | "contact": { 34 | "qq": "" 35 | }, 36 | "declaration": { 37 | "ads": "无", 38 | "data": "无", 39 | "permissions": "无" 40 | }, 41 | "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui" 42 | }, 43 | "uni_modules": { 44 | "dependencies": [], 45 | "encrypt": [], 46 | "platforms": { 47 | "cloud": { 48 | "tcb": "y", 49 | "aliyun": "y" 50 | }, 51 | "client": { 52 | "App": { 53 | "app-vue": "y", 54 | "app-nvue": "y" 55 | }, 56 | "H5-mobile": { 57 | "Safari": "y", 58 | "Android Browser": "y", 59 | "微信浏览器(Android)": "y", 60 | "QQ浏览器(Android)": "y" 61 | }, 62 | "H5-pc": { 63 | "Chrome": "y", 64 | "IE": "y", 65 | "Edge": "y", 66 | "Firefox": "y", 67 | "Safari": "y" 68 | }, 69 | "小程序": { 70 | "微信": "y", 71 | "阿里": "y", 72 | "百度": "y", 73 | "字节跳动": "y", 74 | "QQ": "y" 75 | }, 76 | "快应用": { 77 | "华为": "u", 78 | "联盟": "u" 79 | } 80 | } 81 | } 82 | } 83 | } -------------------------------------------------------------------------------- /uni-wxmp-catering/uni.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * 这里是uni-app内置的常用样式变量 3 | * 4 | * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量 5 | * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App 6 | * 7 | */ 8 | 9 | /** 10 | * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能 11 | * 12 | * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件 13 | */ 14 | 15 | /* 颜色变量 */ 16 | 17 | /* 行为相关颜色 */ 18 | $uni-color-primary: #007aff; 19 | $uni-color-success: #4cd964; 20 | $uni-color-warning: #f0ad4e; 21 | $uni-color-error: #dd524d; 22 | 23 | /* 文字基本颜色 */ 24 | $uni-text-color:#333;//基本色 25 | $uni-text-color-inverse:#fff;//反色 26 | $uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息 27 | $uni-text-color-placeholder: #808080; 28 | $uni-text-color-disable:#c0c0c0; 29 | 30 | /* 背景颜色 */ 31 | $uni-bg-color:#ffffff; 32 | $uni-bg-color-grey:#f8f8f8; 33 | $uni-bg-color-hover:#f1f1f1;//点击状态颜色 34 | $uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色 35 | 36 | /* 边框颜色 */ 37 | $uni-border-color:#c8c7cc; 38 | 39 | /* 尺寸变量 */ 40 | 41 | /* 文字尺寸 */ 42 | $uni-font-size-sm:12px; 43 | $uni-font-size-base:14px; 44 | $uni-font-size-lg:16; 45 | 46 | /* 图片尺寸 */ 47 | $uni-img-size-sm:20px; 48 | $uni-img-size-base:26px; 49 | $uni-img-size-lg:40px; 50 | 51 | /* Border Radius */ 52 | $uni-border-radius-sm: 2px; 53 | $uni-border-radius-base: 3px; 54 | $uni-border-radius-lg: 6px; 55 | $uni-border-radius-circle: 50%; 56 | 57 | /* 水平间距 */ 58 | $uni-spacing-row-sm: 5px; 59 | $uni-spacing-row-base: 10px; 60 | $uni-spacing-row-lg: 15px; 61 | 62 | /* 垂直间距 */ 63 | $uni-spacing-col-sm: 4px; 64 | $uni-spacing-col-base: 8px; 65 | $uni-spacing-col-lg: 12px; 66 | 67 | /* 透明度 */ 68 | $uni-opacity-disabled: 0.3; // 组件禁用态的透明度 69 | 70 | /* 文章场景相关 */ 71 | $uni-color-title: #2C405A; // 文章标题颜色 72 | $uni-font-size-title:20px; 73 | $uni-color-subtitle: #555555; // 二级标题颜色 74 | $uni-font-size-subtitle:26px; 75 | $uni-color-paragraph: #3F536E; // 文章段落颜色 76 | $uni-font-size-paragraph:15px; 77 | -------------------------------------------------------------------------------- /uni-wxmp-catering/utils/wxTimer.js: -------------------------------------------------------------------------------- 1 | var wxTimer = function(initObj) { 2 | initObj = initObj || {}; 3 | this.beginTime = initObj.beginTime || "00:00:00"; //开始时间 4 | this.interval = initObj.interval || 0; //间隔时间 5 | this.complete = initObj.complete; //结束任务 6 | this.intervalFn = initObj.intervalFn; //间隔任务 7 | this.name = initObj.name; //当前计时器在计时器数组对象中的名字 8 | this.intervarID; //计时ID 9 | this.endTime; //结束时间 10 | this.endSystemTime; //结束的系统时间 11 | } 12 | 13 | wxTimer.prototype = { 14 | //开始 15 | start: function(self) { 16 | this.endTime = new Date("1970/01/01 " + this.beginTime).getTime(); //1970年1月1日的00:00:00的字符串日期 17 | this.endSystemTime = new Date(Date.now() + this.endTime); 18 | var that = this; 19 | //开始倒计时 20 | var count = 0; //这个count在这里应该是表示s数,js中获得时间是ms,所以下面*1000都换成ms 21 | function begin() { 22 | var tmpTime = new Date(that.endTime - 1000 * count++); 23 | //把2011年1月1日日 00:00:00换成数字型,这样就可以直接1s,1s的减,就变成了倒计时,为了看的更明确,又用new date把字符串换回来了 24 | var tmpTimeStr = tmpTime.toString().substr(16, 8); //去掉前面的年月日就剩时分秒了 25 | var wxTimerSecond = (tmpTime.getTime() - new Date("1970/01/01 00:00:00").getTime()) / 1000; 26 | 27 | var wxTimerList = self.wxTimerList; 28 | //更新计时器数组 29 | wxTimerList[that.name] = { 30 | wxTimer: tmpTimeStr, 31 | wxTimerSecond: wxTimerSecond, 32 | } 33 | 34 | self.setData({ 35 | wxTimer: tmpTimeStr, 36 | wxTimerSecond: wxTimerSecond, 37 | wxTimerList: wxTimerList 38 | }); 39 | //时间间隔执行函数 40 | if (0 == (count - 1) % that.interval && that.intervalFn) { 41 | that.intervalFn(); 42 | } 43 | //结束执行函数 44 | if (wxTimerSecond <= 0) { 45 | if (that.complete) { 46 | that.complete(); 47 | } 48 | that.stop(); 49 | } 50 | } 51 | begin(); 52 | this.intervarID = setInterval(begin, 1000); 53 | }, 54 | //结束 55 | stop: function() { 56 | clearInterval(this.intervarID); 57 | }, 58 | //校准 59 | calibration: function() { 60 | this.endTime = this.endSystemTime - Date.now(); 61 | } 62 | } 63 | 64 | module.exports = wxTimer; 65 | -------------------------------------------------------------------------------- /element-admin/src/views/setting/pay.vue: -------------------------------------------------------------------------------- 1 | 36 | -------------------------------------------------------------------------------- /element-admin/src/views/setting/printer.vue: -------------------------------------------------------------------------------- 1 | 36 | -------------------------------------------------------------------------------- /element-admin/src/views/login/login.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 66 | -------------------------------------------------------------------------------- /element-admin/src/views/login/reg.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 77 | -------------------------------------------------------------------------------- /uni-wxmp-catering/components/navigation/navigation.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | -------------------------------------------------------------------------------- /node-api-serve/index.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const express = require('express') 4 | const app = express() 5 | const http = require("http"); 6 | const https = require("https"); 7 | const fs = require("fs"); 8 | 9 | //ssl证书 有花生壳https解析 可以注释掉 10 | // var privateKey = fs.readFileSync('./ssl/xxx.com.key'); 11 | // var certificate = fs.readFileSync('./ssl/xxx.com_bundle.crt'); 12 | // var credentials = { key: privateKey, cert: certificate }; 13 | 14 | app.use(require('cors')()) 15 | app.use(express.json()) 16 | //访问uploads必须要定义静态文件托管 17 | app.use('/uploads', express.static(__dirname + '/uploads')) 18 | 19 | require('./plugins/db')(app) 20 | require('./routers/admin/index')(app) 21 | require('./routers/miniprogram/index')(app) 22 | function nowDateTime() { 23 | let nowTime = new Date() 24 | return `${nowTime.toLocaleDateString()} ${nowTime.toLocaleTimeString()} ` 25 | } 26 | var httpServer = http.createServer(app); 27 | var PORT = 3000; 28 | //监听接口 29 | httpServer.listen(PORT, function () { 30 | console.log(`${nowDateTime()} HTTP Server is running on: http://localhost:%s`, PORT); 31 | }); 32 | //监听https接口 用花生壳可以转到3000端口上 33 | // var httpsServer = https.createServer(credentials, app); 34 | // var SSLPORT = 443; 35 | // httpsServer.listen(SSLPORT, function () { 36 | // var nowTime = new Date() 37 | // console.log(`${nowDateTime()} HTTPS Server is running on: https://localhost:%s`, SSLPORT) 38 | // }); 39 | 40 | //每日自动更新团购取货日期用的定时器 41 | const Setting = require('./models/setting.js') 42 | async function check_pickup_date() { 43 | //无限循环 44 | for (let i = 1; i > 0; i++) { 45 | var settings = Setting.findOne() 46 | if (settings.auto_update_pickup_date) { 47 | //console.log(`检测是否现在更新团购取货日期 ${i}次`) 48 | var now = new Date() 49 | var nowHrs = now.getHours() 50 | //console.log(nowHrs) 51 | if (settings.update_time == nowHrs) { 52 | //console.log(`是设定的更新时间`) 53 | // 用现在日期弄出一个后天的日期 54 | now.setTime(now.getTime() + 2 * 24 * 60 * 60 * 1000); 55 | var date = now.getFullYear() + "-" + (now.getMonth() + 1) + "-" + now.getDate(); 56 | //console.log(`settings.pickup_date:${settings.pickup_date}`) 57 | //console.log(`date:${date}`) 58 | if (settings.pickup_date !== date) { 59 | //console.log('设定团购取货日期为后天') 60 | settings = await Setting.findByIdAndUpdate(settings._id, { 61 | pickup_date: date 62 | }) 63 | if (settings) { 64 | console.log('设定团购取货日期-成功') 65 | } else { 66 | console.log('设定团购取货日期-失败') 67 | } 68 | } else { 69 | //console.log('团购取货日期是后天') 70 | } 71 | } 72 | } 73 | //异步中要用Promise调用setTimeout实现延迟 74 | await (() => { 75 | return new Promise((res) => { 76 | //每30秒循环1次 77 | setTimeout(res, 30000); 78 | }); 79 | })(); 80 | } 81 | } 82 | 83 | check_pickup_date(); 84 | 85 | 86 | -------------------------------------------------------------------------------- /uni-wxmp-catering/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "CATERING", 3 | "appid" : "__UNI__ECB11EC", 4 | "description" : "", 5 | "versionName" : "1.0.0", 6 | "versionCode" : "100", 7 | "transformPx" : false, 8 | /* 5+App特有相关 */ 9 | "app-plus" : { 10 | "usingComponents" : true, 11 | "nvueStyleCompiler" : "uni-app", 12 | "compilerVersion" : 3, 13 | "splashscreen" : { 14 | "alwaysShowBeforeRender" : true, 15 | "waiting" : true, 16 | "autoclose" : true, 17 | "delay" : 0 18 | }, 19 | /* 模块配置 */ 20 | "modules" : {}, 21 | /* 应用发布信息 */ 22 | "distribute" : { 23 | /* android打包配置 */ 24 | "android" : { 25 | "permissions" : [ 26 | "", 27 | "", 28 | "", 29 | "", 30 | "", 31 | "", 32 | "", 33 | "", 34 | "", 35 | "", 36 | "", 37 | "", 38 | "", 39 | "", 40 | "" 41 | ] 42 | }, 43 | /* ios打包配置 */ 44 | "ios" : {}, 45 | /* SDK配置 */ 46 | "sdkConfigs" : {} 47 | } 48 | }, 49 | /* 快应用特有相关 */ 50 | "quickapp" : {}, 51 | /* 小程序特有相关 */ 52 | "mp-weixin" : { 53 | "appid" : "wx471ee5e8455662ee", 54 | "setting" : { 55 | "urlCheck" : false, 56 | "es6" : false, 57 | "postcss" : false 58 | }, 59 | "usingComponents" : true, 60 | "permission" : { 61 | "scope.userLocation" : { 62 | "desc" : "定位是为了知道您是否在配送范围内 请允许" 63 | } 64 | } 65 | }, 66 | "mp-alipay" : { 67 | "usingComponents" : true 68 | }, 69 | "mp-baidu" : { 70 | "usingComponents" : true 71 | }, 72 | "mp-toutiao" : { 73 | "usingComponents" : true 74 | }, 75 | "uniStatistics" : { 76 | "enable" : false 77 | }, 78 | "vueVersion" : "2" 79 | } 80 | -------------------------------------------------------------------------------- /uni-wxmp-catering/uni_modules/uni-popup/components/uni-popup-message/uni-popup-message.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 74 | 144 | -------------------------------------------------------------------------------- /node-api-serve/utils/wxpay.js: -------------------------------------------------------------------------------- 1 | var crypto = require('crypto') 2 | 3 | var wxpay = { 4 | // 解析通过post传递过来的xml信息 5 | parseReqXmlData: function (req) { 6 | let notionData = ""; 7 | req.setEncoding('utf8'); 8 | req.on('data', (chunk) => { 9 | notionData += chunk; 10 | }); 11 | return new Promise((resolve, reject) => { 12 | req.on("end", () => { 13 | resolve(notionData) 14 | }); 15 | req.on("error", (e) => { 16 | reject(e) 17 | }) 18 | }) 19 | }, 20 | //把金额转为整数分 21 | getmoney: function (money) { 22 | return (Math.round(money * 100, 0)).toString(); 23 | }, 24 | 25 | // 随机字符串产生函数 26 | createNonceStr: function () { 27 | return Math.random().toString(36).substr(2, 15); 28 | }, 29 | 30 | // 时间戳产生函数 31 | createTimeStamp: function () { 32 | return parseInt(new Date().getTime() / 1000) + ''; 33 | }, 34 | 35 | //退款签名加密算法 36 | refundsignjsapi: function (appid, mch_id, nonce_str, notify_url, out_refund_no, out_trade_no, refund_fee, total_fee, key) { 37 | var ret = { 38 | appid: appid, 39 | mch_id: mch_id, 40 | nonce_str: nonce_str, 41 | notify_url: notify_url, 42 | out_refund_no: out_refund_no, 43 | out_trade_no: out_trade_no, 44 | refund_fee: refund_fee, 45 | total_fee: total_fee 46 | }; 47 | var string = raw(ret); 48 | string = string + '&key=' + key; 49 | var sign = crypto.createHash('md5').update(string, 'utf8').digest('hex'); 50 | return sign.toUpperCase() 51 | }, 52 | 53 | //支付签名加密算法 54 | paysignjsapi: function (appid, body, mch_id, nonce_str, notify_url, openid, out_trade_no, spbill_create_ip, total_fee, trade_type, key) { 55 | var ret = { 56 | appid: appid, 57 | body: body, 58 | mch_id: mch_id, 59 | nonce_str: nonce_str, 60 | notify_url: notify_url, 61 | openid: openid, 62 | out_trade_no: out_trade_no, 63 | spbill_create_ip: spbill_create_ip, 64 | total_fee: total_fee, 65 | trade_type: trade_type 66 | }; 67 | var string = raw(ret); 68 | string = string + '&key=' + key; 69 | // console.log('string:', string) 70 | var sign = crypto.createHash('md5').update(string, 'utf8').digest('hex'); 71 | return sign.toUpperCase() 72 | }, 73 | 74 | //支付签名加密算法,第二次的签名 75 | paysignjsapifinal: function (appid, nonceStr, package, signType, timeStamp, key) { 76 | var ret = { 77 | appId: appid, 78 | nonceStr: nonceStr, 79 | package: package, 80 | signType: signType, 81 | timeStamp: timeStamp 82 | }; 83 | var string = raw(ret); 84 | string = string + '&key=' + key; 85 | var crypto = require('crypto'); 86 | return crypto.createHash('md5').update(string, 'utf8').digest('hex'); 87 | } 88 | } 89 | 90 | function raw(args) { 91 | var keys = Object.keys(args); 92 | keys = keys.sort() 93 | var newArgs = {}; 94 | keys.forEach(function (key) { 95 | newArgs[key] = args[key]; 96 | }); 97 | var string = ''; 98 | for (var k in newArgs) { 99 | string += '&' + k + '=' + newArgs[k]; 100 | } 101 | string = string.substr(1); 102 | return string; 103 | } 104 | 105 | module.exports = wxpay; -------------------------------------------------------------------------------- /uni-wxmp-catering/main.js: -------------------------------------------------------------------------------- 1 | import App from './App' 2 | 3 | // #ifndef VUE3 4 | import Vue from 'vue' 5 | Vue.config.productionTip = false 6 | 7 | //定义setData() 8 | Vue.mixin({ 9 | methods: { 10 | //编辑购物车 11 | editCart: function (object, type,list) { 12 | let find_this = false; 13 | let msg = ""; 14 | for (var i = 0; i < list.length; i++) { 15 | if (list[i]._id == object._id) { 16 | console.log("购物车列表中存在:", object._id); 17 | find_this = true; 18 | if (type == "decrease") { 19 | if (list[i].number == 1 && object.inventory == 1) { 20 | console.log("按钮颜色恢复"); 21 | object.number--; 22 | } 23 | if (list[i].number <= 1) { 24 | list.splice(i, 1); 25 | msg = object.name + " 已从订单移除"; 26 | } else { 27 | list[i].number--; 28 | msg = object.name + " 数量 - 1"; 29 | } 30 | } else { 31 | if (list[i].number >= object.inventory) { 32 | uni.showModal({ 33 | title: "库存不足", 34 | content: "购买数量已经超过最大库存数量", 35 | showCancel: false, 36 | }); 37 | return false; 38 | } else { 39 | list[i].number++; 40 | msg = object.name + " 数量 + 1"; 41 | } 42 | } 43 | break; 44 | } 45 | } 46 | if (object.inventory > 0) { 47 | //在订单中未找到对象就新增 48 | if (!find_this) { 49 | object.number = 1; 50 | list.push(object); 51 | msg = object.name + "加入了订单"; 52 | } 53 | } else { 54 | uni.showModal({ 55 | title: "库存不足", 56 | content: "购买数量已经超过最大库存数量", 57 | showCancel: false, 58 | }); 59 | return false; 60 | } 61 | uni.showToast({ 62 | title: msg, 63 | icon: "none", 64 | duration: 1000, 65 | }); 66 | return list 67 | }, 68 | setData: function (obj, callback) { 69 | let that = this; 70 | const handleData = (tepData, tepKey, afterKey) => { 71 | tepKey = tepKey.split('.'); 72 | tepKey.forEach(item => { 73 | if (tepData[item] === null || tepData[item] === undefined) { 74 | let reg = /^[0-9]+$/; 75 | tepData[item] = reg.test(afterKey) ? [] : {}; 76 | tepData = tepData[item]; 77 | } else { 78 | tepData = tepData[item]; 79 | } 80 | }); 81 | return tepData; 82 | }; 83 | const isFn = function (value) { 84 | return typeof value == 'function' || false; 85 | }; 86 | Object.keys(obj).forEach(function (key) { 87 | let val = obj[key]; 88 | key = key.replace(/\]/g, '').replace(/\[/g, '.'); 89 | let front, after; 90 | let index_after = key.lastIndexOf('.'); 91 | if (index_after != -1) { 92 | after = key.slice(index_after + 1); 93 | front = handleData(that, key.slice(0, index_after), after); 94 | } else { 95 | after = key; 96 | front = that; 97 | } 98 | if (front.$data && front.$data[after] === undefined) { 99 | Object.defineProperty(front, after, { 100 | get() { 101 | return front.$data[after]; 102 | }, 103 | set(newValue) { 104 | front.$data[after] = newValue; 105 | that.$forceUpdate(); 106 | }, 107 | enumerable: true, 108 | configurable: true 109 | }); 110 | front[after] = val; 111 | } else { 112 | that.$set(front, after, val); 113 | } 114 | }); 115 | // this.$forceUpdate(); 116 | isFn(callback) && this.$nextTick(callback); 117 | } 118 | } 119 | }); 120 | 121 | 122 | App.mpType = 'app' 123 | const app = new Vue({ 124 | ...App 125 | }) 126 | app.$mount() 127 | // #endif 128 | 129 | // #ifdef VUE3 130 | import { createSSRApp } from 'vue' 131 | export function createApp() { 132 | const app = createSSRApp(App) 133 | return { 134 | app 135 | } 136 | } 137 | // #endif -------------------------------------------------------------------------------- /uni-wxmp-catering/uni_modules/uni-transition/components/uni-transition/createAnimation.js: -------------------------------------------------------------------------------- 1 | // const defaultOption = { 2 | // duration: 300, 3 | // timingFunction: 'linear', 4 | // delay: 0, 5 | // transformOrigin: '50% 50% 0' 6 | // } 7 | // #ifdef APP-NVUE 8 | const nvueAnimation = uni.requireNativePlugin('animation') 9 | // #endif 10 | class MPAnimation { 11 | constructor(options, _this) { 12 | this.options = options 13 | this.animation = uni.createAnimation(options) 14 | this.currentStepAnimates = {} 15 | this.next = 0 16 | this.$ = _this 17 | 18 | } 19 | 20 | _nvuePushAnimates(type, args) { 21 | let aniObj = this.currentStepAnimates[this.next] 22 | let styles = {} 23 | if (!aniObj) { 24 | styles = { 25 | styles: {}, 26 | config: {} 27 | } 28 | } else { 29 | styles = aniObj 30 | } 31 | if (animateTypes1.includes(type)) { 32 | if (!styles.styles.transform) { 33 | styles.styles.transform = '' 34 | } 35 | let unit = '' 36 | if(type === 'rotate'){ 37 | unit = 'deg' 38 | } 39 | styles.styles.transform += `${type}(${args+unit}) ` 40 | } else { 41 | styles.styles[type] = `${args}` 42 | } 43 | this.currentStepAnimates[this.next] = styles 44 | } 45 | _animateRun(styles = {}, config = {}) { 46 | let ref = this.$.$refs['ani'].ref 47 | if (!ref) return 48 | return new Promise((resolve, reject) => { 49 | nvueAnimation.transition(ref, { 50 | styles, 51 | ...config 52 | }, res => { 53 | resolve() 54 | }) 55 | }) 56 | } 57 | 58 | _nvueNextAnimate(animates, step = 0, fn) { 59 | let obj = animates[step] 60 | if (obj) { 61 | let { 62 | styles, 63 | config 64 | } = obj 65 | this._animateRun(styles, config).then(() => { 66 | step += 1 67 | this._nvueNextAnimate(animates, step, fn) 68 | }) 69 | } else { 70 | this.currentStepAnimates = {} 71 | typeof fn === 'function' && fn() 72 | this.isEnd = true 73 | } 74 | } 75 | 76 | step(config = {}) { 77 | // #ifndef APP-NVUE 78 | this.animation.step(config) 79 | // #endif 80 | // #ifdef APP-NVUE 81 | this.currentStepAnimates[this.next].config = Object.assign({}, this.options, config) 82 | this.currentStepAnimates[this.next].styles.transformOrigin = this.currentStepAnimates[this.next].config.transformOrigin 83 | this.next++ 84 | // #endif 85 | return this 86 | } 87 | 88 | run(fn) { 89 | // #ifndef APP-NVUE 90 | this.$.animationData = this.animation.export() 91 | this.$.timer = setTimeout(() => { 92 | typeof fn === 'function' && fn() 93 | }, this.$.durationTime) 94 | // #endif 95 | // #ifdef APP-NVUE 96 | this.isEnd = false 97 | let ref = this.$.$refs['ani'] && this.$.$refs['ani'].ref 98 | if(!ref) return 99 | this._nvueNextAnimate(this.currentStepAnimates, 0, fn) 100 | this.next = 0 101 | // #endif 102 | } 103 | } 104 | 105 | 106 | const animateTypes1 = ['matrix', 'matrix3d', 'rotate', 'rotate3d', 'rotateX', 'rotateY', 'rotateZ', 'scale', 'scale3d', 107 | 'scaleX', 'scaleY', 'scaleZ', 'skew', 'skewX', 'skewY', 'translate', 'translate3d', 'translateX', 'translateY', 108 | 'translateZ' 109 | ] 110 | const animateTypes2 = ['opacity', 'backgroundColor'] 111 | const animateTypes3 = ['width', 'height', 'left', 'right', 'top', 'bottom'] 112 | animateTypes1.concat(animateTypes2, animateTypes3).forEach(type => { 113 | MPAnimation.prototype[type] = function(...args) { 114 | // #ifndef APP-NVUE 115 | this.animation[type](...args) 116 | // #endif 117 | // #ifdef APP-NVUE 118 | this._nvuePushAnimates(type, args) 119 | // #endif 120 | return this 121 | } 122 | }) 123 | 124 | export function createAnimation(option, _this) { 125 | if(!_this) return 126 | clearTimeout(_this.timer) 127 | return new MPAnimation(option, _this) 128 | } 129 | -------------------------------------------------------------------------------- /element-admin/src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueRouter from 'vue-router' 3 | import Main from '../views/main.vue' 4 | 5 | Vue.use(VueRouter) 6 | 7 | const routes = [ 8 | { 9 | path: '/', 10 | name: 'main', 11 | component: Main, 12 | redirect: '/order', 13 | children: [ 14 | { 15 | path: '/order', 16 | component: () => import('../views/order.vue') 17 | }, 18 | //档案 19 | { 20 | path: '/data/goods', 21 | component: () => import('../views/data/goods.vue') 22 | }, 23 | { 24 | path: '/data/category', 25 | component: () => import('../views/data/category.vue') 26 | }, 27 | { 28 | path: '/data/price', 29 | component: () => import('../views/data/price.vue') 30 | }, 31 | { 32 | path: '/data/wx_user', 33 | component: () => import('../views/data/wx_user.vue') 34 | }, 35 | //营销 36 | { 37 | path: '/promotion/banner', 38 | component: () => import('../views/promotion/banner.vue') 39 | }, 40 | { 41 | path: '/promotion/seckilling', 42 | component: () => import('../views/promotion/seckilling.vue') 43 | }, 44 | { 45 | path: '/promotion/recommend', 46 | component: () => import('../views/promotion/recommend.vue') 47 | }, 48 | { 49 | path: '/promotion/hot', 50 | component: () => import('../views/promotion/hot.vue') 51 | }, 52 | { 53 | path: '/promotion/coupon', 54 | component: () => import('../views/promotion/coupon.vue') 55 | }, 56 | //设置 57 | { 58 | path: '/setting/store', 59 | component: () => import('../views/setting/store.vue') 60 | }, 61 | { 62 | path: '/setting/freight', 63 | component: () => import('../views/setting/freight.vue') 64 | }, 65 | { 66 | path: '/setting/pay', 67 | component: () => import('../views/setting/pay.vue') 68 | }, 69 | { 70 | path: '/setting/printer', 71 | component: () => import('../views/setting/printer.vue') 72 | } 73 | ] 74 | }, 75 | { 76 | path: '/login', 77 | name: 'login', 78 | meta: { 79 | requireNoAuth: true, // 该路由项无需校验 80 | }, 81 | component: () => import('../views/login/login.vue') 82 | }, 83 | { 84 | path: '/reg', 85 | name: 'reg', 86 | meta: { 87 | requireNoAuth: true, // 该路由项无需校验 88 | }, 89 | component: () => import('../views/login/reg.vue') 90 | } 91 | ] 92 | 93 | const router = new VueRouter({ 94 | routes 95 | }) 96 | 97 | // 全局前置守卫(回调函数) 98 | router.beforeEach((to, from, next) => { 99 | if (to.meta.requireNoAuth == true) { 100 | window.console.log(`路由${to.path}不验证token`) 101 | next() 102 | } else { 103 | window.console.log(`路由${to.path}需要验证token`) 104 | if (window.localStorage.getItem('token') != undefined) { 105 | window.console.log('token存在') 106 | // let tokenTimetoInt = window.localStorage.getItem('tokenExpire') 107 | // tokenTimetoInt = +tokenTimetoInt + 1800000//毫秒 108 | // // window.console.log('555:'+tokenTimetoInt) 109 | // // window.console.log('666:'+new Date().getTime()) 110 | // if (tokenTimetoInt < new Date().getTime()) { 111 | // window.console.log('token过期时间小于当前时间') 112 | // new Vue().$message.error('登录已过期 请重新登录') 113 | // window.localStorage.clear() 114 | // next({ 115 | // path: '/login', 116 | // query: { redirect: to.fullPath } // 将跳转的路由path作为参数,登录成功后跳转到该路由 117 | // }) 118 | // } 119 | // else { 120 | // window.console.log('token过期时间大于当前时间,刷新token过期时间') 121 | // window.localStorage.setItem("tokenExpire", new Date().getTime()); 122 | // } 123 | next() 124 | } else { 125 | window.console.log('token不存在') 126 | new Vue().$message.error('无法打开界面 请先登录') 127 | window.localStorage.clear() 128 | next({ 129 | path: '/login', 130 | query: { redirect: to.fullPath } // 将跳转的路由path作为参数,登录成功后跳转到该路由 131 | }) 132 | } 133 | } 134 | }) 135 | 136 | //此VueRouter是自己自定义引入暴露出来的,即是自定义的,以下的VueRouter同样是这样 137 | //解决两次访问相同路由地址报错 138 | const routerPush = VueRouter.prototype.push 139 | VueRouter.prototype.push = function push(location) { 140 | window.console.log('不用跳转') 141 | return routerPush.call(this, location).catch(error => error) 142 | } 143 | 144 | //界面刷新或界面关闭 145 | window.onunload = function () { 146 | window.localStorage.clear() 147 | } 148 | 149 | export default router 150 | -------------------------------------------------------------------------------- /element-admin/src/views/main.vue: -------------------------------------------------------------------------------- 1 | 98 | 99 | 123 | -------------------------------------------------------------------------------- /uni-wxmp-catering/uni_modules/uni-popup/components/uni-popup-share/uni-popup-share.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 106 | 186 | -------------------------------------------------------------------------------- /element-admin/src/views/data/price.vue: -------------------------------------------------------------------------------- 1 | 75 | 167 | -------------------------------------------------------------------------------- /element-admin/src/views/data/wx_user.vue: -------------------------------------------------------------------------------- 1 | 90 | 91 | -------------------------------------------------------------------------------- /uni-wxmp-catering/App.vue: -------------------------------------------------------------------------------- 1 | 58 | 59 | 250 | -------------------------------------------------------------------------------- /element-admin/src/views/setting/store.vue: -------------------------------------------------------------------------------- 1 | 80 | 81 | -------------------------------------------------------------------------------- /uni-wxmp-catering/pages/coupon-list/index.vue: -------------------------------------------------------------------------------- 1 | 61 | 62 | 103 | 104 | 105 | 218 | 219 | -------------------------------------------------------------------------------- /uni-wxmp-catering/uni_modules/uni-popup/components/uni-popup-dialog/uni-popup-dialog.vue: -------------------------------------------------------------------------------- 1 | 27 | 28 | 164 | 165 | 264 | -------------------------------------------------------------------------------- /element-admin/src/views/setting/freight.vue: -------------------------------------------------------------------------------- 1 | 118 | 119 | -------------------------------------------------------------------------------- /uni-wxmp-catering/components/dialog/dialog.vue: -------------------------------------------------------------------------------- 1 | 37 | 38 | 103 | 104 | -------------------------------------------------------------------------------- /uni-wxmp-catering/uni_modules/uni-transition/components/uni-transition/uni-transition.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 276 | 277 | 278 | -------------------------------------------------------------------------------- /uni-wxmp-catering/uni_modules/uni-popup/readme.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Popup 弹出层 4 | > **组件名:uni-popup** 5 | > 代码块: `uPopup` 6 | > 关联组件:`uni-popup-dialog`,`uni-popup-message`,`uni-popup-share`,`uni-transition` 7 | 8 | 9 | 弹出层组件,在应用中弹出一个消息提示窗口、提示框等 10 | 11 | 12 | > **注意事项** 13 | > 为了避免错误使用,给大家带来不好的开发体验,请在使用组件前仔细阅读下面的注意事项,可以帮你避免一些错误。 14 | > - 组件需要依赖 `sass` 插件 ,请自行手动安装 15 | > - `uni-popup-message` 、 `uni-popup-dialog` 等扩展ui组件,需要和 `uni-popup` 配套使用,暂不支持单独使用 16 | > - `nvue` 中使用 `uni-popup` 时,尽量将组件置于其他元素后面,避免出现层级问题 17 | > - `uni-popup` 并不能完全阻止页面滚动,可在打开 `uni-popup` 的时候手动去做一些处理,禁止页面滚动 18 | > - 如果想在页面渲染完毕后就打开 `uni-popup` ,请在 `onReady` 或 `mounted` 生命周期内调用,确保组件渲染完毕 19 | > - 在微信小程序开发者工具中,启用真机调试,popup 会延时出现,是因为 setTimeout 在真机调试中的延时问题导致的,预览和发布小程序不会出现此问题 20 | > - 使用 `npm` 方式引入组件,如果确认引用正确,但是提示未注册组件或显示不正常,请尝试重新编译项目 21 | > - `uni-popup` 中尽量不要使用 `scroll-view` 嵌套过多的内容,可能会影响组件的性能,导致组件无法打开或者打开卡顿 22 | > - `uni-popup` 不会覆盖原生 tabbar 和原生导航栏 23 | > - 组件支持 nvue ,需要在 `manifest.json > app-plus` 节点下配置 `"nvueStyleCompiler" : "uni-app"` 24 | > - 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 25 | 26 | 27 | 28 | ### 安装方式 29 | 30 | 本组件符合[easycom](https://uniapp.dcloud.io/collocation/pages?id=easycom)规范,`HBuilderX 2.5.5`起,只需将本组件导入项目,在页面`template`中即可直接使用,无需在页面中`import`和注册`components`。 31 | 32 | 如需通过`npm`方式使用`uni-ui`组件,另见文档:[https://ext.dcloud.net.cn/plugin?id=55](https://ext.dcloud.net.cn/plugin?id=55) 33 | 34 | 35 | ### 基本用法 36 | 37 | **示例** 38 | 39 | ```html 40 | 41 | 底部弹出 Popup 42 | ``` 43 | 44 | ```javascript 45 | export default { 46 | methods:{ 47 | open(){ 48 | // 通过组件定义的ref调用uni-popup方法 ,如果传入参数 ,type 属性将失效 ,仅支持 ['top','left','bottom','right','center'] 49 | this.$refs.popup.open('top') 50 | } 51 | } 52 | } 53 | 54 | ``` 55 | 56 | ### 设置主窗口背景色 57 | 58 | 在大多数场景下,并不需要设置 `background-color` 属性,因为`uni-popup`的主窗口默认是透明的,在向里面插入内容的时候 ,样式完全交由用户定制,如果设置了背景色 ,例如 `uni-popup-dialog` 中的圆角就很难去实现,不设置背景色,更适合用户去自由发挥。 59 | 60 | 而也有特例,需要我们主动去设置背景色,例如 `type = 'bottom'` 的时候 ,在异型屏中遇到了底部安全区问题(如 iphone 11),因为 `uni-popup`的主要内容避开了安全区(设置`safe-area:true`),导致底部的颜色我们无法自定义,这时候使用 `background-color` 就可以解决这个问题。 61 | 62 | **示例** 63 | 64 | ```html 65 | 66 | 底部弹出 Popup 67 | ``` 68 | 69 | ### 禁用打开动画 70 | 在某些场景 ,可能不希望弹层有动画效果 ,只需要将 `animation` 属性设置为 `false` 即可以关闭动画。 71 | 72 | **示例** 73 | 74 | ```html 75 | 76 | 中间弹出 Popup 77 | ``` 78 | 79 | ### 禁用点击遮罩关闭 80 | 默认情况下,点击遮罩会自动关闭`uni-popup`,如不想点击关闭,只需将`mask-click`设置为`false`,这时候要关闭`uni-popup`,只能手动调用 `close` 方法。 81 | 82 | **示例** 83 | 84 | ```html 85 | 86 | 87 | Popup 88 | 89 | 90 | ``` 91 | 92 | ```javascript 93 | export default { 94 | data() { 95 | return {} 96 | }, 97 | onReady() {}, 98 | methods: { 99 | open() { 100 | this.$refs.popup.open('top') 101 | }, 102 | close() { 103 | this.$refs.popup.close() 104 | } 105 | } 106 | } 107 | 108 | ``` 109 | 110 | ## API 111 | 112 | ### Popup Props 113 | 114 | |属性名|类型|默认值|说明| 115 | |:-:|:-:|:-:|:-:| 116 | |animation|Boolean|true|是否开启动画| 117 | |type|String|'center'|弹出方式| 118 | |mask-click|Boolean|true|蒙版点击是否关闭弹窗| 119 | |background-color|String|'none'|主窗口背景色| 120 | |safe-area|Boolean|true|是否适配底部安全区| 121 | 122 | #### Type Options 123 | 124 | |属性名|说明| 125 | |:-:| :-:| 126 | |top|顶部弹出 | 127 | |center|居中弹出| 128 | |bottom|底部弹出| 129 | |left|左侧弹出| 130 | |right|右侧弹出| 131 | |message|预置样式 :消息提示| 132 | |dialog|预置样式 :对话框| 133 | |share|预置样式 :底部弹出分享示例 | 134 | 135 | 136 | ### Popup Methods 137 | 138 | |方法称名 |说明|参数| 139 | |:-:|:-:|:-:| 140 | |open|打开弹出层|open(String:type) ,如果参数可代替 type 属性| 141 | |close|关闭弹出层 |-| 142 | 143 | 144 | ### Popup Events 145 | 146 | |事件称名|说明|返回值| 147 | |:-:|:-:|:-:| 148 | |change|组件状态发生变化触发|e={show: true|false,type:当前模式}| 149 | |maskClick|点击遮罩层触发|-| 150 | 151 | 152 | ## 扩展组件说明 153 | `uni-popup` 其实并没有任何样式,只提供基础的动画效果,给用户一个弹出层解决方案,仅仅是这样并不能满足开发需求,所以我们提供了三种基础扩展样式 154 | 155 | ### uni-popup-message 提示信息 156 | 157 | 将 `uni-popup` 的`type`属性改为 `message`,并引入对应组件即可使用消息提示 ,*该组件不支持单独使用* 158 | 159 | **示例** 160 | 161 | ```html 162 | 163 | 164 | 165 | ``` 166 | 167 | ### PopupMessage Props 168 | 169 | |属性名|类型|默认值|说明| 170 | |:-:|:-:|:-:|:-:| 171 | |type|String|success|消息提示主题| 172 | |message|String|-|消息提示文字| 173 | |duration|Number|3000|消息显示时间,超过显示时间组件自动关闭,设置为0 将不会关闭,需手动调用 close 方法关闭| 174 | 175 | #### Type Options 176 | 177 | |属性名|说明| 178 | |:-:| :-:| 179 | |success|成功 | 180 | |warn|警告| 181 | |error|失败| 182 | |info|消息| 183 | 184 | ### PopupMessage Slots 185 | 186 | |名称|说明| 187 | |:-:|:-:| 188 | |default|消息内容,会覆盖 message 属性| 189 | 190 | ### uni-popup-dialog 对话框 191 | 192 | 将 `uni-popup` 的`type`属性改为 `dialog`,并引入对应组件即可使用对话框 ,*该组件不支持单独使用* 193 | 194 | **示例** 195 | 196 | ```html 197 | 198 | 199 | 200 | 201 | ``` 202 | 203 | ```javascript 204 | export default { 205 | methods: { 206 | open() { 207 | this.$refs.popup.open() 208 | }, 209 | /** 210 | * 点击取消按钮触发 211 | * @param {Object} done 212 | */ 213 | close() { 214 | // TODO 做一些其他的事情,before-close 为true的情况下,手动执行 close 才会关闭对话框 215 | // ... 216 | this.$refs.popup.close() 217 | }, 218 | /** 219 | * 点击确认按钮触发 220 | * @param {Object} done 221 | * @param {Object} value 222 | */ 223 | confirm(value) { 224 | // 输入框的值 225 | console.log(value) 226 | // TODO 做一些其他的事情,手动执行 close 才会关闭对话框 227 | // ... 228 | this.$refs.popup.close() 229 | } 230 | } 231 | } 232 | ``` 233 | 234 | ### PopupDialog Props 235 | 236 | |属性名|类型|默认值|说明| 237 | |:-:|:-:|:-:|:-:| 238 | |type|String|success|对话框标题主题,可选值: success/warn/info/error| 239 | |mode|String|base| 对话框模式,可选值:base(提示对话框)/input(可输入对话框)| 240 | |title|String|-|对话框标题| 241 | |content|String|-|对话框内容,base模式下生效| 242 | |value| String\Number|-|输入框默认值,input模式下生效| 243 | |placeholder|String|-|输入框提示文字,input模式下生效| 244 | |before-close|Boolean|false | 是否拦截按钮事件,如为true,则不会关闭对话框,关闭需要手动执行 uni-popup 的 close 方法| 245 | 246 | #### PopupDialog Events 247 | 248 | |事件称名 |说明|返回值| 249 | |:-:|:-:|:-:| 250 | |close|点击dialog取消按钮触发|-| 251 | |confirm|点击dialog确定按钮触发|e={value:input模式下输入框的值}| 252 | 253 | ### PopupDialog Slots 254 | 255 | |名称|说明| 256 | |:-:|:-:| 257 | |default|自定义内容,回覆盖原有的内容显示| 258 | 259 | ### uni-popup-share 分享示例 260 | 261 | 分享示例,不作为最终可使用的组件,只做为样式组件,供用户自行修改,`后续的开发计划是实现实际的分享逻辑,参数可配置`。 262 | 263 | 将 `uni-popup` 的 `type` 属性改为 `share`,并引入对应组件即可使用 ,*该组件不支持单独使用* 264 | 265 | **示例** 266 | 267 | ```html 268 | 269 | 270 | 271 | ``` 272 | 273 | ### PopupShare Props 274 | 275 | |属性名|类型|默认值|说明| 276 | |:-:|:-:|:-:| :-: | 277 | |title|String|-|分享弹窗标题| 278 | |before-close|Boolean|false | 是否拦截按钮事件,如为true,则不会关闭对话框,关闭需要手动执行 uni-popup 的 close 方法| 279 | 280 | ### PopupShare Events 281 | 282 | |事件称名|说明|返回值| 283 | |:-:|:-:|:-:| 284 | |select|选择触发|e = {item,index}:所选参数| 285 | 286 | **Tips** 287 | - share 分享组件,只是作为一个扩展示例,如果需要修改数据源,请到组件内修改 288 | 289 | ## 帮助 290 | 在使用中如遇到无法解决的问题,请提 [Issues](https://github.com/dcloudio/uni-ui/issues) 给我们。 291 | 292 | 293 | 294 | ## 组件示例 295 | 296 | 点击查看:[https://hellouniapp.dcloud.net.cn/pages/extUI/popup/popup](https://hellouniapp.dcloud.net.cn/pages/extUI/popup/popup) -------------------------------------------------------------------------------- /element-admin/src/views/promotion/hot.vue: -------------------------------------------------------------------------------- 1 | 124 | 125 | -------------------------------------------------------------------------------- /element-admin/src/views/promotion/recommend.vue: -------------------------------------------------------------------------------- 1 | 126 | 127 | -------------------------------------------------------------------------------- /element-admin/src/views/data/category.vue: -------------------------------------------------------------------------------- 1 | 128 | 129 | -------------------------------------------------------------------------------- /element-admin/src/views/promotion/coupon.vue: -------------------------------------------------------------------------------- 1 | 150 | 151 | -------------------------------------------------------------------------------- /element-admin/src/views/promotion/seckilling.vue: -------------------------------------------------------------------------------- 1 | 139 | 140 | -------------------------------------------------------------------------------- /uni-wxmp-catering/uni_modules/uni-transition/readme.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Transition 过渡动画 4 | > **组件名:uni-transition** 5 | > 代码块: `uTransition` 6 | 7 | 8 | 元素过渡动画 9 | 10 | > **注意事项** 11 | > 为了避免错误使用,给大家带来不好的开发体验,请在使用组件前仔细阅读下面的注意事项,可以帮你避免一些错误。 12 | > - 组件需要依赖 `sass` 插件 ,请自行手动安装 13 | > - rotate 旋转动画不需要填写 deg 单位,在小程序上填写单位动画不会执行 14 | > - NVUE 下修改宽高动画,不能定位到中心点 15 | > - 百度小程序下修改宽高 ,可能会影响其他动画,需注意 16 | > - nvue 不支持 costom-class , 请使用 styles 17 | > - 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 18 | 19 | 20 | ### 安装方式 21 | 22 | 本组件符合[easycom](https://uniapp.dcloud.io/collocation/pages?id=easycom)规范,`HBuilderX 2.5.5`起,只需将本组件导入项目,在页面`template`中即可直接使用,无需在页面中`import`和注册`components`。 23 | 24 | 如需通过`npm`方式使用`uni-ui`组件,另见文档:[https://ext.dcloud.net.cn/plugin?id=55](https://ext.dcloud.net.cn/plugin?id=55) 25 | 26 | ### 基本用法 27 | 28 | 在 ``template`` 中使用组件 29 | 30 | ```html 31 | 37 | 38 | 56 | ``` 57 | 58 | ### 样式覆盖 59 | 60 | **注意:`nvue` 不支持 `custom-class` 属性 ,需要使用 `styles` 属性进行兼容** 61 | 62 | 使用 `custom-class` 属性绑定样式,可以自定义 `uni-transition` 的样式 63 | 64 | ```html 65 | 70 | 71 | 79 | 87 | ``` 88 | 89 | 90 | 如果使用 `styles` 注意带’-‘连接符的属性需要使用小驼峰写法如:`backgroundColor:red` 91 | 92 | ```html 93 | 98 | 111 | ``` 112 | 113 | ### 自定义动画 114 | 当内置动画类型不能满足需求的时候 ,可以使用 `step()` 和 `run()` 自定义动画,入参以及具体用法参考下方属性说明 115 | 116 | `init()` 方法可以覆盖默认配置 117 | 118 | 119 | ```html 120 | 126 | 127 | 166 | ``` 167 | 168 | 169 | ## API 170 | 171 | ### Transition Props 172 | 173 | |属性名 |类型 |默认值 |说明 | 174 | |:-: |:-: |:-: |:-:| 175 | |show |Boolean|false |控制组件显示或隐藏 | 176 | |mode-class |Array/String |- |内置过渡动画类型 | 177 | |custom-class |String |- |自定义类名 | 178 | |duration |Number |300 |过渡动画持续时间 | 179 | |styles |Object |- |组件样式,同 css 样式,注意带’-‘连接符的属性需要使用小驼峰写法如:`backgroundColor:red` | 180 | 181 | #### mode-class 内置过渡动画类型说明 182 | **格式为** :`'fade'` 或者 `['fade','slide-top']` 183 | 184 | |属性名 |说明 | 185 | |:-: |:-: | 186 | |fade |渐隐渐出过渡 | 187 | |slide-top |由上至下过渡 | 188 | |slide-right |由右至左过渡 | 189 | |slide-bottom |由下至上过渡 | 190 | |slide-left |由左至右过渡 | 191 | |zoom-in |由小到大过渡 | 192 | |zoom-out |由大到小过渡 | 193 | 194 | **注意** 195 | 196 | 组合使用时,同一种类型相反的过渡动画如(slide-top、slide-bottom)同时使用时,只有最后一个生效 197 | 198 | ### Transition Events 199 | 200 | |事件名 |说明 |返回值 | 201 | |:-: |:-: |:-: | 202 | |click |点击组件触发 |- | 203 | |change |过渡动画结束时触发 | e = {detail:true} | 204 | 205 | ### Transition Methons 206 | 207 | |方法名|说明|参数| 208 | |:-:|:-:|:-:| 209 | |init()|手动初始化配置|Function(OBJECT:config)| 210 | |step()|动画队列|Function(OBJECT:type,OBJECT:config)| 211 | |run()|执行动画|Function(FUNCTION:callback) | 212 | 213 | ### init(OBJECT:config) 214 | **通过 ref 调用方法** 215 | 216 | 手动设置动画配置,需要在页面渲染完毕后调用 217 | 218 | ```javascript 219 | this.$refs.ani.init({ 220 | duration: 1000, 221 | timingFunction:'ease', 222 | delay:500, 223 | transformOrigin:'left center' 224 | }) 225 | ``` 226 | 227 | ### step(OBJECT:type,OBJECT:config) 动画队列 228 | **通过 ref 调用方法** 229 | 230 | 调用 `step()` 来表示一组动画完成,`step` 第一个参数可以传入任意多个动画方法,一组动画中的所有动画会同时开始,一组动画完成后才会进行下一组动画。`step` 第二个参数可以传入一个跟 `uni.createAnimation()` 一样的配置参数用于指定当前组动画的配置。 231 | 232 | Tips 233 | - 第一个参数支持的动画参考下面的 `支持的动画` 234 | - 第二个参数参考下面的 `动画配置`,可省略,如果省略继承`init`的配置 235 | 236 | 237 | ```javascript 238 | this.$refs.ani.step({ 239 | translateX: '100px' 240 | },{ 241 | duration: 1000, 242 | timingFunction:'ease', 243 | delay:500, 244 | transformOrigin:'left center' 245 | }) 246 | ``` 247 | 248 | ### run(FUNCTION:callback) 执行动画 249 | **通过 ref 调用方法** 250 | 251 | 在执行 `step()` 后,需要调用 `run()` 来运行动画 ,否则动画会一直等待 252 | 253 | `run()` 方法可以传入一个 `callback` 函数 ,会在所有动画执行完毕后回调 254 | 255 | ```javascript 256 | this.$refs.ani.step({ 257 | translateX: '100px' 258 | }) 259 | this.$refs.ani.run(()=>{ 260 | console.log('动画执行完毕') 261 | }) 262 | 263 | ``` 264 | 265 | ### 动画配置 266 | 动画配置 , `init()` 与 `step()` 第二个参数配置相同 ,如果配置`step() `第二个参数,将会覆盖 `init()` 的配置 267 | 268 | |属性名|值|必填|默认值|说明|平台差异| 269 | |:-:|:-:|:-:|:-:|:-:|:-:| 270 | |duration|Number|否|400|动画持续时间,单位ms|-| 271 | |timingFunction|String|否|"linear"|定义动画的效果|-| 272 | |delay|Number|否|0|动画延迟时间,单位 ms|-| 273 | |needLayout|Boolean|否|false |动画执行是否影响布局|仅 nvue 支持| 274 | |transformOrigin|String |否|"center center"|设置 [transform-origin](https://developer.mozilla.org/en-US/docs/Web/CSS/transform-origin)|-| 275 | 276 | 277 | ### timingFunction 属性说明 278 | 279 | |值|说明|平台差异| 280 | |:-:|:-:|:-:| 281 | |linear|动画从头到尾的速度是相同的|-| 282 | |ease|动画以低速开始,然后加快,在结束前变慢|-| 283 | |ease-in| 动画以低速开始|-| 284 | |ease-in-out| 动画以低速开始和结束|-| 285 | |ease-out|动画以低速结束|-| 286 | |step-start|动画第一帧就跳至结束状态直到结束|nvue不支持| 287 | |step-end|动画一直保持开始状态,最后一帧跳到结束状态|nvue不支持| 288 | 289 | ```javascript 290 | // init 配置 291 | this.$refs.ani.init({ 292 | duration: 1000, 293 | timingFunction:'ease', 294 | delay:500, 295 | transformOrigin:'left center' 296 | }) 297 | // step 配置 298 | this.$refs.ani.step({ 299 | translateX: '100px' 300 | },{ 301 | duration: 1000, 302 | timingFunction:'ease', 303 | delay:500, 304 | transformOrigin:'left center' 305 | }) 306 | ``` 307 | 308 | ### 支持的动画 309 | 动画方法 310 | 311 | 如果同一个动画方法有多个值,多个值使用数组分隔 312 | 313 | ```javascript 314 | this.$refs.ani.step({ 315 | width:'100px', 316 | scale: [1.2,0.8], 317 | }) 318 | ``` 319 | 320 | **样式:** 321 | 322 | |属性名|值|说明|平台差异| 323 | |:-:|:-:|:-:|:-:| 324 | |opacity|value|透明度,参数范围 0~1|-| 325 | |backgroundColor|color|颜色值|-| 326 | |width|length|长度值,如果传入 Number 则默认使用 px,可传入其他自定义单位的长度值|-| 327 | |height|length|长度值,如果传入 Number 则默认使用 px,可传入其他自定义单位的长度值|-| 328 | |top|length|长度值,如果传入 Number 则默认使用 px,可传入其他自定义单位的长度值|nvue 不支持| 329 | |left|length|长度值,如果传入 Number 则默认使用 px,可传入其他自定义单位的长度值|nvue 不支持| 330 | |bottom|length|长度值,如果传入 Number 则默认使用 px,可传入其他自定义单位的长度值|nvue 不支持| 331 | |right|length|长度值,如果传入 Number 则默认使用 px,可传入其他自定义单位的长度值|nvue 不支持| 332 | 333 | ```javascript 334 | this.$refs.ani.step({ 335 | opacity: 1, 336 | backgroundColor: '#ff5a5f', 337 | widht:'100px', 338 | height:'50rpx', 339 | }) 340 | ``` 341 | 342 | **旋转:** 343 | 344 | 旋转属性的值不需要填写单位 345 | 346 | |属性名|值|说明|平台差异 | 347 | |:-:|:-:|:-:|:-:| 348 | |rotate|deg|deg的范围-180~180,从原点顺时针旋转一个deg角度 |-| 349 | |rotateX|deg|deg的范围-180~180,在X轴旋转一个deg角度 |-| 350 | |rotateY|deg|deg的范围-180~180,在Y轴旋转一个deg角度 |-| 351 | |rotateZ|deg|deg的范围-180~180,在Z轴旋转一个deg角度 |nvue不支持| 352 | |rotate3d|x,y,z,deg| 同 [transform-function rotate3d](https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/rotate3d()) |nvue不支持| 353 | 354 | ```javascript 355 | this.$refs.ani.step({ 356 | rotateX: 45, 357 | rotateY: 45 358 | }) 359 | ``` 360 | 361 | **缩放:** 362 | 363 | |属性名|值|说明|平台差异| 364 | |:-:|:-:|:-: |:-:| 365 | |scale|sx,[sy]|一个参数时,表示在X轴、Y轴同时缩放sx倍数;两个参数时表示在X轴缩放sx倍数,在Y轴缩放sy倍数|-| 366 | |scaleX|sx|在X轴缩放sx倍数|-| 367 | |scaleY|sy|在Y轴缩放sy倍数|-| 368 | |scaleZ|sz|在Z轴缩放sy倍数|nvue不支持| 369 | |scale3d|sx,sy,sz|在X轴缩放sx倍数,在Y轴缩放sy倍数,在Z轴缩放sz倍数|nvue不支持| 370 | 371 | ```javascript 372 | this.$refs.ani.step({ 373 | scale: [1.2,0.8] 374 | }) 375 | ``` 376 | 377 | **偏移:** 378 | 379 | |属性名|值|说明|平台差异| 380 | |:-:|:-:|:-:|:-:| 381 | |translate|tx,[ty]|一个参数时,表示在X轴偏移tx,单位px;两个参数时,表示在X轴偏移tx,在Y轴偏移ty,单位px。|-| 382 | |translateX|tx| 在X轴偏移tx,单位px|-| 383 | |translateY|ty| 在Y轴偏移tx,单位px|-| 384 | |translateZ|tz| 在Z轴偏移tx,单位px|nvue不支持| 385 | |translate3d|tx,ty,tz| 在X轴偏移tx,在Y轴偏移ty,在Z轴偏移tz,单位px|nvue不支持| 386 | 387 | ```javascript 388 | this.$refs.ani.step({ 389 | translateX: '100px' 390 | }) 391 | ``` 392 | 393 | 394 | 395 | ## 组件示例 396 | 397 | 点击查看:[https://hellouniapp.dcloud.net.cn/pages/extUI/transition/transition](https://hellouniapp.dcloud.net.cn/pages/extUI/transition/transition) --------------------------------------------------------------------------------