1、提货点
2、客服(腾讯云智服)
3、接口权限控制
4、复制第三方商品可配置
4、优化附件上传配置
5、手机端核销订单
6、手机端订单统计、订单管理
7、短信优化
8、订阅消息全自动化
This commit is contained in:
张乐
2020-09-15 16:13:25 +08:00
parent aee9c1d692
commit db2c3b44a6
245 changed files with 19900 additions and 994 deletions

View File

@@ -25,7 +25,7 @@
### 加技术交流群
![加技术交流群](https://images.gitee.com/uploads/images/2020/0910/164840_9c544220_2012975.png "屏幕截图.png")
![加技术交流群](https://images.gitee.com/uploads/images/2020/0915/153227_4c47d782_2012975.png "屏幕截图.png")
如果群二维码过期请加开发者微信拉你进群

473
admin/package-lock.json generated
View File

@@ -299,9 +299,9 @@
}
},
"@babel/parser": {
"version": "7.10.2",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz",
"integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ=="
"version": "7.11.5",
"resolved": "https://registry.npm.taobao.org/@babel/parser/download/@babel/parser-7.11.5.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fparser%2Fdownload%2F%40babel%2Fparser-7.11.5.tgz",
"integrity": "sha1-x/9jA99xCA7HpPW4wAPFjxz1EDc="
},
"@babel/plugin-proposal-async-generator-functions": {
"version": "7.10.1",
@@ -962,6 +962,11 @@
"any-observable": "^0.3.0"
}
},
"@sindresorhus/is": {
"version": "0.14.0",
"resolved": "https://registry.npm.taobao.org/@sindresorhus/is/download/@sindresorhus/is-0.14.0.tgz",
"integrity": "sha1-n7OjzzEyMoFR81PeRjLgHlIQK+o="
},
"@soda/friendly-errors-webpack-plugin": {
"version": "1.7.1",
"resolved": "https://registry.npmjs.org/@soda/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-1.7.1.tgz",
@@ -1036,6 +1041,14 @@
}
}
},
"@szmarczak/http-timer": {
"version": "1.1.2",
"resolved": "https://registry.npm.taobao.org/@szmarczak/http-timer/download/@szmarczak/http-timer-1.1.2.tgz",
"integrity": "sha1-sWZeLEYaLNkvTBu/UNVFTeDUtCE=",
"requires": {
"defer-to-connect": "^1.0.1"
}
},
"@types/codemirror": {
"version": "0.0.71",
"resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-0.0.71.tgz",
@@ -2342,12 +2355,9 @@
"dev": true
},
"async-validator": {
"version": "1.8.5",
"resolved": "https://registry.npmjs.org/async-validator/-/async-validator-1.8.5.tgz",
"integrity": "sha512-tXBM+1m056MAX0E8TL2iCjg8WvSyXu0Zc8LNtYqrVeyoL3+esHRZ4SieE9fKQyyU09uONjnMEjrNBMqT0mbvmA==",
"requires": {
"babel-runtime": "6.x"
}
"version": "1.12.2",
"resolved": "https://registry.npm.taobao.org/async-validator/download/async-validator-1.12.2.tgz?cache=0&sync_timestamp=1596623539220&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fasync-validator%2Fdownload%2Fasync-validator-1.12.2.tgz",
"integrity": "sha1-vq5nHnF00pOLe0tp0vt+cit/1yw="
},
"asynckit": {
"version": "0.4.0",
@@ -2361,18 +2371,26 @@
"dev": true
},
"autoprefixer": {
"version": "9.8.0",
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.0.tgz",
"integrity": "sha512-D96ZiIHXbDmU02dBaemyAg53ez+6F5yZmapmgKcjm35yEe1uVDYI8hGW3VYoGRaG290ZFf91YxHrR518vC0u/A==",
"version": "9.8.6",
"resolved": "https://registry.npm.taobao.org/autoprefixer/download/autoprefixer-9.8.6.tgz?cache=0&sync_timestamp=1596140745397&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fautoprefixer%2Fdownload%2Fautoprefixer-9.8.6.tgz",
"integrity": "sha1-O3NZTKG/kmYyDFrPFYjXTep0IQ8=",
"dev": true,
"requires": {
"browserslist": "^4.12.0",
"caniuse-lite": "^1.0.30001061",
"chalk": "^2.4.2",
"caniuse-lite": "^1.0.30001109",
"colorette": "^1.2.1",
"normalize-range": "^0.1.2",
"num2fraction": "^1.2.2",
"postcss": "^7.0.30",
"postcss": "^7.0.32",
"postcss-value-parser": "^4.1.0"
},
"dependencies": {
"caniuse-lite": {
"version": "1.0.30001129",
"resolved": "https://registry.npm.taobao.org/caniuse-lite/download/caniuse-lite-1.0.30001129.tgz?cache=0&sync_timestamp=1600023834293&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcaniuse-lite%2Fdownload%2Fcaniuse-lite-1.0.30001129.tgz",
"integrity": "sha1-5lFLlMDvUPmM90dtqpEijd0u97w=",
"dev": true
}
}
},
"aws-sign2": {
@@ -3278,6 +3296,11 @@
"node-int64": "^0.4.0"
}
},
"bson": {
"version": "1.1.5",
"resolved": "https://registry.npm.taobao.org/bson/download/bson-1.1.5.tgz?cache=0&sync_timestamp=1597071247841&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbson%2Fdownload%2Fbson-1.1.5.tgz",
"integrity": "sha1-Kqrpj832dQwISLDLod3sPHMGCjQ="
},
"buffer": {
"version": "4.9.2",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz",
@@ -3424,6 +3447,40 @@
}
}
},
"cacheable-request": {
"version": "6.1.0",
"resolved": "https://registry.npm.taobao.org/cacheable-request/download/cacheable-request-6.1.0.tgz",
"integrity": "sha1-IP+4vRYrpL4R6VZ9gj22UQUsqRI=",
"requires": {
"clone-response": "^1.0.2",
"get-stream": "^5.1.0",
"http-cache-semantics": "^4.0.0",
"keyv": "^3.0.0",
"lowercase-keys": "^2.0.0",
"normalize-url": "^4.1.0",
"responselike": "^1.0.2"
},
"dependencies": {
"get-stream": {
"version": "5.2.0",
"resolved": "https://registry.npm.taobao.org/get-stream/download/get-stream-5.2.0.tgz?cache=0&sync_timestamp=1597056491448&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fget-stream%2Fdownload%2Fget-stream-5.2.0.tgz",
"integrity": "sha1-SWaheV7lrOZecGxLe+txJX1uItM=",
"requires": {
"pump": "^3.0.0"
}
},
"lowercase-keys": {
"version": "2.0.0",
"resolved": "https://registry.npm.taobao.org/lowercase-keys/download/lowercase-keys-2.0.0.tgz",
"integrity": "sha1-JgPni3tLAAbLyi+8yKMgJVislHk="
},
"normalize-url": {
"version": "4.5.0",
"resolved": "https://registry.npm.taobao.org/normalize-url/download/normalize-url-4.5.0.tgz",
"integrity": "sha1-RTNUCH5sqWlXvY9br3U/WYIUISk="
}
}
},
"call-me-maybe": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz",
@@ -3930,6 +3987,14 @@
"shallow-clone": "^3.0.0"
}
},
"clone-response": {
"version": "1.0.2",
"resolved": "https://registry.npm.taobao.org/clone-response/download/clone-response-1.0.2.tgz",
"integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=",
"requires": {
"mimic-response": "^1.0.0"
}
},
"co": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
@@ -4016,6 +4081,12 @@
"simple-swizzle": "^0.2.2"
}
},
"colorette": {
"version": "1.2.1",
"resolved": "https://registry.npm.taobao.org/colorette/download/colorette-1.2.1.tgz?cache=0&sync_timestamp=1593955826637&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcolorette%2Fdownload%2Fcolorette-1.2.1.tgz",
"integrity": "sha1-TQuSEyXBT6+SYzCGpTbbbolWSxs=",
"dev": true
},
"combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@@ -4878,6 +4949,14 @@
"integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
"dev": true
},
"decompress-response": {
"version": "3.3.0",
"resolved": "https://registry.npm.taobao.org/decompress-response/download/decompress-response-3.3.0.tgz",
"integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
"requires": {
"mimic-response": "^1.0.0"
}
},
"dedent": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz",
@@ -4976,6 +5055,11 @@
"clone": "^1.0.2"
}
},
"defer-to-connect": {
"version": "1.1.3",
"resolved": "https://registry.npm.taobao.org/defer-to-connect/download/defer-to-connect-1.1.3.tgz",
"integrity": "sha1-MxrgUMCNz3ifjIOnuB8O2U9KxZE="
},
"define-properties": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
@@ -5366,6 +5450,11 @@
"integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=",
"dev": true
},
"duplexer3": {
"version": "0.1.4",
"resolved": "https://registry.npm.taobao.org/duplexer3/download/duplexer3-0.1.4.tgz",
"integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI="
},
"duplexify": {
"version": "3.7.1",
"resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
@@ -5458,6 +5547,14 @@
"throttle-debounce": "^1.0.1"
},
"dependencies": {
"async-validator": {
"version": "1.8.5",
"resolved": "https://registry.npm.taobao.org/async-validator/download/async-validator-1.8.5.tgz?cache=0&sync_timestamp=1596623539220&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fasync-validator%2Fdownload%2Fasync-validator-1.8.5.tgz",
"integrity": "sha1-3D4I7B/Q3dtn5ghC8CwM0c7G1/A=",
"requires": {
"babel-runtime": "6.x"
}
},
"throttle-debounce": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-1.1.0.tgz",
@@ -5509,7 +5606,6 @@
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
"integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
"dev": true,
"requires": {
"once": "^1.4.0"
}
@@ -7229,6 +7325,34 @@
"delegate": "^3.1.2"
}
},
"got": {
"version": "9.6.0",
"resolved": "https://registry.npm.taobao.org/got/download/got-9.6.0.tgz",
"integrity": "sha1-7fRefWf5lUVwXeH3u+7rEhdl7YU=",
"requires": {
"@sindresorhus/is": "^0.14.0",
"@szmarczak/http-timer": "^1.1.2",
"cacheable-request": "^6.0.0",
"decompress-response": "^3.3.0",
"duplexer3": "^0.1.4",
"get-stream": "^4.1.0",
"lowercase-keys": "^1.0.1",
"mimic-response": "^1.0.1",
"p-cancelable": "^1.0.0",
"to-readable-stream": "^1.0.0",
"url-parse-lax": "^3.0.0"
},
"dependencies": {
"get-stream": {
"version": "4.1.0",
"resolved": "https://registry.npm.taobao.org/get-stream/download/get-stream-4.1.0.tgz?cache=0&sync_timestamp=1597056491448&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fget-stream%2Fdownload%2Fget-stream-4.1.0.tgz",
"integrity": "sha1-wbJVV189wh1Zv8ec09K0axw6VLU=",
"requires": {
"pump": "^3.0.0"
}
}
}
},
"graceful-fs": {
"version": "4.2.4",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
@@ -7656,6 +7780,11 @@
}
}
},
"http-cache-semantics": {
"version": "4.1.0",
"resolved": "https://registry.npm.taobao.org/http-cache-semantics/download/http-cache-semantics-4.1.0.tgz",
"integrity": "sha1-SekcXL82yblLz81xwj1SSex045A="
},
"http-deceiver": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz",
@@ -10423,6 +10552,11 @@
"integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
"dev": true
},
"json-buffer": {
"version": "3.0.0",
"resolved": "https://registry.npm.taobao.org/json-buffer/download/json-buffer-3.0.0.tgz",
"integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg="
},
"json-parse-better-errors": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
@@ -10502,6 +10636,19 @@
"set-immediate-shim": "~1.0.1"
}
},
"kareem": {
"version": "2.3.1",
"resolved": "https://registry.npm.taobao.org/kareem/download/kareem-2.3.1.tgz",
"integrity": "sha1-3vEtnJQQF/q/sA+HOvlenJnhvoc="
},
"keyv": {
"version": "3.1.0",
"resolved": "https://registry.npm.taobao.org/keyv/download/keyv-3.1.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fkeyv%2Fdownload%2Fkeyv-3.1.0.tgz",
"integrity": "sha1-7MIoSG9pmR5J6UdkhaW+Ho/FxNk=",
"requires": {
"json-buffer": "3.0.0"
}
},
"killable": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
@@ -10955,6 +11102,11 @@
"integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=",
"dev": true
},
"lodash.isempty": {
"version": "4.4.0",
"resolved": "https://registry.npm.taobao.org/lodash.isempty/download/lodash.isempty-4.4.0.tgz",
"integrity": "sha1-b4bL7di+TsmHvpqvM8loTbGzHn4="
},
"lodash.kebabcase": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz",
@@ -11099,6 +11251,11 @@
"lower-case": "^1.1.2"
}
},
"lowercase-keys": {
"version": "1.0.1",
"resolved": "https://registry.npm.taobao.org/lowercase-keys/download/lowercase-keys-1.0.1.tgz",
"integrity": "sha1-b54wtHCE2XGnyCD/FabFFnt0wm8="
},
"lru-cache": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
@@ -11245,6 +11402,12 @@
"readable-stream": "^2.0.1"
}
},
"memory-pager": {
"version": "1.5.0",
"resolved": "https://registry.npm.taobao.org/memory-pager/download/memory-pager-1.5.0.tgz",
"integrity": "sha1-2HUWVdItOEaCdByXLyw9bfo+ZrU=",
"optional": true
},
"meow": {
"version": "3.7.0",
"resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
@@ -11408,6 +11571,11 @@
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
"integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ=="
},
"mimic-response": {
"version": "1.0.1",
"resolved": "https://registry.npm.taobao.org/mimic-response/download/mimic-response-1.0.1.tgz",
"integrity": "sha1-SSNTiHju9CBjy4o+OweYeBSHqxs="
},
"mini-css-extract-plugin": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.5.0.tgz",
@@ -11533,6 +11701,47 @@
"loader-utils": "^1.2.3"
}
},
"mongodb": {
"version": "3.4.1",
"resolved": "https://registry.npm.taobao.org/mongodb/download/mongodb-3.4.1.tgz",
"integrity": "sha1-DRXlfg6g/IW3pPuSkbN0wucWUtw=",
"requires": {
"bson": "^1.1.1",
"require_optional": "^1.0.1",
"safe-buffer": "^5.1.2",
"saslprep": "^1.0.0"
}
},
"mongoose": {
"version": "5.8.9",
"resolved": "https://registry.npm.taobao.org/mongoose/download/mongoose-5.8.9.tgz?cache=0&sync_timestamp=1599846406427&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmongoose%2Fdownload%2Fmongoose-5.8.9.tgz",
"integrity": "sha1-YWrp30zX9B99LXfQN62UeESFvXQ=",
"requires": {
"bson": "~1.1.1",
"kareem": "2.3.1",
"mongodb": "3.4.1",
"mongoose-legacy-pluralize": "1.0.2",
"mpath": "0.6.0",
"mquery": "3.2.2",
"ms": "2.1.2",
"regexp-clone": "1.0.0",
"safe-buffer": "5.1.2",
"sift": "7.0.1",
"sliced": "1.0.1"
},
"dependencies": {
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npm.taobao.org/ms/download/ms-2.1.2.tgz",
"integrity": "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk="
}
}
},
"mongoose-legacy-pluralize": {
"version": "1.0.2",
"resolved": "https://registry.npm.taobao.org/mongoose-legacy-pluralize/download/mongoose-legacy-pluralize-1.0.2.tgz",
"integrity": "sha1-O6n5H6UHtRhtOZ+0CFS/8Y+1Y+Q="
},
"move-concurrently": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
@@ -11547,6 +11756,46 @@
"run-queue": "^1.0.3"
}
},
"mpath": {
"version": "0.6.0",
"resolved": "https://registry.npm.taobao.org/mpath/download/mpath-0.6.0.tgz",
"integrity": "sha1-qpIgKfyk8PZB82DnTFwbakxHB44="
},
"mpvue-calendar": {
"version": "2.3.7",
"resolved": "https://registry.npm.taobao.org/mpvue-calendar/download/mpvue-calendar-2.3.7.tgz",
"integrity": "sha1-c/fyJalOiAMmtsxLm+Bo3phNCeE=",
"requires": {
"core-js": "^3.4.4",
"vue": "^2.6.10"
},
"dependencies": {
"core-js": {
"version": "3.6.5",
"resolved": "https://registry.npm.taobao.org/core-js/download/core-js-3.6.5.tgz?cache=0&sync_timestamp=1592817929546&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcore-js%2Fdownload%2Fcore-js-3.6.5.tgz",
"integrity": "sha1-c5XcJzrzf7LlDpvT2f6EEoUjHRo="
}
}
},
"mquery": {
"version": "3.2.2",
"resolved": "https://registry.npm.taobao.org/mquery/download/mquery-3.2.2.tgz",
"integrity": "sha1-4Tg6OVGFLOI+N/YZqbNQ8fs2ZOc=",
"requires": {
"bluebird": "3.5.1",
"debug": "3.1.0",
"regexp-clone": "^1.0.0",
"safe-buffer": "5.1.2",
"sliced": "1.0.1"
},
"dependencies": {
"bluebird": {
"version": "3.5.1",
"resolved": "https://registry.npm.taobao.org/bluebird/download/bluebird-3.5.1.tgz",
"integrity": "sha1-2VUfnemPH82h5oPRfukaBgLuLrk="
}
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
@@ -12534,6 +12783,11 @@
"os-tmpdir": "^1.0.0"
}
},
"p-cancelable": {
"version": "1.1.0",
"resolved": "https://registry.npm.taobao.org/p-cancelable/download/p-cancelable-1.1.0.tgz",
"integrity": "sha1-0HjRWjr0CSIMiG8dmgyi5EGrJsw="
},
"p-defer": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz",
@@ -13850,6 +14104,11 @@
"integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
"dev": true
},
"prepend-http": {
"version": "2.0.0",
"resolved": "https://registry.npm.taobao.org/prepend-http/download/prepend-http-2.0.0.tgz",
"integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc="
},
"preserve": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz",
@@ -14029,7 +14288,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
"dev": true,
"requires": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
@@ -14289,6 +14547,11 @@
"safe-regex": "^1.1.0"
}
},
"regexp-clone": {
"version": "1.0.0",
"resolved": "https://registry.npm.taobao.org/regexp-clone/download/regexp-clone-1.0.0.tgz",
"integrity": "sha1-Ii25Z2IydwViYLmSYmNUoEzpv2M="
},
"regexp.prototype.flags": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz",
@@ -14502,6 +14765,22 @@
"resolve-from": "^1.0.0"
}
},
"require_optional": {
"version": "1.0.1",
"resolved": "https://registry.npm.taobao.org/require_optional/download/require_optional-1.0.1.tgz",
"integrity": "sha1-TPNaQkf2TKPfjC7yCMxJSxyo/C4=",
"requires": {
"resolve-from": "^2.0.0",
"semver": "^5.1.0"
},
"dependencies": {
"resolve-from": {
"version": "2.0.0",
"resolved": "https://registry.npm.taobao.org/resolve-from/download/resolve-from-2.0.0.tgz",
"integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c="
}
}
},
"requires-port": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
@@ -14514,6 +14793,11 @@
"integrity": "sha1-79qpjqdFEyTQkrKyFjpqHXqaIUc=",
"dev": true
},
"resize-detector": {
"version": "0.1.10",
"resolved": "https://registry.npm.taobao.org/resize-detector/download/resize-detector-0.1.10.tgz",
"integrity": "sha1-HaP5YapfkUzLz9N1LVL9Rb7raSw="
},
"resize-observer-polyfill": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
@@ -14567,6 +14851,14 @@
"integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
"dev": true
},
"responselike": {
"version": "1.0.2",
"resolved": "https://registry.npm.taobao.org/responselike/download/responselike-1.0.2.tgz",
"integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=",
"requires": {
"lowercase-keys": "^1.0.0"
}
},
"restore-cursor": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
@@ -14789,6 +15081,15 @@
}
}
},
"saslprep": {
"version": "1.0.3",
"resolved": "https://registry.npm.taobao.org/saslprep/download/saslprep-1.0.3.tgz",
"integrity": "sha1-TAL5RrVs9UKX40e6EJPnrKxM8iY=",
"optional": true,
"requires": {
"sparse-bitfield": "^3.0.3"
}
},
"sass-graph": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.5.tgz",
@@ -14830,8 +15131,7 @@
"sax": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
"dev": true
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
},
"schema-utils": {
"version": "2.7.0",
@@ -15324,6 +15624,11 @@
}
}
},
"sift": {
"version": "7.0.1",
"resolved": "https://registry.npm.taobao.org/sift/download/sift-7.0.1.tgz",
"integrity": "sha1-R9YsULFZ0xbxNy+LU/nBDNIaSwg="
},
"sigmund": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz",
@@ -15409,6 +15714,11 @@
}
}
},
"sliced": {
"version": "1.0.1",
"resolved": "https://registry.npm.taobao.org/sliced/download/sliced-1.0.1.tgz",
"integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E="
},
"snake-case": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/snake-case/-/snake-case-2.1.0.tgz",
@@ -15653,6 +15963,15 @@
"integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
"dev": true
},
"sparse-bitfield": {
"version": "3.0.3",
"resolved": "https://registry.npm.taobao.org/sparse-bitfield/download/sparse-bitfield-3.0.3.tgz",
"integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=",
"optional": true,
"requires": {
"memory-pager": "^1.0.2"
}
},
"spdx-correct": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz",
@@ -16762,9 +17081,9 @@
"dev": true
},
"throttle-debounce": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-2.2.1.tgz",
"integrity": "sha512-i9hAVld1f+woAiyNGqWelpDD5W1tpMroL3NofTz9xzwq6acWBlO2dC8k5EFSZepU6oOINtV5Q3aSPoRg7o4+fA=="
"version": "2.3.0",
"resolved": "https://registry.npm.taobao.org/throttle-debounce/download/throttle-debounce-2.3.0.tgz?cache=0&sync_timestamp=1597225176825&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fthrottle-debounce%2Fdownload%2Fthrottle-debounce-2.3.0.tgz",
"integrity": "sha1-/TGGXmZQIHHkEYF+JBRls+nDcuI="
},
"through": {
"version": "2.3.8",
@@ -16876,6 +17195,11 @@
}
}
},
"to-readable-stream": {
"version": "1.0.0",
"resolved": "https://registry.npm.taobao.org/to-readable-stream/download/to-readable-stream-1.0.0.tgz",
"integrity": "sha1-zgqgwvPfat+FLvtASng+d8BHV3E="
},
"to-regex": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
@@ -16934,21 +17258,6 @@
"integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=",
"dev": true
},
"tree": {
"version": "0.1.3",
"resolved": "https://registry.npm.taobao.org/tree/download/tree-0.1.3.tgz",
"integrity": "sha1-FPulc9eFMAnEzO9E90CfrHFik48=",
"requires": {
"underscore": "^1.10.2"
},
"dependencies": {
"underscore": {
"version": "1.10.2",
"resolved": "https://registry.npm.taobao.org/underscore/download/underscore-1.10.2.tgz",
"integrity": "sha1-c9aqNmjzGI5K2w8ZQ70Sz9fvqq8="
}
}
},
"trim-newlines": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
@@ -17363,6 +17672,14 @@
"requires-port": "^1.0.0"
}
},
"url-parse-lax": {
"version": "3.0.0",
"resolved": "https://registry.npm.taobao.org/url-parse-lax/download/url-parse-lax-3.0.0.tgz",
"integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=",
"requires": {
"prepend-http": "^2.0.0"
}
},
"url-slug": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/url-slug/-/url-slug-2.0.0.tgz",
@@ -17459,6 +17776,11 @@
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
"dev": true
},
"vconsole": {
"version": "3.3.4",
"resolved": "https://registry.npm.taobao.org/vconsole/download/vconsole-3.3.4.tgz",
"integrity": "sha1-p9rNiIez0+kC6NGEJc2lbDTnf1E="
},
"vendors": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz",
@@ -17500,6 +17822,15 @@
"resolved": "https://registry.npmjs.org/vue-count-to/-/vue-count-to-1.0.13.tgz",
"integrity": "sha512-6R4OVBVNtQTlcbXu6SJ8ENR35M2/CdWt3Jmv57jOUM+1ojiFmjVGvZPH8DfHpMDSA+ITs+EW5V6qthADxeyYOQ=="
},
"vue-echarts": {
"version": "4.1.0",
"resolved": "https://registry.npm.taobao.org/vue-echarts/download/vue-echarts-4.1.0.tgz",
"integrity": "sha1-/0goqqWZ56qqyV41KX2WQZKjrw0=",
"requires": {
"lodash": "^4.17.15",
"resize-detector": "^0.1.10"
}
},
"vue-eslint-parser": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-2.0.3.tgz",
@@ -17648,22 +17979,27 @@
"dev": true
},
"vue-ueditor-wrap": {
"version": "2.4.3",
"resolved": "https://registry.npmjs.org/vue-ueditor-wrap/-/vue-ueditor-wrap-2.4.3.tgz",
"integrity": "sha512-7oMUQ1f+m5k0SWE1ndVQ4RY8JI7LX5T6DO3uDvfZqefrp1hzL5VUE1eEhtxS9PbdNIx9QuOatbNW9yAGp8NxLw=="
"version": "2.4.4",
"resolved": "https://registry.npm.taobao.org/vue-ueditor-wrap/download/vue-ueditor-wrap-2.4.4.tgz",
"integrity": "sha1-F4u8YLqZOKgx5n32tXjOCMprOCM="
},
"vue-ydui": {
"version": "1.2.6",
"resolved": "https://registry.npm.taobao.org/vue-ydui/download/vue-ydui-1.2.6.tgz",
"integrity": "sha1-GQZItGcjkXAEpMJKe+/TzWnWQ1U="
},
"vuedraggable": {
"version": "2.23.2",
"resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-2.23.2.tgz",
"integrity": "sha512-PgHCjUpxEAEZJq36ys49HfQmXglattf/7ofOzUrW2/rRdG7tu6fK84ir14t1jYv4kdXewTEa2ieKEAhhEMdwkQ==",
"version": "2.24.1",
"resolved": "https://registry.npm.taobao.org/vuedraggable/download/vuedraggable-2.24.1.tgz",
"integrity": "sha1-MEq9dkTd4FwfGZoie/npEH9WGXo=",
"requires": {
"sortablejs": "^1.10.1"
},
"dependencies": {
"sortablejs": {
"version": "1.10.2",
"resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.10.2.tgz",
"integrity": "sha512-YkPGufevysvfwn5rfdlGyrGjt7/CRHwvRPogD/lC+TnvcN29jDpCifKP+rBqf+LRldfXSTh+0CGLcSg0VIxq3A=="
"resolved": "https://registry.npm.taobao.org/sortablejs/download/sortablejs-1.10.2.tgz?cache=0&sync_timestamp=1600124099427&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsortablejs%2Fdownload%2Fsortablejs-1.10.2.tgz",
"integrity": "sha1-bkA2TZE/mLhaFPZnj5K1wSIfUpA="
}
}
},
@@ -18315,6 +18651,39 @@
"integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==",
"dev": true
},
"wechat-jssdk": {
"version": "5.0.4",
"resolved": "https://registry.npm.taobao.org/wechat-jssdk/download/wechat-jssdk-5.0.4.tgz",
"integrity": "sha1-QZ1TAjuEzAfIkNM+3c1XkVUcY+c=",
"requires": {
"date-fns": "2.9.0",
"debug": "4.1.1",
"got": "9.6.0",
"lodash.isempty": "4.4.0",
"mongoose": "5.8.9",
"xml2js": "0.4.23"
},
"dependencies": {
"date-fns": {
"version": "2.9.0",
"resolved": "https://registry.npm.taobao.org/date-fns/download/date-fns-2.9.0.tgz",
"integrity": "sha1-0LF1pcN+1fF7l+InK7wfpa7Gd9I="
},
"debug": {
"version": "4.1.1",
"resolved": "https://registry.npm.taobao.org/debug/download/debug-4.1.1.tgz",
"integrity": "sha1-O3ImAlUQnGtYnO4FDx1RYTlmR5E=",
"requires": {
"ms": "^2.1.1"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npm.taobao.org/ms/download/ms-2.1.2.tgz",
"integrity": "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk="
}
}
},
"whatwg-encoding": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz",
@@ -18486,6 +18855,20 @@
"integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==",
"dev": true
},
"xml2js": {
"version": "0.4.23",
"resolved": "https://registry.npm.taobao.org/xml2js/download/xml2js-0.4.23.tgz",
"integrity": "sha1-oMaVFnUkIesqx1juTUzPWIQ+rGY=",
"requires": {
"sax": ">=0.6.0",
"xmlbuilder": "~11.0.0"
}
},
"xmlbuilder": {
"version": "11.0.1",
"resolved": "https://registry.npm.taobao.org/xmlbuilder/download/xmlbuilder-11.0.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fxmlbuilder%2Fdownload%2Fxmlbuilder-11.0.1.tgz",
"integrity": "sha1-vpuuHIoEbnazESdyY0fQrXACvrM="
},
"xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",

View File

@@ -44,6 +44,7 @@
},
"dependencies": {
"@babel/parser": "^7.9.6",
"async-validator": "^1.11.2",
"axios": "0.18.1",
"clipboard": "2.0.4",
"codemirror": "5.45.0",
@@ -58,6 +59,7 @@
"jsonlint": "1.6.3",
"jszip": "3.2.1",
"monaco-editor": "^0.20.0",
"mpvue-calendar": "^2.3.7",
"node-sass": "^4.13.1",
"normalize.css": "7.0.0",
"nprogress": "0.2.0",
@@ -68,16 +70,19 @@
"showdown": "1.9.0",
"sortablejs": "1.8.4",
"throttle-debounce": "^2.1.0",
"tree": "^0.1.3",
"tui-editor": "1.3.3",
"vconsole": "^3.3.2",
"vue": "2.6.10",
"vue-awesome-swiper": "^3.1.3",
"vue-count-to": "1.0.13",
"vue-echarts": "^4.0.3",
"vue-router": "3.0.2",
"vue-splitpane": "1.0.4",
"vue-ueditor-wrap": "^2.4.1",
"vue-ydui": "^1.2.6",
"vuedraggable": "^2.20.0",
"vuex": "3.1.0",
"wechat-jssdk": "^5.0.4",
"xlsx": "0.14.1"
},
"devDependencies": {

View File

@@ -109,3 +109,68 @@ export function orderRefundApi(params) {
params
})
}
/**
* 订单 核销订单
* @param pram
*/
export function writeUpdateApi(vCode) {
return request({
url: `/admin/store/order/writeUpdate/${vCode}`,
method: 'get'
})
}
/**
* 订单 核销码查询待核销订单
* @param pram
*/
export function writeConfirmApi(vCode) {
return request({
url: `/admin/store/order/writeConfirm/${vCode}`,
method: 'get'
})
}
/**
* 订单 统计 头部数据
*/
export function orderStatisticsApi() {
return request({
url: `/admin/store/order/statistics`,
method: 'get'
})
}
/**
* 核销订单 月列表数据
*/
export function statisticsDataApi(params) {
return request({
url: `/admin/store/order/statisticsData`,
method: 'get',
params
})
}
/**
* 一键改价
*/
export function editPriceApi(params) {
return request({
url: `/admin/store/order/editPrice`,
method: 'get',
params
})
}
/**
*订单统计详情
*/
export function orderTimeApi(params) {
return request({
url: `/admin/store/order/time`,
method: 'get',
params
})
}

View File

@@ -4,13 +4,14 @@ export function addRole(pram) {
const data = {
level: pram.level,
roleName: pram.roleName,
status: pram.status
status: pram.status,
rules: pram.rules.join(',')
}
data.rules = pram.rules.join(',')
// data.rules = pram.rules.join(',')
return request({
url: '/admin/system/role/save',
method: 'POST',
params: data
data: data
})
}
@@ -54,6 +55,7 @@ export function getRoleList(pram) {
})
}
export function updateRole(pram) {
const data = {
id: pram.id,
@@ -65,6 +67,7 @@ export function updateRole(pram) {
return request({
url: '/admin/system/role/update',
method: 'post',
params: data
params: {id: pram.id},
data: data
})
}

View File

@@ -210,7 +210,6 @@ export function replyDeleteApi(id) {
* @param pram
*/
export function replyCommentApi(data) {
console.log(data)
return request({
url: `/admin/store/product/reply/comment`,
method: 'post',

View File

@@ -295,7 +295,6 @@ export function groupSaveApi(data) {
* @param pram
*/
export function groupUpdateApi(params, data) {
console.log(params, data)
return request({
url: `/admin/user/group/update`,
method: 'post',

View File

@@ -1,4 +1,5 @@
import request from '@/utils/request'
// TODO 微信沟通难度大暂放 呵呵
export function menuCreate(data) {
@@ -57,7 +58,6 @@ export function wechatTemplateSaveApi(data) {
* @param pram
*/
export function wechatTemplateUpdateApi(id, data) {
console.log(id)
return request({
url: `/admin/wechat/template/update/${id}`,
method: 'post',
@@ -195,3 +195,158 @@ export function wechatMenuAddApi(data) {
data
})
}
/**
* 小程序 公共模板列表
*/
export function publicTempListApi(params) {
return request({
url: `/admin/wechat/program/public/temp/list`,
method: 'get',
params
})
}
/**
* 小程序 模版所属类目
*/
export function categoryApi() {
return request({
url: `/admin/wechat/program/category`,
method: 'get'
})
}
/**
* 小程序 通过微信模板tid获取关键字列表
*/
export function getWeChatKeywordsByTidApi(params) {
return request({
url: `/admin/wechat/program/getWeChatKeywordsByTid`,
method: 'get',
params
})
}
/**
* 小程序 模板详情,主要是获取左侧标题
*/
export function publicTempInfoApi(params) {
return request({
url: `/admin/wechat/program/public/temp/info`,
method: 'get',
params
})
}
/**
* 小程序 我的模板列表
*/
export function myTempListApi(params) {
return request({
url: `/admin/wechat/program/my/temp/list`,
method: 'get',
params
})
}
/**
* 小程序 我的模板详情
*/
export function myTempInfoApi(params) {
return request({
url: `/admin/wechat/program/my/temp/info`,
method: 'get',
params
})
}
/**
* 小程序 模板新增
*/
export function myTempSaveApi(data) {
return request({
url: `/admin/wechat/program/my/temp/save`,
method: 'post',
data
})
}
/**
* 小程序 模板修改
*/
export function myTempUpdateApi(params, data) {
return request({
url: `/admin/wechat/program/my/temp/update`,
method: 'post',
params,
data
})
}
/**
* 小程序 我的模板修改状态
*/
export function myTempStatusApi(params) {
return request({
url: `/admin/wechat/program/my/temp/update/status`,
method: 'get',
params
})
}
/**
* 小程序 我的模板修改应用场景
*/
export function myTempTypeApi(params) {
return request({
url: `/admin/wechat/program/my/temp/update/type`,
method: 'get',
params
})
}
/**
* 获取微信sdk配置
* @returns {*}
*/
export function getWechatConfig() {
return request({
url: `/admin/wechat/config`,
method: 'get',
params:{ url: encodeURIComponent(location.href.split('#')[0]) } // for Test
})
}
/**
* 微信授权登录
* @returns {*}
*/
export function wechatAuth(code) {
return request({
url: `/admin/authorize/login`,
method: 'get',
params: { code }
})
}
/**
* 与微信解绑账号
*/
export function unbindApi() {
return request({
url: `/admin/unbind`,
method: 'get'
})
}
/**
* 一键同步我的模板到小程序
*/
export function tempAsyncApi() {
return request({
url: `/admin/wechat/program/my/temp/async`,
method: 'get'
})
}

View File

File diff suppressed because one or more lines are too long

View File

Binary file not shown.

View File

File diff suppressed because one or more lines are too long

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 284 KiB

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

@@ -0,0 +1,62 @@
(function flexible(window, document) {
var docEl = document.documentElement || document.body;
var dpr = window.devicePixelRatio || 1;
// adjust body font size
function setBodyFontSize() {
if (document.body) {
} else {
document.addEventListener("DOMContentLoaded", setBodyFontSize);
}
}
setBodyFontSize();
// set 1rem = viewWidth / 10
function setRemUnit() {
var rem = docEl.clientWidth / 7.5;
docEl.style.fontSize = rem + "px";
}
setRemUnit();
// reset rem unit on page resize
window.addEventListener("resize", setRemUnit);
window.addEventListener("pageshow", function(e) {
if (e.persisted) {
setRemUnit();
}
});
// detect 0.5px supports
if (dpr >= 2) {
var fakeBody = document.createElement("body");
var testElement = document.createElement("div");
testElement.style.border = ".5px solid transparent";
fakeBody.appendChild(testElement);
docEl.appendChild(fakeBody);
if (testElement.offsetHeight === 1) {
docEl.classList.add("hairlines");
}
docEl.removeChild(fakeBody);
}
if (typeof WeixinJSBridge == "object" && typeof WeixinJSBridge.invoke == "function") {
handleFontSize();
} else {
if (document.addEventListener) {
document.addEventListener("WeixinJSBridgeReady", handleFontSize, false);
} else if (document.attachEvent) {
document.attachEvent("WeixinJSBridgeReady", handleFontSize);
document.attachEvent("onWeixinJSBridgeReady", handleFontSize);
}
}
function handleFontSize() {
// 设置网页字体为默认大小
WeixinJSBridge.invoke('setFontSizeCallback', { 'fontSize' : 0 });
// 重写设置网页字体大小的事件
WeixinJSBridge.on('menu:setfont', function() {
WeixinJSBridge.invoke('setFontSizeCallback', { 'fontSize' : 0 });
});
}
})(window, document);

View File

@@ -126,10 +126,8 @@ export default {
this.$emit('hideEditDialog')
},
initEditData() {
console.log(this.editData)
this.addTreeListLabelForCasCard(this.allTreeList, 'child')
this.parentOptions = this.allTreeList
console.log(this.parentOptions)
if (this.isCreate !== 1) {
const { id } = this.prent
this.editPram.pid = id
@@ -143,7 +141,6 @@ export default {
this.editPram.type = type
this.editPram.url = url
this.editPram.id = id
console.log(this.editPram.id)
}
},
addTreeListLabelForCasCard(arr, child) {

View File

@@ -2,13 +2,15 @@
<div>
<template v-if="selectModel">
<el-tree
node-key="id"
:props="treeProps"
ref="tree"
:data="treeList"
show-checkbox
:default-checked-keys="selectModelKeys"
@check="handleSelectionChange"
/>
check-strictly
node-key="id"
@check="getCurrentNode"
:default-checked-keys="selectModelKeysNew"
:props="treeProps">
</el-tree>
</template>
<template v-else>
<div class="divBox">
@@ -84,7 +86,7 @@
<el-table-column label="操作" min-width="200" fixed="right">
<template slot-scope="scope">
<el-button
v-if="biztype.value!==3 && scope.row.pid === 0"
v-if="(biztype.value === 1 && scope.row.pid === 0) || (biztype.value !== 1)"
type="text"
size="small"
@click="handleAddMenu(scope.row)"
@@ -145,6 +147,9 @@ export default {
type: Boolean,
default: false
},
// selectModelKeys: {
// type: String
// },
selectModelKeys: {
type: Array
},
@@ -152,6 +157,8 @@ export default {
},
data() {
return {
selectModelKeysNew: this.selectModelKeys,
loading: false,
constants,
treeProps: {
label: 'name',
@@ -207,6 +214,37 @@ export default {
this.editDialogConfig.biztype = this.biztype
this.editDialogConfig.visible = true
},
getCurrentNode(data) {
let node = this.$refs.tree.getNode(data);
this.childNodes(node);
this.parentNodes(node);
//是否编辑的表示
// this.ruleForm.isEditorFlag = true;
//编辑时候使用
this.$emit('rulesSelect', this.$refs.tree.getCheckedKeys());
// this.selectModelKeys = this.$refs.tree.getCheckedKeys();
//无论编辑和新增点击了就传到后台这个值
// this.$emit('rulesSelect', this.$refs.tree.getCheckedKeys().concat(this.$refs.tree.getHalfCheckedKeys()));
// this.ruleForm.menuIdsisEditor = this.$refs.tree.getCheckedKeys().concat(this.$refs.tree.getHalfCheckedKeys());
},
//具体方法可以看element官网api
childNodes(node){
let len = node.childNodes.length;
for(let i = 0; i < len; i++){
node.childNodes[i].checked = node.checked;
this.childNodes(node.childNodes[i]);
}
},
parentNodes(node){
if(node.parent){
for(let key in node){
if(key == "parent"){
node[key].checked = true;
this.parentNodes(node[key]);
}
}
}
},
handleDelMenu(rowData) {
this.$confirm('确定删除当前数据?').then(() => {
categoryApi.deleteCategroy(rowData).then(data => {
@@ -221,9 +259,14 @@ export default {
})
},
handlerGetTreeList() {
const _pram = { type: this.biztype.value, status: this.selectModel ? 1 : -1 }
// this.biztype.value === 5 && !this.selectModel) ? -1 : 1
const _pram = { type: this.biztype.value, status: !this.selectModel ? -1 : (this.biztype.value === 5 ? -1 : 1) }
this.loading = true
this.biztype.value!==3 ? categoryApi.treeCategroy(_pram).then(data => {
this.treeList = this.handleAddArrt(data)
this.loading = false
}).catch(()=>{
this.loading = false
}) : categoryApi.listCategroy({ type: 3, status: '', pid: this.listPram.pid}).then(data => {
this.treeList = data.list
})

View File

@@ -181,7 +181,6 @@ function buildProps(scheme, propsList) {
// el-upload的BeforeUpload
function buildBeforeUpload(scheme) {
console.log(scheme)
const config = scheme.__config__
const unitNum = units[config.sizeUnit]; let rightSizeCode = ''; let acceptCode = ''; const
returnList = []

View File

@@ -245,7 +245,6 @@ export default {
}
} catch (err) {
this.$message.error(`js错误${err}`)
console.error(err)
}
},
generateCode() {

View File

@@ -327,7 +327,6 @@ export default {
const clone = this.cloneComponent(item)
this.drawingList.push(clone)
this.activeFormItem(clone)
console.log(this.drawingList)
},
cloneComponent(origin) {
const clone = JSON.parse(JSON.stringify(origin))

View File

@@ -2,7 +2,7 @@
<div ref="rightPanel" :class="{show:show}" class="rightPanel-container">
<div class="rightPanel-background" />
<div class="rightPanel">
<div class="handle-button" :style="{'top':buttonTop+'px','background-color':theme}" @click="show=!show">
<div class="handle-button" :style="{'top':buttonTop+'px','background-color':theme}" @click="show=!show" v-if="!isPhone">
<i :class="show?'el-icon-close':'el-icon-setting'" />
</div>
<div class="rightPanel-items">
@@ -29,6 +29,7 @@ export default {
},
data() {
return {
isPhone: this.$wechat.isPhone(),
show: false
}
},

View File

@@ -35,7 +35,6 @@ export default {
if (typeof val !== 'string') return
const themeCluster = this.getThemeCluster(val.replace('#', ''))
const originalCluster = this.getThemeCluster(oldVal.replace('#', ''))
console.log(themeCluster, originalCluster)
const $message = this.$message({
message: ' Compiling the theme',

View File

@@ -8,44 +8,44 @@
:show-file-list="false"
multiple
>
<div class="upLoadPicBox" v-if="url">
<div v-if="url" class="upLoadPicBox">
<div class="upLoad">
<i class="el-icon-document-checked cameraIconfont" />
</div>
</div>
<el-button size="mini" type="primary" v-else>点击上传</el-button>
<el-button v-else size="mini" type="primary">点击上传</el-button>
</el-upload>
</div>
</template>
<script>
import { fileFileApi } from '@/api/systemSetting'
import { getToken } from '@/utils/auth'
export default {
name: "uploadFile",
import { fileFileApi } from '@/api/systemSetting'
import { getToken } from '@/utils/auth'
export default {
name: 'UploadFile',
props: {
value: {}
},
data() {
return {
myHeaders: {'X-Token': getToken()},
myHeaders: { 'X-Token': getToken() },
url: ''
}
},
props:{
value: {}
},
beforeMount(){
if(this.value){
beforeMount() {
if (this.value) {
this.url = this.value
}
},
methods: {
// 上传
handleUploadForm(param){
handleUploadForm(param) {
const formData = new FormData()
const data = {
model: this.$route.path.split("/")[1],
model: this.$route.path.split('/')[1],
pid: 10
}
formData.append('multipart', param.file)
let loading = this.$loading({
const loading = this.$loading({
lock: true,
text: '上传中,请稍候...',
spinner: 'el-icon-loading',
@@ -61,7 +61,7 @@
})
}
}
}
}
</script>
<style scoped>

View File

@@ -1,23 +1,18 @@
<template>
<el-dialog v-model="dialogFormVisible" title="请选择商城用户" append-to-body :visible.sync="dialogFormVisible" width="1000px" @close="cancel">
<el-dialog v-model="dialogFormVisible" title="请选择管理员" append-to-body :visible.sync="dialogFormVisible" width="1200px" @close="cancel">
<el-form ref="form" inline :model="artFrom">
<el-form-item label="搜索日期">
<el-radio-group v-model="artFrom.data" size="small" @change="search">
<el-radio-button :label="item.val" v-for="(item,index) in fromData" :key="index" >{{item.text}}</el-radio-button>
</el-radio-group>
<el-date-picker
v-model="timeVal"
size="small"
type="daterange"
range-separator=""
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="yyyy:MM:dd"
@change="onchangeTime">
</el-date-picker>
<el-form-item label="身份">
<el-select v-model="artFrom.roles" placeholder="请输入身份" clearable class="selWidth">
<el-option
v-for="item in roleList.list"
:key="item.id"
:label="item.roleName"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label="用户名称">
<el-input v-model="artFrom.keywords" size="small" placeholder="请输入用户名称" style="width:100%">
<el-form-item label="姓名">
<el-input v-model="artFrom.realName" size="small" placeholder="请输入姓名或者账号" class="selWidth">
<el-button slot="append" icon="el-icon-search" @click="search" class="">搜索</el-button>
</el-input>
</el-form-item>
@@ -33,56 +28,59 @@
label=""
width="55">
<template slot-scope="{ row, index }">
<el-radio v-model="templateRadio" :label="row.uid" @change.native="getTemplateRow(row.uid,row.avatar)">&nbsp;</el-radio>
<el-radio v-model="templateRadio" :label="row.uid" @change.native="getTemplateRow(row)">&nbsp;</el-radio>
</template>
</el-table-column>
<el-table-column
prop="uid"
prop="id"
label="ID"
sortable
width="80">
</el-table-column>
<el-table-column
prop="nickname"
label="微信用户名称"
min-Width="100">
prop="realName"
label="姓名"
min-Width="120">
</el-table-column>
<!--<el-table-column-->
<!--label="客服头像"-->
<!--min-Width="100">-->
<!--<template slot-scope="{ row, index }" class="picMiddle">-->
<!--<div class="demo-image__preview">-->
<!--<el-image-->
<!--:src="row.avatar"-->
<!--:preview-src-list="[row.avatar]"-->
<!--/>-->
<!--</div>-->
<!--</template>-->
<!--</el-table-column>-->
<el-table-column
label="客服头像"
min-Width="100">
<template slot-scope="{ row, index }" class="picMiddle">
<div class="demo-image__preview">
<el-image
:src="row.avatar"
:preview-src-list="[row.avatar]"
/>
</div>
prop="account"
label="账号"
min-Width="120"/>
<el-table-column label="身份" prop="realName" min-width="230">
<template slot-scope="scope">
<el-tag size="small" type="info" v-for="(item, index) in scope.row.roleNames.split(',')" class="mr5">{{ item }}</el-tag>
</template>
</el-table-column>
<el-table-column
prop="sex"
label="性别"
min-Width="60">
<template slot-scope="{ row, index }">
<span v-show="row.sex ===1"></span>
<span v-show="row.sex ===2"></span>
<span v-show="row.sex ===0">保密</span>
<el-table-column label="最后登录时间" prop="lastTime" min-width="180">
<template slot-scope="scope">
<span>{{ scope.row.lastTime | filterEmpty }}</span>
</template>
</el-table-column>
<el-table-column
prop="country"
label="地区"
min-Width="100">
<template slot-scope="{ row, index }">
{{row.country}}{{row.province}}{{row.city}}
<el-table-column label="最后登录IP" prop="lastIp" min-width="150">
<template slot-scope="scope">
<span>{{ scope.row.lastIp | filterEmpty }}</span>
</template>
</el-table-column>
<el-table-column
prop="subscribe"
label="是否关注公众号"
min-Width="100">
<template slot-scope="{ row, index }">
{{row.subscribe?'关注':'未关注'}}
<el-table-column label="状态" prop="status" min-width="100">
<template slot-scope="scope">
<span>{{ scope.row.status | filterShowOrHide }}</span>
</template>
</el-table-column>
<el-table-column label="删除标记" prop="status" min-width="100">
<template slot-scope="scope">
<span>{{ scope.row.isDel | filterYesOrNo }}</span>
</template>
</el-table-column>
</el-table>
@@ -102,11 +100,14 @@
</template>
<script>
import { userListApi } from '@/api/user';
import * as systemAdminApi from '@/api/systemadmin.js'
import * as roleApi from '@/api/role.js'
import * as constants from '@/utils/constants.js'
export default {
name: "index",
data(){
return{
return {
constants,
loading:false,
templateRadio:'',
dialogFormVisible:false,
@@ -114,37 +115,48 @@
artFrom: {
page: 1,
limit: 20,
data: '',
keywords: ''
status: 1,
realName: '',
roles: ''
},
total:0,
timeVal:'',
fromData: [
{ text: '全部', val: '' },
{ text: '今天', val: 'today' },
{ text: '昨天', val: 'yesterday' },
{ text: '最近7天', val: 'lately7' },
{ text: '最近30天', val: 'lately30' },
{ text: '本月', val: 'month' },
{ text: '本年', val: 'year' }
]
roleList: []
}
},
created(){
this.handleGetRoleList()
},
methods:{
getTemplateRow(id,img){
handleGetRoleList() {
const _pram = {
page: 1,
limit: 9999
}
roleApi.getRoleList(_pram).then(data => {
this.roleList = data
})
},
getTemplateRow(row){
this.dialogFormVisible = false;
this.$emit("upImgUid",id,img);
this.$emit("upImgUid", row);
},
tableList(){
let that = this;
that.loading = true;
userListApi(that.artFrom).then(res=>{
that.loading = false;
that.tableData = res.list;
that.total = res.total
this.loading = true;
systemAdminApi.adminList( this.artFrom ).then(data => {
this.tableData = data.list
this.total = data.total
this.loading = false;
}).catch(() => {
this.loading = false;
})
// let that = this;
// that.loading = true;
// userListApi(that.artFrom).then(res=>{
// that.loading = false;
// that.tableData = res.list;
// that.total = res.total
// })
},
//切换显示条数
sizeChange(index){
@@ -175,7 +187,7 @@
page: 1,
limit: 20,
data: '',
keywords: ''
realName: ''
};
this.timeVal = '';
this.templateRadio = ''

View File

@@ -67,7 +67,6 @@ export default {
iconChange(n) {
this.$emit('getIcon', n)
this.$msgbox.close()
console.log(n)
}
}
}

View File

@@ -13,8 +13,10 @@ export function filterEmpty(val) {
// 时间过滤器
export function formatDate(time) {
console.log(time)
if (time !== 0) {
const date = new Date(time * 1000);
console.log(date)
return formatDates(date, 'yyyy-MM-dd hh:mm');
}
}
@@ -93,3 +95,4 @@ export function articleTypeFilter(status) {
}
return arrayList.filter(item => Number(status) === Number(item.id))[0].name
}

View File

@@ -4,6 +4,7 @@ export { parseTime, formatTime } from '@/utils'
export * from '../filters/commFilter'
export * from '../filters/user'
export * from '../filters/order'
export * from '../filters/wx'
/**
* Show plural label if time is plural number

View File

@@ -5,22 +5,24 @@
*/
export function paidFilter(status) {
const statusMap = {
true: '支付',
false: '支付'
true: '支付',
false: '支付'
}
return statusMap[status]
}
/**
* @description 订单状态
* 2,已收货,待评价
*/
export function orderStatusFilter(status) {
const statusMap = {
'0': '待发货',
'1': '待收货',
'2': '已收货',
'3': '待评价',
'-1': '已退款'
'2': '待评价',
'3': '已完成',
'-2': '已退款',
'-1': '退款中'
}
return statusMap[status]
}

29
admin/src/filters/wx.js Normal file
View File

@@ -0,0 +1,29 @@
//小程序 微信过滤器
import Cookies from 'js-cookie'
/**
* @description 小程序所属类目
*/
export function wxCategoryFilter(status) {
if(!status){
return ''
}
if(!Cookies.get('WxCategory')) {
return
}
let arrayList = JSON.parse(Cookies.get('WxCategory'));
if(arrayList.filter(item => Number(status) === Number(item.id)).length < 1){
return ''
}
return arrayList.filter(item => Number(status) === Number(item.id))[0].name
}
/**
* @description 小程序模板类型
*/
export function wxTypeFilter(status) {
const statusMap = {
2: '一次性订阅',
3: '长期订阅'
}
return statusMap[status]
}

View File

@@ -37,6 +37,7 @@ export default {
.hasTagsView {
.app-main {
background: #f5f5f5;
/* 84 = navbar + tags-view = 50 + 34 */
min-height: calc(100vh - 84px);
}

View File

@@ -26,9 +26,10 @@
<router-link to="/">
<el-dropdown-item>控制台</el-dropdown-item>
</router-link>
<router-link :to=" { path: '/maintain/user' } ">
<router-link :to=" { path: '/maintain/user' } " v-if="!isPhone">
<el-dropdown-item>个人中心</el-dropdown-item>
</router-link>
<el-dropdown-item @click.native="onUnbundling">解绑账号</el-dropdown-item>
<!-- <a target="_blank" href="https://github.com/PanJiaChen/vue-element-admin/">-->
<!-- <el-dropdown-item>Github</el-dropdown-item>-->
<!-- </a>-->
@@ -51,6 +52,7 @@ import Hamburger from '@/components/Hamburger'
import ErrorLog from '@/components/ErrorLog'
import Screenfull from '@/components/Screenfull'
import Search from '@/components/HeaderSearch'
import { unbindApi } from '@/api/wxApi'
export default {
components: {
@@ -60,6 +62,11 @@ export default {
Screenfull,
Search
},
data() {
return {
isPhone: this.$wechat.isPhone()
}
},
computed: {
...mapGetters([
'sidebar',
@@ -68,6 +75,13 @@ export default {
])
},
methods: {
onUnbundling() {
this.$modalSure('解绑微信吗').then(() => {
unbindApi().then(() => {
this.$message.success('解绑成功')
})
})
},
toggleSideBar() {
this.$store.dispatch('app/toggleSideBar')
},

View File

@@ -2,6 +2,7 @@
<div :class="{'has-logo':showLogo}">
<logo v-if="showLogo" :collapse="isCollapse" />
<div>hello</div>
{{permission_routes}}
<el-scrollbar wrap-class="scrollbar-wrapper">
<el-menu
:default-active="activeMenu"

View File

@@ -1,5 +1,5 @@
<template>
<div id="tags-view-container" class="tags-view-container">
<div id="tags-view-container" class="tags-view-container" v-if="!isPhone">
<scroll-pane ref="scrollPane" class="tags-view-wrapper">
<router-link
v-for="tag in visitedViews"
@@ -17,10 +17,10 @@
</router-link>
</scroll-pane>
<ul v-show="visible" :style="{left:left+'px',top:top+'px'}" class="contextmenu">
<li @click="refreshSelectedTag(selectedTag)">Refresh</li>
<li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)">Close</li>
<li @click="closeOthersTags">Close Others</li>
<li @click="closeAllTags(selectedTag)">Close All</li>
<li @click="refreshSelectedTag(selectedTag)">刷新</li>
<li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)">关闭</li>
<li @click="closeOthersTags">关闭其他</li>
<li @click="closeAllTags(selectedTag)">关闭所有</li>
</ul>
</div>
</template>
@@ -33,11 +33,13 @@ export default {
components: { ScrollPane },
data() {
return {
fullWidth: document.body.clientWidth,
visible: false,
top: 0,
left: 0,
selectedTag: {},
affixTags: []
affixTags: [],
isPhone: this.$wechat.isPhone()
}
},
computed: {
@@ -51,7 +53,7 @@ export default {
watch: {
$route() {
this.addTags()
this.moveToCurrentTag()
if( !this.isPhone ) this.moveToCurrentTag()
},
visible(value) {
if (value) {
@@ -62,10 +64,14 @@ export default {
}
},
mounted() {
window.addEventListener('resize', this.handleResize)
this.initTags()
this.addTags()
},
methods: {
handleResize(event) {
this.fullWidth = document.body.clientWidth
},
isActive(route) {
return route.path === this.$route.path
},
@@ -262,7 +268,7 @@ export default {
}
</style>
<style lang="scss">
<style lang="scss" scoped>
//reset element css of el-icon-close
.tags-view-wrapper {
.tags-view-item {

57
admin/src/libs/dialog.js Normal file
View File

@@ -0,0 +1,57 @@
import {
Confirm as confirm,
Alert as alert,
Toast as toast,
Notify as notify,
Loading as loading
} from "vue-ydui/dist/lib.rem/dialog";
const dialog = {
confirm,
alert,
toast,
notify,
loading
};
const icons = { error: "操作失败", success: "操作成功" };
Object.keys(icons).reduce((dialog, key) => {
dialog[key] = (mes, obj = {}) => {
return new Promise(function(resolve) {
toast({
mes: mes || icons[key],
timeout: 1000,
icon: key,
callback: () => {
resolve();
},
...obj
});
});
};
return dialog;
}, dialog);
dialog.message = (mes = "操作失败", obj = {}) => {
return new Promise(function(resolve) {
toast({
mes,
timeout: 1000,
callback: () => {
resolve();
},
...obj
});
});
};
dialog.validateError = (...args) => {
validatorDefaultCatch(...args);
};
export function validatorDefaultCatch(err, type = "message") {
console.log(err)
return dialog[type](err.errors[0].message);
}
export default dialog;

38
admin/src/libs/loading.js Normal file
View File

@@ -0,0 +1,38 @@
const events = [];
const $scroll = function(dom, fn) {
events.push({ dom, fn });
fn._index = events.length - 1;
};
$scroll.remove = function(fn) {
fn._index && events.splice(fn._index, 1);
};
//上拉加载;
const Scroll = {
addHandler: function(element, type, handler) {
if (element.addEventListener)
element.addEventListener(type, handler, false);
else if (element.attachEvent) element.attachEvent("on" + type, handler);
else element["on" + type] = handler;
},
listenTouchDirection: function() {
this.addHandler(window, "scroll", function() {
const wh = window.innerHeight,
st = window.scrollY;
events
.filter(e => e.dom.scrollHeight && e.dom.scrollHeight > 0)
.forEach(e => {
var dh = e.dom.scrollHeight;
var s = Math.ceil((st / (dh - wh)) * 100);
if (s > 85) e.fn();
});
});
}
};
Scroll.listenTouchDirection();
export default $scroll;
export { Scroll };

View File

@@ -1,5 +1,7 @@
import { storeStaffListApi } from '@/api/storePoint'
import Cookies from 'js-cookie'
export function modalSure(title) {
console.log(title)
return new Promise((resolve, reject) => {
this.$confirm(`确定${title || '永久删除该文件'}?`, '提示', {
confirmButtonText: '确定',
@@ -17,7 +19,6 @@ export function modalSure(title) {
})
}
/**
* @description 短信是否登录
*/
@@ -30,3 +31,14 @@ export function isLogin() {
})
})
}
/**
* @description 核销员列表
*/
export function getStoreStaff() {
return new Promise((resolve, reject) => {
storeStaffListApi({page: 1, limit: 9999}).then(async res => {
localStorage.setItem('storeStaffList', res.list ? JSON.stringify(res.list) : [])
})
})
}

167
admin/src/libs/wechat.js Normal file
View File

@@ -0,0 +1,167 @@
import WechatJSSDK from "wechat-jssdk/dist/client.umd";
import { getWechatConfig, wechatAuth } from "@/api/wxApi";
import { getToken, removeToken, setToken } from '@/utils/auth'
import { parseQuery } from "@/utils";
import Cookies from 'js-cookie'
const STATE_KEY = "wx_authorize_state";
import store from "@/store";
const WX_AUTH = "wx_auth";
const BACK_URL = "login_back_url";
const LOGINTYPE = "loginType";
let instance;
let wechatObj;
const LONGITUDE = "user_longitude";
const LATITUDE = "user_latitude";
const WECHAT_SCRIPT_URL = "//res.wx.qq.com/open/js/jweixin-1.6.0.js";
/**
* 是否是微信
*/
export function isWeixin() {
return navigator.userAgent.toLowerCase().indexOf("micromessenger") !== -1;
}
/**
* 是否是移动端
*/
export function isPhone() {
return /(iPhone|iPad|iPod|iOS|Android)/i.test(navigator.userAgent);
}
export default function wechat() {
return new Promise((resolve, reject) => {
if (instance) return resolve(instance);
getWechatConfig()
.then(res => {
const _wx = WechatJSSDK(res);
wechatObj = _wx;
_wx
.initialize()
.then(() => {
instance = _wx.wx;
instance.initConfig = res;
resolve(instance);
})
.catch(reject);
})
.catch(err => {
reject(err);
});
});
}
export function loginByWxCode(code) {
return new Promise((resolve, reject) => {
let loginType = getToken();
wechatAuth(code)
.then((res) => {
store.commit('SET_TOKEN', res.token)
setToken(res.token)
Cookies.set(WX_AUTH, code);
resolve(res);
})
.catch((err)=>{
reject(err);
});
});
}
export function getWXCodeByUrl(path, step) {
if( getToken() ) return;
generatorWxUrl(path, step);
}
export function generatorWxUrl(path, step) {
wechat().then(wx => {
window.location.href = getAuthUrl(wx.initConfig, path, step);
});
}
function getAuthUrl(config, path, step) {
const finalUrl = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${config.appId}&redirect_uri=${encodeURIComponent(path)}&response_type=code&scope=snsapi_base&state=${step}#wechat_redirect`;
return finalUrl;
}
function getQueryString(name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
var reg_rewrite = new RegExp("(^|/)" + name + "/([^/]*)(/|$)", "i");
var r = window.location.search.substr(1).match(reg);
var q = window.location.pathname.substr(1).match(reg_rewrite);
if(r != null){
return unescape(r[2]);
}else if(q != null){
return unescape(q[2]);
}else{
return null;
}
}
/**
* 公众号事件
* @param name 事件名
* @param config 配置
* @returns {Promise<unknown>}
*/
export function wechatEvevt(name, config) {
return new Promise((resolve, reject) => {
let wx;
let configDefault = {
fail(res) {
if (wx) return reject({ is_ready: true, wx: wx });
getWechatConfig().then(res => {
wechatObj.signSignature({
nonceStr: res.nonceStr,
signature: res.signature,
timestamp: res.timestamp
});
wx = wechatObj.getOriginalWx();
reject({ is_ready: true, wx: wx });
});
},
success(res) {
resolve(res);
},
cancel(err) {
reject(err);
},
complete(err) {
reject(err);
}
};
Object.assign(configDefault, config);
getWechatConfig().then(res => {
const _wx = WechatJSSDK(res);
_wx.initialize().then(() => {
instance = _wx.getOriginalWx();
instance.ready(() => {
if (typeof name === "object") {
name.forEach(item => {
instance[item] && instance[item](configDefault);
});
} else instance[name] && instance[name](configDefault);
});
});
});
});
}
export function ready() {
return new Promise(resolve => {
if (typeof instance !== "undefined") {
instance.ready(() => {
resolve(instance);
});
} else {
getWechatConfig().then(res => {
const _wx = WechatJSSDK(res);
_wx.initialize().then(() => {
instance = _wx.wx;
instance.ready(() => {
resolve(instance);
});
});
});
}
});
}

View File

@@ -9,8 +9,12 @@ import './styles/element-variables.scss'
import '@/styles/index.scss' // global css
import "@/assets/iconfont/iconfont";
import "@/assets/iconfont/iconfont.css";
import VueAwesomeSwiper from 'vue-awesome-swiper'
import 'swiper/dist/css/swiper.css'
import "vue-ydui/dist/ydui.base.css";
// 懒加载
import VueLazyload from 'vue-lazyload'
@@ -27,6 +31,9 @@ import UploadFile from '@/components/Upload/uploadFile.vue'
import ueditorFrom from '@/components/ueditorFrom'
import VueUeditorWrap from 'vue-ueditor-wrap'
import iconFrom from './components/iconFrom'
import dialog from "@/libs/dialog";
import scroll from "@/libs/loading";
import schema from "async-validator";
// 切勿更改 此组件为表单生成中使用的图片上传组件
import SelfUpload from '@/components/uploadPicture/forGenrator/index.vue'
import modalAttr from '@/libs/modal-attr'
@@ -38,7 +45,8 @@ import './icons' // icon
import './permission' // permission control
import './utils/error-log' // error integralLog
import * as filters from './filters' // global filters
import { parseQuery } from "@/utils";
import * as Auth from '@/libs/wechat';
Vue.use(VueLazyload, {
preLoad: 1.3,
error: require('./assets/imgs/no.png'),
@@ -58,10 +66,37 @@ Vue.component('UploadIndex', UploadIndex)
Vue.component('SelfUpload', SelfUpload)
Vue.component('iconFrom', iconFrom)
Vue.component('ueditorFrom', ueditorFrom)
Vue.component('UploadFile', UploadFile)
Vue.component('uploadFile', UploadFile)
Vue.prototype.$modalSure = modalSure
Vue.prototype.$modalAttr = modalAttr
Vue.prototype.$modalIcon = modalIcon
Vue.prototype.$dialog = dialog
Vue.prototype.$scroll = scroll;
Vue.prototype.$wechat = Auth;
Vue.prototype.$validator = function(rule) {
return new schema(rule);
};
let cookieName = "VCONSOLE";
let query = parseQuery();
let urlSpread = query["spread"];
let vconsole = query[cookieName.toLowerCase()];
let md5Crmeb = "b14d1e9baeced9bb7525ab19ee35f2d2"; //CRMEB MD5 加密开启vconsole模式
let md5UnCrmeb = "3dca2162c4e101b7656793a1af20295c"; //UN_CREMB MD5 加密关闭vconsole模式
if (vconsole !== undefined) {
if (vconsole === md5UnCrmeb && Cookies.has(cookieName))
Cookies.remove(cookieName);
} else vconsole = Cookies.get(cookieName);
if (vconsole !== undefined && vconsole === md5Crmeb) {
Cookies.set(cookieName, md5Crmeb, 3600);
const module = () => import("vconsole");
module().then(Module => {
new Module.default();
});
}
// Vue.prototype.$modalCoupon = modalCoupon
/**
* If you don't want to use mock-server

View File

@@ -18,7 +18,7 @@ import contentRouter from './modules/content'
import operationRouter from './modules/operation'
import appSettingRouter from './modules/appSetting'
import maintainRouter from './modules/maintain'
import mobileRouter from './modules/mobile'
/**
@@ -68,6 +68,8 @@ export const constantRoutes = [
appSettingRouter,
// 维护
maintainRouter,
//移动端管理
mobileRouter,
// 数据
{
path: '/datas',
@@ -192,6 +194,11 @@ export const constantRoutes = [
}
]
},
{
path: '/auth-send',
component: () => import('@/views/mobile/auth-send'),
hidden: true
},
{
path: '/login',
component: () => import('@/views/login/index'),

View File

@@ -84,9 +84,22 @@ const appSettingRouter = {
children: [
{
path: 'routineTemplate',
component: () => import('@/views/appSetting/wxAccount/wxTemplate'),
component: () => import('@/views/appSetting/routine/myTemplate'),
name: 'RoutineTemplate',
meta: { title: '小程序订阅消息', icon: '' }
meta: { title: '我的模板', icon: '' }
},
{
path: 'publicRoutineTemplate',
component: () => import('@/views/appSetting/routine/publicTemplate/index.vue'),
name: 'PublicRoutineTemplate',
meta: { title: '公共模板', icon: '' }
},
{
path: 'creatPublicTemplate/:tid/:id/:myId?',
component: () => import('@/views/appSetting/routine/publicTemplate/creatPublicTemplate.vue'),
name: 'CreatPublicTemplate',
meta: { title: '添加公共模板', icon: '', activeMenu: `/appSetting/publicRoutine/publicRoutineTemplate` },
hidden: true
}
]
}

View File

@@ -0,0 +1,53 @@
import Layout from '@/layout'
const mobileRouter = {
path: '/javaMobile',
component: Layout,
redirect: '/javaMobile/index',
name: 'Mobile',
alwaysShow: true,
meta: {
title: '移动端',
icon: 'clipboard'
},
children: [
{
path: 'orderCancellation',
component: () => import('@/views/mobile/orderCancellation/index.vue'),
name: 'OrderCancellation',
meta: { title: '订单核销', icon: '' }
},
{
path: 'orderStatistics',
component: () => import('@/views/mobile/orderStatistics/index.vue'),
name: 'OrderStatistics',
meta: { title: '订单统计' }
},
{
path: 'orderList/:types?',
component: () => import('@/views/mobile/orderStatistics/orderList.vue'),
name: 'OrderList',
meta: { title: '订单列表' }
},
{
path: 'orderDelivery/:oid/:id?',
component: () => import('@/views/mobile/orderStatistics/orderDelivery.vue'),
name: 'OrderDelivery',
meta: { title: '订单发货' }
},
{
path: 'orderDetail/:id?/:goname?',
component: () => import('@/views/mobile/orderStatistics/orderDetail.vue'),
name: 'OrderDetail',
meta: { title: '订单详情' }
},
{
path: 'orderStatisticsDetail/:type/:time?',
component: () => import('@/views/mobile/orderStatistics/Statistics.vue'),
name: 'OrderStatistics',
meta: { title: '订单数据统计' }
}
]
}
export default mobileRouter

View File

@@ -156,6 +156,30 @@ const operationRouter = {
}
]
},
{
path: 'storeService',
component: () => import('@/views/systemSetting/storeService'),
name: 'StoreService',
meta: {
title: '客服管理',
icon: 'clipboard',
roles: ['admin']
},
children: [
{
path: 'list',
component: () => import('@/views/systemSetting/storeService/chatRoom'),
name: 'StoreServiceList',
meta: { title: '客服列表', noCache: true }
},
{
path: 'chatRoom',
component: () => import('@/views/systemSetting/storeService/list'),
name: 'ChatRoom',
meta: { title: '聊天室', noCache: true }
}
]
},
]
}

View File

@@ -16,6 +16,36 @@ const orderRouter = {
component: () => import('@/views/order/index'),
name: 'OrderIndex',
meta: { title: '订单管理' }
},
{
path: 'statistics',
component: () => import('@/views/mobile/orderStatistics/index.vue'),
name: 'OrderStatistics',
meta: { title: '订单统计' }
},
{
path: 'orderList/:types?',
component: () => import('@/views/mobile/orderStatistics/orderList.vue'),
name: 'OrderList',
meta: { title: '订单列表' }
},
{
path: 'orderDelivery/:oid/:id?',
component: () => import('@/views/mobile/orderStatistics/orderDelivery.vue'),
name: 'OrderDelivery',
meta: { title: '订单发货' }
},
{
path: 'orderDetail/:id?/:goname?',
component: () => import('@/views/mobile/orderStatistics/orderDetail.vue'),
name: 'OrderDetail',
meta: { title: '订单详情' }
},
{
path: 'orderStatistics/:type/:time?',
component: () => import('@/views/mobile/orderStatistics/Statistics.vue'),
name: 'OrderStatistics',
meta: { title: '订单数据统计' }
}
]
}

View File

@@ -1,6 +1,7 @@
import { asyncRoutes, constantRoutes } from '@/router'
import * as categoryApi from '@/api/categoryApi.js'
import * as roleApi from '@/api/roleApi.js'
import * as Auth from '@/libs/wechat';
/**
* Use meta.role to determine if the current user has permission
@@ -61,12 +62,13 @@ const actions = {
generateRoutes({ commit }, roleid) {
return new Promise(async resolve => {
let accessedRoutes = []
let menus= []
const { rules } = await roleApi.getRoleById(roleid)
// const menus = await categoryApi.categroyByIds({ ids: rules })
const menus = await roleApi.menuListApi()
const menusAll = await roleApi.menuListApi()
!Auth.isPhone() ? menus = menusAll.filter(item => item.url !== '/javaMobile') : menus = menusAll.filter(item => item.url === '/javaMobile')
const _routerResult = comRouter(menus, asyncRoutes)
accessedRoutes = filterAsyncRoutes(_routerResult, rules)
console.log(accessedRoutes)
// todo 这里控制是否过滤路由,经测试有些菜单不能予以设置,比如系统设置等等
commit('SET_ROUTES', menus)
// resolve(menus)

View File

@@ -3,6 +3,7 @@ import { getToken, setToken, removeToken } from '@/utils/auth'
import router, { resetRouter } from '@/router'
import { isLoginApi } from '@/api/sms'
import Cookies from 'js-cookie'
import { oAuth, getQueryString } from "@/libs/wechat";
const state = {
token: getToken(),
@@ -38,7 +39,7 @@ const mutations = {
const actions = {
// user login
login({ commit }, userInfo) {
const { account, pwd, key, code } = userInfo
const { account, pwd, key, code, wxCode } = userInfo
return new Promise((resolve, reject) => {
login( userInfo ).then(data => {
commit('SET_TOKEN', data.token)
@@ -100,7 +101,10 @@ const actions = {
commit('SET_ROLES', [])
removeToken()
resetRouter()
localStorage.clear();
Cookies.remove('storeStaffList')
Cookies.remove('JavaInfo')
sessionStorage.removeItem('token')
// reset visited views and cached views
// to fixed https://github.com/PanJiaChen/vue-element-admin/issues/2485
dispatch('tagsView/delAllViews', null, { root: true })
@@ -121,6 +125,15 @@ const actions = {
resolve()
})
},
// 设置token
setToken({commit},state) {
return new Promise(resolve => {
commit('SET_TOKEN', state.token)
Cookies.set('JavaInfo', JSON.stringify(state))
setToken(data.token)
resolve()
})
},
// dynamically modify permissions
changeRoles({ commit, dispatch }, role) {

126
admin/src/styles/reset.css Normal file
View File

@@ -0,0 +1,126 @@
body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, dl, dt, dd, ul, ol, li, pre, form, fieldset, legend, button, input, textarea, th, td,select { margin:0; padding:0; }
body, button, input, select, textarea {font-size:.3rem;}
h1, h2, h3, h4, h5, h6{ font-size:100%; }
address, cite, dfn, em, var { font-style:normal; }
code, kbd, pre, samp { font-family:couriernew, courier, monospace; }
small{ font-size:12px; }
ul, ol { list-style:none; }
sup { vertical-align:text-top; }
sub{ vertical-align:text-bottom; }
legend { color:#000; }
fieldset, img { border:0; }
button, input, select, textarea { font-size:100%; }
table { border-collapse:collapse; border-spacing:0;width:100%;}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, menu, nav, section { display: block; }
input,input[type="search"],button,select,option,textarea,a{ outline:none; border:0; -webkit-appearance:none;border-radius: 0; background:none;-webkit-box-sizing:border-box;box-sizing:border-box;}
/* custom */
a { text-decoration: none; -webkit-backface-visibility: hidden; color:#333; }
body,input,textarea{ -webkit-text-size-adjust: none; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: 'PingFang SC', 'STHeitiSC-Light', 'Helvetica-Light', arial, sans-serif, 'Droid Sans Fallback'; color:#333;}
div,section,header,footer{-webkit-box-sizing:border-box; box-sizing:border-box;}
input{line-height: normal; box-sizing:border-box;}
.fl{ float:left; }
.fr{ float:right; }
.clear{ clear:both; height: 0; line-height: 0; font-size: 0; }
.clearfix:after{ content:"."; display:block; height:0; visibility:hidden; clear:both; overflow: hidden; }
::-webkit-scrollbar {
width:0px;
}
::-webkit-scrollbar-track {
background-color:unset;
}
::-webkit-scrollbar-thumb {
background-color:unset;
}
::-webkit-scrollbar-thumb:hover {
background-color:unset;
}
::-webkit-scrollbar-thumb:active {
background-color:unset;
}
.flex {
display: -webkit-box;
display: -moz-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
.con-cell{ display: table-cell; height: 100%; vertical-align: middle; }
.old-price{text-decoration: line-through;}
.icon {
width: 1em; height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
@font-face {
font-family: 'GuildfordProBook 5';
/*src:url('GuildfordProBook 5.otf')*/
}
[v-cloak] {
display: none;
}
.iconfont{
font-size: .36rem;
}
/* 一像素边框 */
@media (-webkit-min-device-pixel-ratio: 1.5), (min-device-pixel-ratio: 1.5) {
.border-1px::after {
-webkit-transform: scaleY(0.7);
-moz-transform: scaleY(0.7);
-o-transform: scaleY(0.7);
-ms-transform: scaleY(0.7);
transform: scaleY(0.7);
}
.border-1px::before {
-webkit-transform: scaleY(0.7);
-moz-transform: scaleY(0.7);
-o-transform: scaleY(0.7);
-ms-transform: scaleY(0.7);
transform: scaleY(0.7);
}
}
@media (-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2) {
.border-1px::after {
-webkit-transform: scaleY(0.5);
-moz-transform: scaleY(0.5);
-o-transform: scaleY(0.5);
-ms-transform: scaleY(0.5);
transform: scaleY(0.5);
}
.border-1px::before {
-webkit-transform: scaleY(0.5);
-moz-transform: scaleY(0.5);
-o-transform: scaleY(0.5);
-ms-transform: scaleY(0.5);
transform: scaleY(0.5);
}
}
@media (-webkit-min-device-pixel-ratio: 3), (min-device-pixel-ratio: 3) {
.border-1px::after {
-webkit-transform: scaleY(0.33);
-moz-transform: scaleY(0.33);
-o-transform: scaleY(0.33);
-ms-transform: scaleY(0.33);
transform: scaleY(0.33);
}
.border-1px::before {
-webkit-transform: scaleY(0.33);
-moz-transform: scaleY(0.33);
-o-transform: scaleY(0.33);
-ms-transform: scaleY(0.33);
transform: scaleY(0.33);
}
}
.line1{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width: 100%;}
.line2{word-break:break-all;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;}
.mask{position:fixed;top:0;left:0;right:0;bottom:0;z-index:555;background-color:rgba(0,0,0,0.5);}

View File

@@ -16,6 +16,22 @@
flex-wrap: wrap;
/* 辅助类 */
}
.acea-row.row-middle {
-webkit-box-align: center;
-moz-box-align: center;
-o-box-align: center;
-ms-flex-align: center;
-webkit-align-items: center;
align-items: center;
}
.acea-row.row-right {
-webkit-box-pack: end;
-moz-box-pack: end;
-o-box-pack: end;
-ms-flex-pack: end;
-webkit-justify-content: flex-end;
justify-content: flex-end;
}
.acea-row.row-bottom {
-webkit-box-align: end;
-moz-box-align: end;
@@ -24,6 +40,10 @@
-webkit-align-items: flex-end;
align-items: flex-end;
}
.acea-row.row-around {
justify-content: space-around;
-webkit-justify-content: space-around;
}
.acea-row.row-between {
-webkit-box-pack: justify;
-moz-box-pack: justify;
@@ -47,14 +67,6 @@
-webkit-justify-content: center;
justify-content: center;
}
.acea-row.row-middle {
-webkit-box-align: center;
-moz-box-align: center;
-o-box-align: center;
-ms-flex-align: center;
-webkit-align-items: center;
align-items: center;
}
/* 上下两边居中对齐 */
.acea-row.row-between-wrapper {
-webkit-box-align: center;
@@ -193,6 +205,9 @@ table .el-image{
.mb20{
margin-bottom: 20px;
}
.mb35{
margin-bottom: 35px;
}
.mt20{
margin-top: 20px;
}
@@ -342,3 +357,33 @@ table .el-image{
.edui-dialog{
//z-index: 4009 !important;
}
.maskModel {
position:fixed;top:0;left:0;right:0;bottom:0;z-index:55;background-color:rgba(0,0,0,0.5);
}
.line2 {
word-break: break-all;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.statistical-page .mpvue-calendar{min-width:100%;}
.statistical-page .mpvue-calendar table{margin:0;}
.statistical-page .mpvue-calendar td{border-right:1px solid #fff;padding:0;width:14%!important;}
.statistical-page .calendar-tools{box-shadow:unset;-webkit-box-shadow:unset;-o-box-shadow:unset;-moz-box-shadow:unset;}
.statistical-page .mc-head-box div{font-size: 14px;}
.statistical-page .mpvue-calendar td:not(.disabled) span.mc-date-red{color:unset;}
.statistical-page .mpvue-calendar .mc-range-mode .mc-range-end span.calendar-date, .statistical-page .mpvue-calendar .mc-range-mode .mc-range-begin span.calendar-date{
border-radius:0;background-color:#2291f8!important;
}
.statistical-page .mpvue-calendar td.selected span.mc-date-red{color:#fff;}
.statistical-page .mc-range-mode .selected .mc-range-bg{background-color:#a0dcf9;}
.statistical-page .mpvue-calendar .mc-range-mode .mc-range-row-last .calendar-date,.statistical-page .mpvue-calendar .mc-range-mode .mc-range-row-first .calendar-date{
background-color:#a0dcf9;
}
.statistical-page .mpvue-calendar .mc-range-mode .selected.mc-range-second-to-last span{background-color:#a0dcf9;}
.statistical-page .mpvue-calendar .mc-range-mode .mc-range-month-first.selected .calendar-date, .statistical-page .mpvue-calendar .mc-range-mode .mc-range-month-last.selected .calendar-date{
background-color:#a0dcf9;
}
.statistical-page .mc-today-element .calendar-date{border-radius:0;background-color:unset;}

View File

@@ -71,6 +71,7 @@ export const fromList = {
title: '选择时间',
custom: true,
fromTxt: [
{ text: '全部', val: '' },
{ text: '今天', val: 'today' },
{ text: '昨天', val: 'yesterday' },
{ text: '最近7天', val: 'lately7' },

View File

@@ -1,3 +1,4 @@
import Cookies from 'js-cookie'
/**
* Created by PanJiaChen on 16/11/18.
*/
@@ -31,7 +32,7 @@ function padLeftZero (str) {
}
/**
* Parse the time to string
* 更改时间格式成2010-01-10格式
* @param {(Object|string|number)} time
* @param {string} cFormat
* @returns {string | null}
@@ -47,15 +48,11 @@ export function parseTime(time, cFormat) {
} else {
if ((typeof time === 'string')) {
if ((/^[0-9]+$/.test(time))) {
// support "1548221490638"
time = parseInt(time)
} else {
// support safari
// https://stackoverflow.com/questions/4310953/invalid-date-in-safari
time = time.replace(new RegExp(/-/gm), '/')
}
}
if ((typeof time === 'number') && (time.toString().length === 10)) {
time = time * 1000
}
@@ -381,3 +378,45 @@ export function removeClass(ele, cls) {
ele.className = ele.className.replace(reg, ' ')
}
}
/**
* 判断地址
*/
export function parseQuery() {
const res = {};
const query = (location.href.split("?")[1] || "")
.trim()
.replace(/^(\?|#|&)/, "");
if (!query) {
return res;
}
query.split("&").forEach(param => {
const parts = param.replace(/\+/g, " ").split("=");
const key = decodeURIComponent(parts.shift());
const val = parts.length > 0 ? decodeURIComponent(parts.join("=")) : null;
if (res[key] === undefined) {
res[key] = val;
} else if (Array.isArray(res[key])) {
res[key].push(val);
} else {
res[key] = [res[key], val];
}
});
return res;
}
/**
* 是否是核销员
*/
export function isWriteOff() {
if(localStorage.getItem('storeStaffList')){
let JavaInfo = JSON.parse(Cookies.get('JavaInfo'))
let staff = JSON.parse(localStorage.getItem('storeStaffList'))
return staff.some(item => item.avatar === JavaInfo.account)
}
}

View File

@@ -3,7 +3,7 @@ import { MessageBox, Message } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'
import SettingMer from '@/utils/settingMer'
import { isPhone } from "@/libs/wechat";
// create an axios instance
const service = axios.create({
baseURL: SettingMer.apiBaseURL, // url = base url + request url
@@ -15,12 +15,12 @@ const service = axios.create({
service.interceptors.request.use(
config => {
// do something before request is sent
if (store.getters.token) {
const token = !store.getters.token?sessionStorage.getItem('token'):store.getters.token;
if (token) {
// let each request carry token
// ['X-Token'] is a custom headers key
// please modify it according to the actual situationf
config.headers['Authori-zation'] = getToken()
config.headers['Authori-zation'] = token
}
if(/get/i.test(config.method)){
config.params = config.params || {}
@@ -62,6 +62,9 @@ service.interceptors.response.use(
})
}
if (res.code !== 200) {
if (isPhone()) { //移动端
return Promise.reject(res || 'Error')
}
Message({
message: res.message || 'Error',
type: 'error',

View File

@@ -1,6 +1,13 @@
/**
* Created by PanJiaChen on 16/11/18.
*/
const baseAttr = {
min: "%s最小长度为:min",
max: "%s最大长度为:max",
length: "%s长度必须为:length",
range: "%s长度为:range",
pattern: "$s格式错误"
};
/**
* @param {string} path
@@ -86,3 +93,52 @@ export function isArray(arg) {
}
return Array.isArray(arg)
}
const bindMessage = (fn, message) => {
fn.message = field => message.replace("%s", field || "");
};
export function required(message, opt = {}) {
return {
required: true,
message,
type: "string",
...opt
};
}
bindMessage(required, "请输入%s");
/**
* 正确的金额
*
* @param message
* @returns {*}
*/
export function num(message) {
return attrs.pattern(
/(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/,
message
);
}
bindMessage(num, "%s格式不正确");
const attrs = Object.keys(baseAttr).reduce((attrs, key) => {
attrs[key] = (attr, message = "", opt = {}) => {
const _attr =
key === "range" ? { min: attr[0], max: attr[1] } : { [key]: attr };
return {
message: message.replace(
`:${key}`,
key === "range" ? `${attr[0]}-${attr[1]}` : attr
),
type: "string",
..._attr,
...opt
};
};
bindMessage(attrs[key], baseAttr[key]);
return attrs;
}, {});
export default attrs;

View File

@@ -0,0 +1,272 @@
<template>
<div class="divBox">
<el-card class="box-card">
<div slot="header" class="clearfix">
<div class="container">
<el-form size="small" :inline="true" label-width="55px" label-position="left">
<el-form-item label="状态:">
<el-select v-model="tableFrom.status" placeholder="请选择状态" clearable class="selWidth">
<el-option :label="item.label" :value="item.value" v-for="(item, index) in switchData" :key="index"></el-option>
</el-select>
</el-form-item>
<el-form-item label="名称:">
<el-input v-model="tableFrom.title" placeholder="请输入模板名称" class="selWidth" size="small"></el-input>
</el-form-item>
<el-form-item label="ID">
<el-input v-model="tableFrom.tempId" placeholder="请输入模板ID" class="selWidth" size="small"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="seachList" size="small">查询</el-button>
</el-form-item>
</el-form>
<router-link :to=" { path:'/appSetting/publicRoutine/publicRoutineTemplate' } ">
<el-button type="primary" size="small" class="mr10">添加</el-button>
</router-link>
<el-button type="primary" size="small" class="mr10" @click="checkTemp">一键同步我的模板</el-button>
</div>
</div>
<el-table
v-loading="listLoading"
:data="tableData.data"
style="width: 100%"
size="mini"
class="table"
highlight-current-row
>
<el-table-column
label="ID"
width="80"
prop="id"
/>
<el-table-column
prop="tempId"
label="模板ID"
min-width="320"
/>
<el-table-column
prop="title"
label="模板名"
min-width="150"
/>
<el-table-column
label="模板关键字"
min-width="250">
<template slot-scope="scope" v-if="scope.row.extra">
<span v-for="item in JSON.parse(scope.row.extra)" :key="item.kid" class="mr5">{{item.name}}</span>
</template>
<template slot-scope="scope" v-else>
<span class="mr5">-</span>
</template>
</el-table-column>
<el-table-column
label="状态"
min-width="100"
>
<template slot-scope="scope">
<el-switch
v-model="scope.row.status"
class="demo"
active-text="开启"
inactive-text="关闭"
:active-value="true"
:inactive-value="false"
@click.native="onchangeIsShow(scope.row)"
/>
</template>
</el-table-column>
<el-table-column
label="应用场景"
min-width="150"
>
<template slot-scope="scope">
<el-select v-model="scope.row.type" placeholder="请选择" clearable @change="onchangeType(scope.row)">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</template>
</el-table-column>
<el-table-column
prop="createTime"
label="添加时间"
min-width="120"
/>
<el-table-column label="操作" min-width="150" fixed="right" align="center">
<template slot-scope="scope">
<router-link :to=" { path:'/appSetting/publicRoutine/creatPublicTemplate/' + scope.row.tid + '/0/' + scope.row.id } ">
<el-button size="small" type="text" class="mr10">编辑</el-button>
</router-link>
<!--<el-button type="text" size="small" @click="handleDelete(scope.row, scope.$index)">删除</el-button>-->
</template>
</el-table-column>
</el-table>
<div class="block">
<el-pagination
:page-sizes="[20, 40, 60, 80]"
:page-size="tableFrom.limit"
:current-page="tableFrom.page"
layout="total, sizes, prev, pager, next, jumper"
:total="tableData.total"
@size-change="handleSizeChange"
@current-change="pageChange"
/>
</div>
</el-card>
<!--编辑-->
<el-dialog
title="编辑订单"
:visible.sync="dialogVisible"
width="500px"
:before-close="handleClose">
<zb-parser
v-if="dialogVisible"
:form-id="105"
:is-create="isCreate"
:edit-data="editData"
@submit="handlerSubmit"
/>
</el-dialog>
</div>
</template>
<script>
import * as constants from '@/utils/constants.js'
import { tempAsyncApi, myTempTypeApi, myTempListApi, wechatTemplateStatusApi, wechatTemplateSaveApi, wechatTemplateUpdateApi, wechatTemplateDeleteApi, myTempStatusApi} from '@/api/wxApi'
import zbParser from '@/components/FormGenerator/components/parser/ZBParser'
export default {
name: "MyTemplates",
components: { zbParser },
data() {
return {
value: '',
options: [{
value: 'paySubscribe',
label: '支付成功'
}, {
value: 'orderSubscribe',
label: '订单相关'
}, {
value: 'extrctSubscribe',
label: '提现消息'
}, {
value: 'orderRefundSubscribe',
label: '订单退款'
}, {
value: 'rechargeSubscribe',
label: '充值成功'
}],
labelPosition:'right',
isCreate: 0,
editData: {},
dialogVisible: false,
switchData: constants.switchStatus,
tableFrom: {
page: 1,
limit: 20,
status: null,
title: null,
tempId: null
},
tableData: {
data: [],
total: 0
},
listLoading: true,
tempId: null
}
},
mounted() {
this.getList()
},
methods: {
checkTemp() {
this.$modalSure('同步我的模板到小程序').then(() => {
tempAsyncApi().then(() => {
this.$message.success('同步成功')
})
})
},
seachList() {
this.tableFrom.page = 1
this.getList()
},
// 订单删除
handleDelete(row, idx) {
this.$modalSure().then(() => {
wechatTemplateDeleteApi( row.id ).then(() => {
this.$message.success('删除成功')
this.tableData.data.splice(idx, 1)
})
})
},
handleClose() {
this.dialogVisible = false
this.editData = {}
},
handlerSubmit(formValue) {
this.isCreate === 0 ? wechatTemplateSaveApi(formValue).then(data => {
this.$message.success('新增成功')
this.dialogVisible = false
this.editData = {}
this.getList()
}) : wechatTemplateUpdateApi(this.tempId, formValue).then(data => {
this.$message.success('编辑成功')
this.dialogVisible = false
this.getList()
})
},
add() {
this.dialogVisible = true
},
edit(row) {
this.tempId = row.id
this.dialogVisible = true
this.isCreate = 1
this.editData = JSON.parse(JSON.stringify(row))
},
// 列表
getList() {
this.listLoading = true
myTempListApi(this.tableFrom).then(res => {
this.tableData.data = res.list || []
this.tableData.total = res.total
this.listLoading = false
}).catch(() => {
this.listLoading = false
})
},
pageChange(page) {
this.tableFrom.page = page
this.getList()
},
handleSizeChange(val) {
this.tableFrom.limit = val
this.getList()
},
// 修改状态
onchangeIsShow(row) {
myTempStatusApi({status: row.status , id: row.id}).then(() => {
this.$message.success('修改成功')
this.getList()
})
},
// 修改场景
onchangeType(row) {
myTempTypeApi({type: row.type , id: row.id}).then(() => {
this.$message.success('修改成功')
this.getList()
})
}
}
}
</script>
<style scoped lang="scss">
.selWidth {
width: 350px;
}
</style>

View File

@@ -0,0 +1,272 @@
<template>
<div class="divBox">
<el-card class="box-card" v-loading="loadingAll">
<el-alert
:closable="false"
title="你可用该标题的模板搭配不同的关键词使用,配置提交后关键词种类和顺序将不能修改"
type="warning">
</el-alert>
<el-divider></el-divider>
<el-row>
<el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="8">
<div class="tmplmsg-box">
<div class="tmplmsg-preview">
<div class="tmplmsg-preview-title mb35" v-text="form.title"></div>
<div class="acea-row row-middle tmplmsg-preview-cont mb10" v-for="(item, index) in KeywordCheck" :key="item.kid">
<label v-text="item.name"></label>
<span v-text="item.example"></span>
</div>
</div>
</div>
</el-col>
<el-col :xs="24" :sm="24" :md="16" :lg="16" :xl="16">
<div class="tmplmsg-form">
<el-form ref="form" :model="form" :rules="rules" label-width="100px" size="mini">
<el-form-item label="配置关键词" prop="checkList">
<div class="tmplmsg-form-cont">
<el-checkbox-group v-model="form.checkList" :max="5" @change="handleChecked">
<el-checkbox :label="item.kid" v-for="item in KeywordList" :key="item.kid">{{item.name}}</el-checkbox>
</el-checkbox-group>
</div>
</el-form-item>
<el-form-item :label=" '已选择(' + KeywordCheck.length + '/5)'">
<span v-if="KeywordCheck.length ===0 ">请先从上方选择关键词</span>
<div v-else class="tmplmsg-form-check">
<div class="tmplmsg-form-check-list mb10 acea-row row-between" v-for="(item, index) in KeywordCheck" :key="item.kid"
draggable="true"
@dragstart="handleDragStart($event, item)"
@dragover.prevent="handleDragOver($event, item)"
@dragover="handleDragEnter($event, item)"
@dragend="handleDragEnd($event, item)">
<span v-text="item.name"></span>
<i class="el-icon-close" @click="closeCheck(index)"></i>
</div>
</div>
</el-form-item>
<el-form-item label="场景说明" prop="sceneDesc">
<el-input
type="textarea"
:rows="2"
placeholder="请输入场景说明"
v-model="form.sceneDesc">
</el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" :loading="loading" @click="onSubmit('form')">提交</el-button>
</el-form-item>
</el-form>
</div>
</el-col>
</el-row>
</el-card>
</div>
</template>
<script>
import { getWeChatKeywordsByTidApi, myTempSaveApi, publicTempInfoApi, myTempInfoApi, myTempUpdateApi } from '@/api/wxApi'
export default {
name: "creatPublicTemplate",
data() {
return {
KeywordList: [],
form: {
checkList: [],
kid: '',
sceneDesc: '',
tid: '',
title: '',
extra: ''
},
KeywordCheck: [],
loading: false,
loadingAll: false,
rules: {
sceneDesc: [
{ required: true, message: '请填写场景说明', trigger: 'blur' }
],
checkList: [
{ type: 'array', required: true, message: '请至少选择一个关键词', trigger: 'change' }
]
},
tempRoute: {}
}
},
created() {
this.tempRoute = Object.assign({}, this.$route)
},
mounted() {
this.getKeywordList()
if( this.$route.params.id !== '0' )this.getTitle()
if( this.$route.params.myId!== '0'){
this.setTagsViewTitle()
this.wxInfo()
}
},
methods: {
// 设置tab标题
setTagsViewTitle() {
const title = '编辑模板'
const route = Object.assign({}, this.tempRoute, { title: `${title}-${this.$route.params.myId}` })
this.$store.dispatch('tagsView/updateVisitedView', route)
},
handleChecked(val) {
this.KeywordCheck = this.KeywordList.filter(item=> val.some(ele=>ele == item.kid))
},
onSubmit(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
let data = {
kid: this.form.checkList.join(','),
sceneDesc: this.form.sceneDesc,
tid: this.$route.params.tid,
title: this.form.title,
extra: JSON.stringify(this.KeywordCheck)
}
this.loading = true
this.$route.params.myId === '0' ? myTempSaveApi(data).then(res => {
this.$message.success('提交成功')
this.$router.push('/appSetting/publicRoutine/publicRoutineTemplate')
this.loading = false
}).catch(()=>{
this.loading = false
}) : myTempUpdateApi({id: this.$route.params.myId}, data).then(res => {
this.$message.success('提交成功')
this.$router.push('/appSetting/publicRoutine/routineTemplate')
this.loading = false
}).catch(()=>{
this.loading = false
})
} else {
return false;
}
});
},
closeCheck(i) {
this.form.checkList.splice(i, 1)
},
// 详情
wxInfo() {
myTempInfoApi({ id: this.$route.params.myId}).then(res => {
this.form = {
checkList: res.kid.split(',').map(Number),
sceneDesc: res.sceneDesc,
tid: res.tid,
title: res.title,
extra: res.extra
}
this.KeywordCheck = JSON.parse(res.extra)
})
},
// 标题
getTitle() {
publicTempInfoApi({ id: this.$route.params.id}).then(res => {
this.form.title = res.title
})
},
// 关键字列表
getKeywordList() {
this.loadingAll = true
getWeChatKeywordsByTidApi({ tid: this.$route.params.tid}).then(res => {
this.KeywordList = res
for (let i=0;i<res; i++) {
this.$set(this.form.checkList, i,res[i])
}
this.loadingAll = false
}).catch(() => {
this.loadingAll = false
})
},
// 移动
handleDragStart (e, item) {
this.dragging = item;
},
handleDragEnd (e, item) {
this.dragging = null
},
handleDragOver (e) {
e.dataTransfer.dropEffect = 'move'
},
handleDragEnter (e, item) {
e.dataTransfer.effectAllowed = 'move'
if (item === this.dragging) {
return
}
const newItems = [...this.KeywordCheck]
const src = newItems.indexOf(this.dragging)
const dst = newItems.indexOf(item)
newItems.splice(dst, 0, ...newItems.splice(src, 1))
this.KeywordCheck = newItems;
}
}
}
</script>
<style scoped lang="scss">
.tmplmsg{
&-box{
border: 1px solid #E7E7EB;
border-radius: 5px;
width: 90%;
min-width: 325px;
margin-right: 30px;
}
&-preview{
min-height: 230px;
padding: 15px;
&-title{
font-size: 14px;
}
&-cont{
font-size: 13px;
label{
width: 100px;
}
}
}
&-form{
position: relative;
width: 60%;
height: auto;
background: #f6f8f9;
background-clip: padding-box;
padding: 20px 20px;
&-cont{
width: 100%;
height: auto;
background: #fff;
padding: 15px;
max-height: 250px;
overflow-y: auto;
/deep/.el-checkbox{
display: block !important;
}
}
&-check{
&-list{
width: 100%;
background: #fff;
line-height: 37px;
height: 37px;
align-items: center;
padding: 0 15px;
box-sizing: border-box;
cursor: pointer;
}
/deep/.el-alert--success{
line-height: normal !important;
}
}
}
&-form::after {
content:"";
position: absolute;
right: 100%;
top: 26px;
width: 0;
height: 0;
border-top: 13px solid transparent;
border-right: 26px solid #f6f8f9;
border-bottom: 13px solid transparent;
}
}
</style>

View File

@@ -0,0 +1,157 @@
<template>
<div class="divBox">
<el-card class="box-card">
<div slot="header" class="clearfix">
<div class="container">
<el-form size="small" :inline="true" label-width="100px">
<el-form-item label="模板标题:">
<el-input v-model="tableFrom.title" placeholder="请输入模板标题" class="selWidth" size="small"></el-input>
</el-form-item>
<el-form-item label="所属类目:">
<el-select v-model="tableFrom.categoryId" placeholder="请选择状态" clearable class="selWidth">
<el-option :label="item.name" :value="item.id" v-for="item in categoryList" :key="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item label="模板类型:">
<el-select v-model="tableFrom.type" placeholder="请选择类型" clearable class="selWidth">
<el-option label="一次性订阅" value="2"></el-option>
<el-option label="长期订阅" value="3"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="seachList" size="small">查询</el-button>
</el-form-item>
</el-form>
</div>
</div>
<el-table
v-loading="listLoading"
:data="tableData.data"
style="width: 100%"
size="mini"
class="table"
highlight-current-row
>
<el-table-column
label="ID"
width="80"
prop="id"
/>
<el-table-column
prop="tid"
label="模板ID"
min-width="100"
/>
<el-table-column
prop="title"
label="模版标题"
min-width="150"
/>
<el-table-column
label="所属类目"
min-width="100"
>
<template slot-scope="scope">
<span>{{ scope.row.categoryId | wxCategoryFilter }}</span>
</template>
</el-table-column>
<el-table-column
label="模版类型"
min-width="100"
>
<template slot-scope="scope">
<span>{{ scope.row.type | wxTypeFilter }}</span>
</template>
</el-table-column>
<el-table-column
prop="createTime"
label="创建时间"
min-width="150"
/>
<el-table-column label="操作" min-width="80" fixed="right" align="center">
<template slot-scope="scope">
<router-link :to=" { path:'/appSetting/publicRoutine/creatPublicTemplate/' + scope.row.tid + '/' + scope.row.id + '/0' } ">
<el-button size="small" type="text" class="mr10">选用</el-button>
</router-link>
</template>
</el-table-column>
</el-table>
<div class="block">
<el-pagination
:page-sizes="[20, 40, 60, 80]"
:page-size="tableFrom.limit"
:current-page="tableFrom.page"
layout="total, sizes, prev, pager, next, jumper"
:total="tableData.total"
@size-change="handleSizeChange"
@current-change="pageChange"
/>
</div>
</el-card>
</div>
</template>
<script>
import { publicTempListApi, categoryApi } from '@/api/wxApi'
import Cookies from 'js-cookie'
export default {
name: "index",
data() {
return {
tableData: {
data: [],
total: 0
},
listLoading: true,
tableFrom: {
page: 1,
limit: 20,
title: '',
type: '',
categoryId: ''
},
categoryList: []
}
},
mounted() {
this.getList()
this.getCategoryList()
},
methods: {
seachList() {
this.tableFrom.page = 1
this.getList()
},
// 列表
getList() {
this.listLoading = true
publicTempListApi(this.tableFrom).then(res => {
this.tableData.data = res.list || []
this.tableData.total = res.total
this.listLoading = false
}).catch(() => {
this.listLoading = false
})
},
pageChange(page) {
this.tableFrom.page = page
this.getList()
},
handleSizeChange(val) {
this.tableFrom.limit = val
this.getList()
},
// 所属类目
getCategoryList() {
categoryApi().then(res => {
this.categoryList = res
Cookies.set('WxCategory', res)
})
},
}
}
</script>
<style scoped>
</style>

View File

@@ -1,3 +1,5 @@
<template>
</template>
<script>
export default {
name: 'AuthRedirect',

View File

@@ -70,6 +70,8 @@
<div class="imgs" @click="getCaptcha()"><img :src="captchatImg"></div>
</div>
</el-form-item>
<div class="acea-row">
<el-button
:loading="loading"
type="primary"
@@ -77,6 +79,11 @@
@click.native.prevent="handleLogin"
>登录
</el-button>
<!--<div class="acea-row footer" @click="onWechat">-->
<!--<div class="wechat mr10"><img src="../../assets/imgs/weixin.png"></div>-->
<!--<span>微信</span>-->
<!--</div>-->
</div>
</el-form>
</div>
</div>
@@ -86,6 +93,11 @@
<script>
import { validUsername } from '@/utils/validate'
import { getLoginPicApi, captchaApi, codeCheckApi } from '@/api/user'
import { getStoreStaff } from '@/libs/public'
import { getWXCodeByUrl, loginByWxCode } from "@/libs/wechat";
import { getWechatConfig } from "@/api/wxApi";
import { getToken, removeToken, setToken } from '@/utils/auth'
import Cookies from 'js-cookie'
export default {
name: 'Login',
data() {
@@ -123,7 +135,8 @@ export default {
account: 'demo', // admin
pwd: 'crmeb.com',
key: '',
code: ''
code: '',
wxCode: ''
},
loginRules: {
account: [{ required: true, trigger: 'blur' }], // validator: validateUsername
@@ -183,6 +196,7 @@ export default {
this.$refs.pwd.focus()
}
this.getCaptcha()
this.agentWeiXinLogin()
},
destroyed() {
// window.removeEventListener('storage', this.afterQRScan)
@@ -191,6 +205,35 @@ export default {
window.removeEventListener('resize', this.handleResize)
},
methods: {
agentWeiXinLogin(){ // 判断是否需要微信公众号登陆
const _isWechat = this.$wechat.isWeixin();
if (_isWechat) {
let code = this.$route.query.code
let state = this.$route.query.state
let wxAuthPath = location.origin + '/login';
// 如果没有code 去获取
if(null == code){
getWXCodeByUrl(wxAuthPath,'step1');
}
// 如果有state=step1 根据code去登陆
if(state === 'step1'){
loginByWxCode(code).then(res => {
sessionStorage.setItem('token',res.token)
this.$router.push({ path: this.redirect || '/', query: this.otherQuery })
}).catch(err => {
// 如果登陆失败那么输入账号登陆重新获取code传递给后端做绑定
getWXCodeByUrl(wxAuthPath,'step2');
})
}else if(state === 'step2'){
this.loginForm.wxCode = code
}
}
},
onWechat(){
let url = this.$route.query.redirect ? this.$route.query.redirect : '/dashboard'
this.$wechat.oAuth(url, 'login')
},
handleResize(event) {
this.fullWidth = document.body.clientWidth
},
@@ -217,19 +260,25 @@ export default {
})
},
handleLogin() {
const code = this.$route.query.code;
this.$refs.loginForm.validate(valid => {
if (valid) {
this.loading = true
if(this.$wechat.isWeixin()){
this.loginForm.wxCode = code
}
this.$store.dispatch('user/login', this.loginForm)
.then(() => {
this.$router.push({ path: this.redirect || '/', query: this.otherQuery })
console.log('lalaalalala')
getStoreStaff()
this.loading = false
}).catch(() => {
}).catch((err) => {
this.loading = false
if(this.$wechat.isPhone()) this.$dialog.error(err.message);
this.getCaptcha()
})
} else {
console.log('error submit!!')
return false
}
})
@@ -262,6 +311,21 @@ export default {
$transition-time : .2s;
$ease-in-out : ease-in-out;
$subsidiary-color : #808695;
.footer{
align-items: center;
justify-content: center;
width: 50%;
height: 36px;
cursor: pointer;
}
.wechat{
width: 26px;
height: 26px;
img{
width: 100%;
height: 100%;
}
}
.page-account{
display: flex;
flex-direction: column;

View File

@@ -126,7 +126,6 @@
},
methods: {
remoteMethod(query) {
console.log(query)
if (query !== '') {
this.loading = true;
setTimeout(() => {

View File

@@ -0,0 +1,62 @@
<template>
<div class="lottie-bg">
<div>222进来了22222</div>
<div id="lottie">
<img
src="@/assets/imgs/live-logo.gif"
rel="preload"
style="width: 100%;"
/>
</div>
</div>
</template>
<script>
import { auth, oAuth } from "@/libs/wechat";
import Cookies from 'js-cookie'
const WX_AUTH = "wx_auth";
export default {
name: 'AuthSend',
created() {
import('@/assets/js/media_750')
// const hash = window.location.search.slice(1)
// if (window.localStorage) {
// window.localStorage.setItem('x-admin-oauth-code', hash)
// window.close()
// }
Cookies.set(WX_AUTH, this.$route.query.code);
},
render: function(h) {
return h() // avoid warning message
},
mounted() {
if(this.$route.query.code) location.replace("/login");
// oAuth('/auth-send')
// if( Cookies.get(WX_AUTH)!==undefined) location.replace("/login");
}
}
</script>
<style scoped>
.lottie-bg {
position: fixed;
left: 0;
top: 0;
background-color: #fff;
width: 100%;
height: 100%;
z-index: 999;
display: -webkit-flex;
display: flex;
-webkit-align-items: center;
align-items: center;
-webkit-justify-content: center;
justify-content: center;
}
#lottie {
width: 35%;
display: block;
overflow: hidden;
transform: translate3d(0, 0, 0);
margin: auto;
}
</style>

View File

@@ -0,0 +1,30 @@
<template>
<div
class="Loads acea-row row-center-wrapper"
v-if="loading && !loaded"
style="margin-top: .2rem;font-size: 12px"
>
<template v-if="loading">
<div
class="iconfont icon-jiazai loading acea-row row-center-wrapper"
></div>
正在加载中
</template>
<template v-else>
上拉加载更多
</template>
</div>
</template>
<script>
export default {
name: "Loading",
props: {
loaded: Boolean,
loading: Boolean
},
created() {
import('@/assets/js/media_750')
}
};
</script>

View File

@@ -0,0 +1,257 @@
<template>
<div>
<div class="priceChange" :class="change === true ? 'on' : ''">
<div class="priceTitle">
{{
status === 0 || status === 2
? orderInfo.refundStatus === 1
? "立即退款"
: "一键改价"
: "订单备注"
}}
<span class="iconfont icon-guanbi" @click="close"></span>
</div>
<div class="listChange" v-if="status === 0 || status === 2">
<div
class="item acea-row row-between-wrapper"
v-if="orderInfo.refundStatus === 0"
>
<div>商品总价(¥)</div>
<div class="money">
{{ orderInfo.totalPrice }}<span class="iconfont icon-suozi"></span>
</div>
</div>
<div
class="item acea-row row-between-wrapper"
v-if="orderInfo.refundStatus === 0"
>
<div>原始邮费(¥)</div>
<div class="money">
{{ orderInfo.payPostage }}<span class="iconfont icon-suozi"></span>
</div>
</div>
<div
class="item acea-row row-between-wrapper"
v-if="orderInfo.refundStatus === 0"
>
<div>实际支付(¥)</div>
<div class="money">
<input
type="text"
v-model="price"
:class="focus === true ? 'on' : ''"
@focus="priceChange"
/>
</div>
</div>
<div
class="item acea-row row-between-wrapper"
v-if="orderInfo.refundStatus === 1"
>
<div>实际支付(¥)</div>
<div class="money">
{{ orderInfo.payPrice }}<span class="iconfont icon-suozi"></span>
</div>
</div>
<div
class="item acea-row row-between-wrapper"
v-if="orderInfo.refundStatus === 1"
>
<div>退款金额(¥)</div>
<div class="money">
<input
type="text"
v-model="refundPrice"
:class="focus === true ? 'on' : ''"
@focus="priceChange"
/>
</div>
</div>
</div>
<div class="listChange" v-else>
<textarea
:placeholder="
orderInfo.remark ? orderInfo.remark : '请填写备注信息...'
"
v-model="remark" maxlength="100"
></textarea>
</div>
<div class="modify" @click="save">
{{ orderInfo.refundStatus === 0 || status === 1 ? "立即修改" : "确认退款" }}
</div>
<div class="modify1" @click="refuse" v-if="orderInfo.refundStatus === 1 && status === 2">
拒绝退款
</div>
</div>
<div class="maskModel" @touchmove.prevent v-show="change === true"></div>
</div>
</template>
<script>
import {required, num} from "@/utils/validate";
import {validatorDefaultCatch} from "@/libs/dialog";
import { orderMarkApi, editPriceApi, orderRefundApi } from '@/api/order';
export default {
name: "PriceChange",
components: {},
props: {
change: Boolean,
orderInfo: {
type: Object,
default: null
},
status: {
type: Number,
default: 0
}
},
data: function () {
return {
focus: false,
price: 0,
refundPrice: 0,
remark: ""
};
},
watch: {
orderInfo: function () {
this.price = this.orderInfo.payPrice;
this.refundPrice = this.orderInfo.payPrice;
this.remark = this.orderInfo.remark;
}
},
created() {
import('@/assets/js/media_750')
},
methods: {
priceChange: function () {
this.focus = true;
},
close: function () {
this.price = this.orderInfo.payPrice;
this.$emit("closechange", false);
},
save() {
this.savePrice({
price: this.price,
refundPrice: this.refundPrice,
type: 1,
remark: this.remark,
id: this.orderInfo.id,
orderId: this.orderInfo.orderId
})
},
async savePrice(opt) {
let that = this,
data = {},
price = opt.price,
refundPrice = opt.refundPrice,
refundStatus = that.orderInfo.refundStatus,
remark = opt.remark;
if (that.status == 0 && refundStatus === 0) {
try {
await this.$validator({
price: [
required(required.message("金额")),
num(num.message("金额"))
]
}).validate({price});
} catch (e) {
return validatorDefaultCatch(e);
}
data.price = price;
data.orderId = opt.orderId;
editPriceApi(data).then(() => {
// that.change = false;
this.$emit("closechange", false);
that.$dialog.success("改价成功");
// that.$emit('init');
// that.init();
}).catch((error) => {
that.$dialog.error(error.message);
});
} else if (that.status == 2 && refundStatus === 1) {
try {
await this.$validator({
refundPrice: [
required(required.message("金额")),
num(num.message("金额"))
]
}).validate({refundPrice});
} catch (e) {
return validatorDefaultCatch(e);
}
data.amount = refundPrice;
data.type = opt.type;
data.orderId = opt.id;
orderRefundApi(data).then(
res => {
this.$emit("closechange", false);
// that.change = false;
that.$dialog.success('退款成功');
// that.init();
// that.$emit('init');
},
err => {
this.$emit("closechange", false);
that.$dialog.error(err.message);
}
);
} else {
try {
await this.$validator({
remark: [required(required.message("备注"))]
}).validate({remark});
} catch (e) {
return validatorDefaultCatch(e);
}
data.mark = remark;
data.id = opt.id;
orderMarkApi(data).then(
res => {
this.$emit("closechange", false);
// that.change = false;
that.$dialog.success('提交成功');
// that.$emit('init');
// that.init();
},
err => {
this.$emit("closechange", false);
// that.change = false;
that.$dialog.error(err.message);
}
);
}
},
refuse: function () {
let that = this;
that.$emit("getRefuse", this.orderInfo.id);
}
}
};
</script>
<style scoped>
@import '../../../styles/reset.css';
.priceChange{position:fixed;width:5.8rem;height:6.7rem;background-color:#fff;border-radius:0.1rem;top:50%;left:50%;margin-left:-2.9rem;margin-top:-3.35rem;z-index:99;transition:all 0.3s ease-in-out 0s;-webkit-transition:all 0.3s ease-in-out 0s;-o-transition:all 0.3s ease-in-out 0s;-moz-transition:all 0.3s ease-in-out 0s;-webkit-transform:scale(0);-o-transform:scale(0);-moz-transform:scale(0);-ms-transform:scale(0);
transform: scale(0);opacity:0;}
.priceChange.on{opacity:1;transform: scale(1);-webkit-transform:scale(1);-o-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);}
.priceChange .priceTitle{background:url("../../../assets/imgs/pricetitle.jpg") no-repeat;background-size:100% 100%;width:100%;height:1.6rem;border-radius:0.1rem 0.1rem 0 0;text-align:center;font-size:0.4rem;color:#fff;line-height:1.6rem;position:relative;}
.priceChange .priceTitle .iconfont{position:absolute;font-size:0.4rem;right:0.26rem;top:0.23rem;width:0.4rem;height:0.4rem;line-height:0.4rem;}
.priceChange .listChange{padding:0 0.4rem;}
.priceChange .listChange .item{height:1.03rem;border-bottom:1px solid #e3e3e3;font-size:0.32rem;color:#333;}
.priceChange .listChange .item .money{color:#666;width:3rem;text-align:right;}
.priceChange .listChange .item .money .iconfont{font-size:0.32rem;margin-left:0.2rem;}
.priceChange .listChange .item .money input{width:100%;height:100%;text-align:right;color:#ccc;}
.priceChange .listChange .item .money input.on{color:#666;}
.priceChange .modify{font-size:0.32rem;color:#fff;width:4.9rem;height:0.9rem;text-align:center;line-height:0.9rem;border-radius:0.45rem;background-color:#2291f8;margin:0.53rem auto 0 auto;}
.priceChange .modify1{font-size:0.32rem;color:#312b2b;width:4.9rem;height:0.9rem;text-align:center;line-height:0.9rem;border-radius:0.45rem;background-color:#eee;margin:0.3rem auto 0 auto;}
.priceChange .listChange textarea {
border: 1px solid #eee;
width: 100%;
height: 2rem;
margin-top: 0.5rem;
border-radius: 0.1rem;
color: #333;
padding: 0.2rem;
font-size: 0.3rem;
}
</style>

View File

@@ -0,0 +1,150 @@
<template>
<div v-show="iShidden === false">
<div class="WriteOff">
<div class="pictrue"><img :src="orderInfo.storeOrderInfoVos[0].info.productInfo.image" /></div>
<div class="num acea-row row-center-wrapper">
{{ orderInfo.orderId }}
<div class="views" @click="toDetail(orderInfo)">
查看<span class="iconfont icon-jiantou views-jian"></span>
</div>
</div>
<div class="tip">确定要核销此订单吗</div>
<div class="sure" @click="confirm">确定核销</div>
<div class="sure cancel" @click="cancel">取消</div>
</div>
<div class="maskModel" @touchmove.prevent></div>
</div>
</template>
<script>
export default {
name: "WriteOff",
props: {
iShidden: {
type: Boolean,
default: true
},
orderInfo: {
type: Object,
default: null
}
},
data: function() {
return {};
},
created() {
import('@/assets/js/media_750')
},
methods: {
toDetail: function(item) {
this.$router.push({
path: "/javaMobile/orderDetail/" + item.id + "/looks"
});
},
cancel: function() {
this.$emit("cancel", true);
},
confirm: function() {
this.$emit("confirm", true);
}
}
};
</script>
<style scoped>
.views {
font-size: 0.16rem;
background: #c68937;
border-radius: 4px;
color: #fff;
padding: 0.05rem 0.02rem 0.05rem 0.08rem;
margin-left: 0.1rem;
}
.views-jian {
font-size: 0.1rem;
}
.WriteOff {
width: 5.6rem;
height: 8rem;
background-color: #fff;
border-radius: 0.2rem;
position: fixed;
top: 50%;
left: 50%;
margin-top: -4rem;
margin-left: -2.8rem;
z-index: 99;
padding-top: 0.55rem;
}
.WriteOff .pictrue {
width: 3.4rem;
height: 3.4rem;
margin: 0 auto;
}
.WriteOff .pictrue img {
width: 100%;
height: 100%;
display: block;
border-radius: 0.1rem;
}
.WriteOff .num {
font-size: 0.3rem;
color: #666;
margin: 0.28rem 0 0.3rem 0;
}
.WriteOff .num .see {
font-size: 0.16rem;
color: #fff;
border-radius: 0.04rem;
background-color: #c68937;
padding-left: 0.05rem;
margin-left: 0.12rem;
}
.WriteOff .num .see .iconfont {
font-size: 0.15rem;
}
.WriteOff .tip {
font-size: 0.36rem;
color: #282828;
text-align: center;
border-top: 1px dashed #ccc;
padding-top: 0.4rem;
position: relative;
}
.WriteOff .tip:after {
content: "";
position: absolute;
width: 0.25rem;
height: 0.25rem;
border-radius: 50%;
background-color: #7f7f7f;
right: -0.125rem;
top: -0.125rem;
}
.WriteOff .tip:before {
content: "";
position: absolute;
width: 0.25rem;
height: 0.25rem;
border-radius: 50%;
background-color: #7f7f7f;
left: -0.125rem;
top: -0.125rem;
}
.WriteOff .sure {
font-size: 0.32rem;
color: #fff;
text-align: center;
line-height: 0.82rem;
height: 0.82rem;
width: 4.6rem;
border-radius: 0.41rem;
margin: 0.4rem auto 0 auto;
background-image: linear-gradient(to right, #f67a38 0%, #f11b09 100%);
background-image: -webkit-linear-gradient(to right, #f67a38 0%, #f11b09 100%);
background-image: -moz-linear-gradient(to right, #f67a38 0%, #f11b09 100%);
}
.WriteOff .sure.cancel {
background-image: none;
color: #999;
margin-top: 0.1rem;
}
</style>

View File

@@ -0,0 +1,68 @@
<template>
<div ref="container">
<div class="public-wrapper">
<div class="title">
<span class="iconfont icon-xiangxishuju"></span>详细数据
</div>
<div class="nav acea-row row-between-wrapper">
<div class="data">日期</div>
<div class="browse">订单数</div>
<div class="turnover">成交额</div>
</div>
<div class="conter">
<div
class="item acea-row row-between-wrapper"
v-for="(item, index) in list"
:key="index"
>
<div class="data">{{ item.time }}</div>
<div class="browse">{{ item.count }}</div>
<div class="turnover">{{ item.price }}</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { statisticsDataApi } from '@/api/order';
export default {
name: "statisticsData",
props: {
list:{
type: Array,
default: ()=> []
}
},
components: {
// Loading
},
data() {
return {
// list: [],
where: {
page: 1,
limit: 10
},
loaded: false,
loading: false
}
},
created() {
import('@/assets/js/media_750')
}
}
</script>
<style scoped lang="scss">
.public-wrapper .title{font-size:0.3rem;color:#282828;padding:0 0.3rem;margin-bottom:0.2rem;}
.public-wrapper .title .iconfont{color:#2291f8;font-size:0.4rem;margin-right:0.13rem;vertical-align:middle;}
.public-wrapper{margin:0.18rem auto 0 auto;width:6.9rem;background-color:#fff;border-radius:0.1rem;padding-top:0.25rem;}
.public-wrapper .nav{padding:0 0.3rem;height:0.7rem;line-height:0.7rem;font-size:0.24rem;color:#999;}
.public-wrapper .data{width:2.1rem;text-align:left;}
.public-wrapper .browse{width:1.92rem;text-align:right;}
.public-wrapper .turnover{width:2.27rem;text-align:right;}
.public-wrapper .conter{padding:0 0.3rem;}
.public-wrapper .conter .item{border-bottom:1px solid #f7f7f7;height:0.7rem;font-size:0.24rem;}
.public-wrapper .conter .item .turnover{color:#d84242;}
</style>

View File

@@ -0,0 +1,167 @@
<template>
<div>
<div class="OrderCancellation">
<div class="header"></div>
<div class="whiteBg">
<div class="input">
<input type="number" placeholder="请输入核销码" v-model="verify_code" />
</div>
<div class="bnt" @click="storeCancellation">立即核销</div>
</div>
<div class="scan" v-if="isWeixin">
<img src="../../../assets/imgs/scan.gif" @click="openQRCode" />
</div>
</div>
<WriteOff
v-if="orderInfo"
:iShidden="iShidden"
:orderInfo="orderInfo"
@cancel="cancel"
@confirm="confirm"
></WriteOff>
</div>
</template>
<script>
import WriteOff from "../components/WriteOff";
import { wechatEvevt } from "@/libs/wechat";
// import { orderVerific } from "@api/order";
import { writeUpdateApi, writeConfirmApi } from '@/api/order'
const NAME = "OrderCancellation";
export default {
name: NAME,
components: {
WriteOff
},
props: {},
data: function() {
return {
isWeixin: this.$wechat.isWeixin(),
iShidden: true,
orderInfo: null,
verify_code: ""
};
},
created() {
import('@/assets/js/media_750')
},
methods: {
cancel: function(res) {
this.iShidden = res;
},
confirm: function() {
writeUpdateApi(this.verify_code)
.then(res => {
this.iShidden = true;
this.verify_code = "";
this.$dialog.success(res.msg);
})
.catch(res => {
this.$dialog.error(res.msg);
});
},
storeCancellation: function() {
let ref = /[0-9]{10}/;
if (!this.verify_code) return this.$dialog.error("请输入核销码");
if (!ref.test(this.verify_code))
return this.$dialog.error("请输入正确的核销码");
this.$dialog.loading.open("查询中");
writeConfirmApi(this.verify_code)
.then(res => {
this.$dialog.loading.close();
this.orderInfo = res;
this.iShidden = false;
})
.catch(res => {
this.$dialog.loading.close();
this.verify_code = "";
return this.$dialog.error(res.message);
});
},
openQRCode: function() {
let that = this;
wechatEvevt("scanQRCode", {
needResult: 1,
scanType: ["qrCode", "barCode"]
})
.then(res => {
console.log('openQRCode',res)
if (res.resultStr) {
that.verify_code = res.resultStr;
that.storeCancellation();
} else that.$dialog.error("没有扫描到什么!");
})
.catch(res => {
console.log('catch', res)
if (res.is_ready) {
res.wx.scanQRCode({
needResult: 1,
scanType: ["qrCode", "barCode"],
success: function(res) {
that.verify_code = res.resultStr;
that.storeCancellation();
},
fail: function(res) {
if (res.errMsg == "scanQRCode:permission denied") {
that.$dialog.error("没有权限");
}
}
});
}
});
}
}
};
</script>
<style scoped lang="scss">
.OrderCancellation .header {
background: url("../../../assets/imgs/writeOffBg.jpg") no-repeat;
width: 100%;
height: 3rem;
background-size: 100% 100%;
}
.OrderCancellation .whiteBg {
width: 5.9rem;
background-color: #fff;
margin: -0.93rem auto 0 auto;
padding-top: 0.8rem;
border-radius: 0.06rem 0.06rem 0 0;
}
.OrderCancellation .whiteBg .input {
width: 5.8rem;
margin: 0 auto;
border-bottom: 0.01rem solid #eee;
}
.OrderCancellation .whiteBg .input input {
padding: 0.25rem;
font-size: 0.6rem;
color: #282828;
width: 100%;
text-align: center;
border: none;
}
.OrderCancellation .whiteBg .bnt {
font-size: 0.32rem;
color: #fff;
width: 5.8rem;
height: 0.86rem;
border-radius: 0.43rem;
background-image: linear-gradient(to right, #f67a38 0%, #f11b09 100%);
background-image: -webkit-linear-gradient(to right, #f67a38 0%, #f11b09 100%);
background-image: -moz-linear-gradient(to right, #f67a38 0%, #f11b09 100%);
text-align: center;
line-height: 0.86rem;
margin: 0.55rem auto 0 auto;
}
.OrderCancellation .scan {
width: 3rem;
height: 3rem;
margin: 1.1rem auto 0 auto;
background-color: #f5f5f5;
}
.OrderCancellation .scan img {
width: 100%;
height: 100%;
display: block;
}
</style>

View File

@@ -0,0 +1,477 @@
<template>
<div class="statistical-page" ref="container">
<div class="navs">
<div class="list">
<div
class="item"
:class="time == 'today' ? 'on' : ''"
@click="setTime('today')"
>
今天
</div>
<div
class="item"
:class="time == 'yesterday' ? 'on' : ''"
@click="setTime('yesterday')"
>
昨天
</div>
<div
class="item"
:class="time == 'lately7' ? 'on' : ''"
@click="setTime('lately7')"
>
最近7天
</div>
<div
class="item"
:class="time == 'month' ? 'on' : ''"
@click="setTime('month')"
>
本月
</div>
<div
class="item"
:class="time == 'date' ? 'on' : ''"
@click="dateTitle"
>
<!-- <span class="iconfont icon-xiangxia"></span>
<span v-for="(value, index) in renderValues" :key="index">
{{ value }}</span
> -->
自定义
</div>
</div>
</div>
<div class="wrapper">
<div class="title">
{{ title }}{{ this.where.type == 1 ? "营业额(元)" : "订单量(份)" }}
</div>
<div class="money">{{ time_price }}</div>
<div class="increase acea-row row-between-wrapper">
<div>
{{ title }}增长率<span
:class="increase_time_status === 1 ? 'red' : 'green'"
>{{ increase_time_status === 1 ? "" : "-" }}{{ growth_rate }}%
<span
class="iconfont"
:class="
increase_time_status === 1
? 'icon-xiangshang1'
: 'icon-xiangxia2'
"
></span
></span>
</div>
<div>
{{ title }}增长<span
:class="increase_time_status === 1 ? 'red' : 'green'"
>{{ Number(increase_time).toFixed(2) }}
<span
class="iconfont"
:class="
increase_time_status === 1
? 'icon-xiangshang1'
: 'icon-xiangxia2'
"
></span
></span>
</div>
</div>
</div>
<div class="chart">
<div class="company">
{{ where.type === 1 ? "单位(元)" : "单位(份)" }}
</div>
<ECharts :options="polar"></ECharts>
</div>
<!--<div class="public-wrapper">-->
<!--<div class="title">-->
<!--<span class="iconfont icon-xiangxishuju"></span>详细数据-->
<!--</div>-->
<!--<div class="nav acea-row row-between-wrapper">-->
<!--<div class="data">日期</div>-->
<!--<div class="browse">订单量</div>-->
<!--<div class="turnover">成交额</div>-->
<!--</div>-->
<!--<div class="conter">-->
<!--<div-->
<!--class="item acea-row row-between-wrapper"-->
<!--v-for="(item, index) in list"-->
<!--:key="index"-->
<!--&gt;-->
<!--<div class="data">{{ item.time }}</div>-->
<!--<div class="browse">{{ item.count }}</div>-->
<!--<div class="turnover">{{ item.price }}</div>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<statistics-data :list="list"></statistics-data>
<div class="calendar-wrapper" :class="current === true ? 'on' : ''">
<div class="calendar">
<Calendar
:clean="clean"
:lunar="lunar"
ref="calendar"
:range="isrange"
:multi="ismulti"
@select="select"
@next="next"
@prev="prev"
:value="value"
:weekSwitch="weekSwitch"
:monthRange="monthRange"
rangeMonthFormat="yyyy-mm-dd"
monFirst
responsive
:begin="[1992, 5, 20]"
:end="[2049, 5, 20]"
/>
</div>
</div>
<div
class="maskModel"
@touchmove.prevent
v-show="current === true"
@click="close"
></div>
<Loading :loaded="loaded" :loading="loading"></Loading>
</div>
</template>
<script>
import statisticsData from "../components/statisticsData";
import ECharts from "vue-echarts";
import "echarts/lib/chart/line";
import "echarts/lib/component/polar";
import Calendar from "mpvue-calendar";
import "mpvue-calendar/src/browser-style.css";
import { statisticsDataApi, orderTimeApi } from '@/api/order';
import { parseTime } from '@/utils';
import Loading from "../components/Loading";
const year = new Date().getFullYear();
const month = new Date().getMonth() + 1;
const day = new Date().getDate();
export default {
name: "Statistics",
components: {
ECharts,
Calendar,
Loading,
statisticsData
},
props: {},
data: function() {
return {
polar: {
tooltip: {
trigger: "axis"
},
legend: {
data: [""]
},
toolbox: {
show: false,
feature: {
mark: { show: true },
dataView: { show: true, readOnly: false },
magicType: { show: true, type: ["line"] },
restore: { show: true },
saveAsImage: { show: true }
}
},
calculable: true,
xAxis: [
{
type: "category",
boundaryGap: false,
data: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"],
splitLine: {
show: false
},
axisLine: {
lineStyle: {
color: "#999",
width: 1 //这里是为了突出显示加上的
}
}
}
],
yAxis: [
{
type: "value",
splitLine: {
show: true,
lineStyle: {
color: ["#f5f5f5"],
width: 1,
type: "solid"
}
},
axisLine: {
lineStyle: {
color: "#999",
width: 1 //这里是为了突出显示加上的
}
}
}
],
series: [
{
name: "邮件营销",
type: "line",
stack: "总量",
itemStyle: {
normal: {
color: "#2291f8", //折点颜色
lineStyle: {
color: "#2291f8" //折线颜色
}
}
},
data: [120, 132.5, 101, 134, 90, 150, 30]
}
],
grid: {
x: 30,
x2: 10,
y: 20,
y2: 110,
left: 40
},
animationDuration: 2000
},
value: [[year, month, day - 1], [year, month, day]],
isrange: true,
weekSwitch: false,
ismulti: false,
monFirst: true,
clean: true, //简洁模式
lunar: false, //显示农历
renderValues: [],
monthRange: [],
current: false,
where: {
dateLimit : '',
type: ''
},
types: "", //类型|order=订单数|price=营业额
time: "", //时间|today=今天|yesterday=昨天|month=本月
title: "", //时间|today=今天|yesterday=昨天|month=本月
growth_rate: "", //增长率
increase_time: "", //增长率
increase_time_status: "", //增长率
time_price: "", //增长率
loaded: false,
loading: false,
filter: {
page: 1,
limit: 10,
dateLimit: ""
},
list: []
};
},
watch: {
"$route.params": function(newVal) {
var that = this;
if (newVal != undefined) {
that.setType(newVal.type);
that.setTime(newVal.time);
that.getIndex();
}
}
},
mounted: function() {
this.handelRenderValues();
this.setTime(this.$route.params.time);
this.setType(this.$route.params.type);
this.getIndex();
this.getInfo();
this.$scroll(this.$refs.container, () => {
!this.loading && this.getInfo();
});
},
computed: {
monthRangeText() {
return this.monthRange.length ? "固定" : "指定范围";
}
},
methods: {
getIndex: function() {
var that = this;
orderTimeApi(that.where).then(
res => {
var _info = res.chart,
day = [],
num = [];
_info.forEach(function(item) {
day.push(item.time);
num.push(item.num);
});
that.polar.xAxis[0].data = day;
that.polar.series[0].data = num;
that.growth_rate = res.growthRate;
that.increase_time = res.increaseTime;
that.increase_time_status = res.increaseTimeStatus;
that.time_price = res.time;
},
error => {
that.$dialog.error(error.msg);
}
);
},
setTime: function(time) {
this.time = time;
this.where.dateLimit = time
this.list = [];
this.filter.page = 1;
this.loaded = false;
this.loading = false;
this.getIndex();
this.getInfo();
},
setType: function(type) {
switch (type) {
case "price":
this.where.type = 1;
break;
case "order":
this.where.type = 2;
break;
}
},
handelRenderValues(data) {
if (this.ismulti) {
this.renderValues = this.value.map(v => v.join("-"));
} else if (this.isrange) {
const values = [];
data || this.value;
this.value.forEach((v, i) => {
values.push(v.join("-"));
// if (!i) {
// values.push("~");
// }
});
this.renderValues = values;
} else {
this.renderValues = [this.value.join("-")];
}
console.log( this.renderValues)
this.where.dateLimit = parseTime(this.renderValues[0], '{y}-{m}-{d}')+','+parseTime(this.renderValues[1], '{y}-{m}-{d}')
this.filter.dateLimit = this.where.dateLimit
},
prev(y, m, w) {
console.log(y, m, w);
},
next(year, month, week) {
console.log(year, month, week);
},
selectYear(year) {
},
setToday() {
this.$refs.calendar.setToday();
},
dateInfo() {
const info = this.$refs.calendar.dateInfo(2018, 8, 23);
},
renderer() {
if (this.monthRange.length) {
this.monthRange = ["2018-08", "2018-08"];
}
this.$refs.calendar.renderer(2018, 8); //渲染2018年8月份
},
select(val, val2) {
if (this.isrange) {
this.handelRenderValues([val, val2]);
} else if (this.ismulti) {
this.handelRenderValues(val);
} else {
this.handelRenderValues([val]);
}
this.list = [];
this.filter.page = 1;
this.loaded = false;
this.loading = false;
this.time = "date";
this.title = "";
// this.getIndex();
// this.getInfo();
},
dateTitle: function() {
this.current = true;
},
close: function() {
this.current = false;
this.getIndex();
this.getInfo();
},
getInfo: function() {
var that = this;
if (that.loading || that.loaded) return;
that.loading = true;
statisticsDataApi(that.filter).then(
res => {
that.loading = false;
that.loaded = res.length < that.filter.limit;
that.list.push.apply(that.list, res);
that.filter.page = that.filter.page + 1;
},
error => {
that.$dialog.message(error.msg);
}
);
}
}
};
</script>
<style scoped lang="scss">
.public-wrapper .title{font-size:0.3rem;color:#282828;padding:0 0.3rem;margin-bottom:0.2rem;}
.public-wrapper .title .iconfont{color:#2291f8;font-size:0.4rem;margin-right:0.13rem;vertical-align:middle;}
.public-wrapper{margin:0.18rem auto 0 auto;width:6.9rem;background-color:#fff;border-radius:0.1rem;padding-top:0.25rem;}
.public-wrapper .nav{padding:0 0.3rem;height:0.7rem;line-height:0.7rem;font-size:0.24rem;color:#999;}
.public-wrapper .data{width:2.1rem;text-align:left;}
.public-wrapper .browse{width:1.92rem;text-align:right;}
.public-wrapper .turnover{width:2.27rem;text-align:right;}
.public-wrapper .conter{padding:0 0.3rem;}
.public-wrapper .conter .item{border-bottom:1px solid #f7f7f7;height:0.7rem;font-size:0.24rem;}
.public-wrapper .conter .item .turnover{color:#d84242;}
.statistical-page .navs{width:100%;height:0.96rem;background-color:#fff;overflow:hidden;line-height:0.96rem;position:fixed;top:0;left:0;z-index:9;}
.statistical-page .navs .list{overflow-y:hidden;overflow-x:auto;white-space: nowrap;-webkit-overflow-scrolling: touch;
width: 100%;}
.statistical-page .navs .item{font-size:0.32rem;color:#282828;margin-left:0.6rem;display: inline-block;}
.statistical-page .navs .item.on{color:#2291f8;}
.statistical-page .navs .item .iconfont{font-size:0.25rem;margin-left:0.13rem;}
.statistical-page .wrapper{width:7.4rem;background-color:#fff;border-radius:0.1rem;margin:0.19rem auto 0 auto;padding:0.5rem 0.6rem;}
.statistical-page .wrapper .title{font-size:0.3rem;color:#999;text-align:center;}
.statistical-page .wrapper .money{font-size:0.72rem;color:#fba02a;text-align:center;margin-top:0.1rem;}
.statistical-page .wrapper .increase{font-size:0.28rem;color:#999;margin-top:0.2rem;}
.statistical-page .wrapper .increase .red{color:#ff6969;}
.statistical-page .wrapper .increase .green{color:#1abb1d;}
.statistical-page .wrapper .increase .iconfont{font-size:0.23rem;margin-left:0.15rem;}
.statistical-page .chart{width:6.9rem;height:4.8rem;background-color:#fff;border-radius:0.1rem;margin:0.23rem auto 0 auto;padding: 0.25rem 0.22rem 0 0.22rem;}
.statistical-page .chart .company{font-size:0.26rem;color:#999;}
.statistical-page .mc-body{padding-bottom:0;}
.statistical-page .mc-body tr{background-color: #edf8fe;border-top: 1px solid #fff;width:100%;}
.echarts {
width: 100%;
height: 5.5rem;
}
.calendar-wrapper {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
z-index: 777;
transform: translate3d(0, 100%, 0);
transition: all 0.3s cubic-bezier(0.25, 0.5, 0.5, 0.9);
}
.calendar-wrapper.on {
transform: translate3d(0, 0, 0);
}
.statistical-page .wrapper .increase {
font-size: 0.26rem;
}
.statistical-page .wrapper .increase .iconfont {
margin-left: 0;
}
</style>

View File

@@ -0,0 +1,146 @@
<template>
<div class="order-index" ref="container">
<div class="header acea-row">
<router-link class="item" :to="'/javaMobile/orderList/unPaid'">
<div class="num">{{ census.unpaidCount }}</div>
<div>待付款</div>
</router-link>
<router-link class="item" :to="'/javaMobile/orderList/notShipped'">
<div class="num">{{ census.unshippedCount }}</div>
<div>待发货</div>
</router-link>
<router-link class="item" :to="'/javaMobile/orderList/spike'">
<div class="num">{{ census.receivedCount }}</div>
<div>待收货</div>
</router-link>
<router-link class="item" :to="'/javaMobile/orderList/toBeWrittenOff'">
<div class="num">{{ census.verificationCount }}</div>
<div>待核销</div>
</router-link>
<router-link class="item" :to="'/javaMobile/orderList/refunding'">
<div class="num">{{ census.refundCount }}</div>
<div>退款</div>
</router-link>
</div>
<div class="wrapper">
<div class="title">
<span class="iconfont icon-shujutongji"></span>数据统计
</div>
<div class="list acea-row">
<router-link class="item" :to="'/javaMobile/orderStatisticsDetail/price/today'">
<div class="num">{{ census.todayPrice }}</div>
<div>今日成交额</div>
</router-link>
<router-link class="item" :to="'/javaMobile/orderStatisticsDetail/price/yesterday'">
<div class="num">{{ census.proPrice }}</div>
<div>昨日成交额</div>
</router-link>
<router-link class="item" :to="'/javaMobile/orderStatisticsDetail/price/month'">
<div class="num">{{ census.monthPrice }}</div>
<div>本月成交额</div>
</router-link>
<router-link class="item" :to="'/javaMobile/orderStatisticsDetail/order/today'">
<div class="num">{{ census.todayCount }}</div>
<div>今日订单数</div>
</router-link>
<router-link class="item" :to="'/javaMobile/orderStatisticsDetail/order/yesterday'">
<div class="num">{{ census.proCount }}</div>
<div>昨日订单数</div>
</router-link>
<router-link class="item" :to="'/javaMobile/orderStatisticsDetail/order/month'">
<div class="num">{{ census.monthCount }}</div>
<div>本月订单数</div>
</router-link>
</div>
</div>
<statistics-data :list="list"></statistics-data>
<Loading :loaded="loaded" :loading="loading"></Loading>
</div>
</template>
<script>
import {orderStatisticsApi, statisticsDataApi } from '@/api/order';
import statisticsData from "../components/statisticsData";
import Loading from "../components/Loading";
export default {
name: "OrderIndex",
components: {
Loading,
statisticsData
},
props: {},
data: function() {
return {
census: [],
list: [],
where: {
page: 1,
limit: 10
},
loaded: false,
loading: false
};
},
created() {
import('@/assets/js/media_750')
},
mounted: function() {
this.getIndex();
this.getList();
this.$scroll(this.$refs.container, () => {
!this.loading && this.getList();
});
},
methods: {
getIndex() {
orderStatisticsApi().then(
res => {
this.census = res
},
err => {
this.$dialog.message(err.message);
}
);
},
getList() {
if (this.loading || this.loaded) return;
this.loading = true;
statisticsDataApi(this.where).then(
res => {
this.loading = false;
this.loaded = res.length < this.where.limit;
this.list.push.apply(this.list, res);
this.where.page = this.where.page + 1;
},
error => {
this.$dialog.message(error.message);
},
300
);
}
}
};
</script>
<style scoped lang="scss">
.order-index{
background: #f5f5f5;
}
.order-index .header{background:url("../../../assets/imgs/orderIndex.png") no-repeat;background-size:100% 100%;width:100%;height:3.02rem;padding:0.45rem 0.3rem 0 0.3rem;}
.order-index .header .item{flex:1;-webkit-flex:1;-o-flex:1;-ms-flex:1;text-align:center;font-size:0.24rem;color:#fff;}
.order-index .header .item .num{font-size:0.4rem;margin-bottom:0.07rem;}
.order-index .wrapper{width:6.9rem;background-color:#fff;border-radius:0.1rem;margin:-1.15rem auto 0 auto;padding-top:0.25rem;}
.order-index .wrapper .title{font-size:0.3rem;color:#282828;padding:0 0.3rem;margin-bottom:0.4rem;}
.order-index .wrapper .title .iconfont{color:#2291f8;font-size:0.4rem;margin-right:0.13rem;vertical-align:middle;}
.order-index .wrapper .list .item{width:33.33%;text-align:center;font-size:0.24rem;color:#999;margin-bottom:0.45rem;}
.order-index .wrapper .list .item .num{font-size:0.4rem;color:#333;}
.public-wrapper .title{font-size:0.3rem;color:#282828;padding:0 0.3rem;margin-bottom:0.2rem;}
.public-wrapper .title .iconfont{color:#2291f8;font-size:0.4rem;margin-right:0.13rem;vertical-align:middle;}
.public-wrapper{margin:0.18rem auto 0 auto;width:6.9rem;background-color:#fff;border-radius:0.1rem;padding-top:0.25rem;}
.public-wrapper .nav{padding:0 0.3rem;height:0.7rem;line-height:0.7rem;font-size:0.24rem;color:#999;}
.public-wrapper .data{width:2.1rem;text-align:left;}
.public-wrapper .browse{width:1.92rem;text-align:right;}
.public-wrapper .turnover{width:2.27rem;text-align:right;}
.public-wrapper .conter{padding:0 0.3rem;}
.public-wrapper .conter .item{border-bottom:1px solid #f7f7f7;height:0.7rem;font-size:0.24rem;}
.public-wrapper .conter .item .turnover{color:#d84242;}
</style>

View File

@@ -0,0 +1,242 @@
<template>
<div class="deliver-goods">
<header>
<div class="order-num acea-row row-between-wrapper">
<div class="num line1">订单号{{ orderId }}</div>
<div class="name line1">
<span class="iconfont icon-yonghu2"></span>{{ delivery.user.nickname }}
</div>
</div>
<div class="address">
<div class="name">
{{ delivery.realName
}}<span class="phone">{{ delivery.userPhone }}</span>
</div>
<div>{{ delivery.userAddress }}</div>
</div>
<div class="line"><img src="../../../assets/imgs/line.jpg" /></div>
</header>
<div class="wrapper">
<div class="item acea-row row-between-wrapper">
<div>发货方式</div>
<div class="mode acea-row row-middle row-right">
<div
class="goods"
:class="active === index ? 'on' : ''"
v-for="(item, index) in types"
:key="index"
@click="changeType(item, index)"
>
{{ item.title }}<span class="iconfont icon-xuanzhong2"></span>
</div>
</div>
</div>
<div class="list" v-show="active === 0">
<div class="item acea-row row-between-wrapper">
<div>发货方式</div>
<select class="mode" v-model="expressId">
<option value="">选择快递公司</option>
<option
:value="item.id"
v-for="(item, index) in express"
:key="index"
>{{ item.name }}</option
>
</select>
<span class="iconfont icon-up"></span>
</div>
<div class="item acea-row row-between-wrapper">
<div>快递单号</div>
<input
type="text"
placeholder="填写快递单号"
v-model="expressCode"
class="mode"
/>
</div>
</div>
<div class="list" v-show="active === 1">
<div class="item acea-row row-between-wrapper">
<div>送货人</div>
<input
type="text"
placeholder="填写送货人"
v-model="expressId"
class="mode"
/>
</div>
<div class="item acea-row row-between-wrapper">
<div>送货电话</div>
<input
type="text"
placeholder="填写送货电话"
v-model="expressCode"
class="mode"
/>
</div>
</div>
</div>
<div style="height:1.2rem;"></div>
<div class="confirm" @click="saveInfo">确认提交</div>
</div>
</template>
<script>
// import { getAdminOrderDelivery, setAdminOrderDelivery } from "../../api/admin";
import { orderSendApi, orderDetailApi } from '@/api/order';
import { expressList } from '@/api/logistics';
import { required, num } from "@/utils/validate";
import { validatorDefaultCatch } from "@/libs/dialog";
export default {
name: "GoodsDeliver",
components: {},
props: {},
data: function() {
return {
types: [
{
type: "1",
title: "发货"
},
{
type: "2",
title: "送货"
},
{
type: "3",
title: "无需发货"
}
],
active: 0,
orderId: "",
delivery: {},
express: [],
type: "1",
expressId: "",
expressCode: ""
};
},
watch: {
"$route.params.oid": function(newVal) {
let that = this;
if (newVal != undefined) {
that.orderId = newVal;
that.getIndex();
}
}
},
created() {
import('@/assets/js/media_750')
},
mounted: function() {
this.orderId = this.$route.params.oid;
this.getIndex();
this.getLogistics();
},
methods: {
changeType: function(item, index) {
this.active = index;
this.type = item.type;
this.expressId = "";
this.expressCode = "";
},
getIndex() {
orderDetailApi({ id: this.$route.params.id }).then(res => {
this.delivery = res
}).catch((error)=>{
this.$dialog.error(error.message);
})
},
getLogistics() {
expressList({ page: 1, limit: 999, isShow:1 }).then(async res => {
this.express = res.list
})
},
async saveInfo() {
let that = this,
type = that.type,
expressId = that.expressId,
expressCode = that.expressCode,
save = {};
save.id = that.$route.params.id;
save.type = that.type;
switch (type) {
case "1":
// try {
// await this.$validator({
// expressId: [required(required.message("快递公司"))],
// expressCode: [required(required.message("快递单号"))]
// }).validate({ expressId, expressCode });
// } catch (e) {
// return validatorDefaultCatch(e);
// }
if( !that.expressId ) return that.$dialog.error('请输入快递公司');
if( !that.expressCode ) return that.$dialog.error('请输入快递单号');
save.expressId = expressId;
save.expressCode = expressCode;
save.id = this.$route.params.id;
that.setInfo(save);
break;
case "2":
try {
await this.$validator({
expressId: [required(required.message("发货人姓名"))],
expressCode: [required(required.message("发货人电话"))]
}).validate({ expressId, expressCode });
} catch (e) {
return validatorDefaultCatch(e);
}
save.expressId = expressId;
save.expressCode = expressCode;
that.setInfo(save);
break;
case "3":
that.setInfo(save);
break;
}
},
setInfo: function(item) {
let that = this;
orderSendApi(item).then(
res => {
that.$dialog.success('发送货成功');
that.$router.go(-1);
},
error => {
that.$dialog.error(error.message);
}
);
}
}
};
</script>
<style scoped lang="scss">
/*input{*/
/*line-height: normal; box-sizing:border-box;*/
/*-webkit-text-size-adjust: none; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: 'PingFang SC', 'STHeitiSC-Light', 'Helvetica-Light', arial, sans-serif, 'Droid Sans Fallback'; color:#333;*/
/*outline:none; border:none; -webkit-appearance:none;border-radius: 0; background:none;*/
/*}*/
/*input,input[type="search"],button,select,option,textarea,a{ outline:none; border:0; -webkit-appearance:none;border-radius: 0; background:none;-webkit-box-sizing:border-box;box-sizing:border-box;}*/
/*button, input, select, textarea { font-size:100%; }*/
.deliver-goods header{width:100%;background-color:#fff;margin-top:0.1rem;}
.deliver-goods header .order-num{padding:0 0.3rem;border-bottom:1px solid #f5f5f5;height:0.67rem;}
.deliver-goods header .order-num .num{width:4.3rem;font-size:0.26rem;color:#282828;position:relative;}
.deliver-goods header .order-num .num:after{position:absolute;content:'';width:1px;height:0.3rem;background-color:#ddd;top:50%;margin-top:-0.15rem;right:0;}
.deliver-goods header .order-num .name{width:2.6rem;font-size:0.26rem;color:#282828;text-align: center;}
.deliver-goods header .order-num .name .iconfont{font-size:0.35rem;color:#477ef3;vertical-align:middle;margin-right:0.1rem;}
.deliver-goods header .address{font-size:0.26rem;color:#868686;background-color:#fff;padding:0.3rem;}
.deliver-goods header .address .name{font-size:0.3rem;color:#282828;margin-bottom:0.1rem;}
.deliver-goods header .address .name .phone{margin-left:0.4rem;}
.deliver-goods header .line{width:100%;height:0.03rem;}
.deliver-goods header .line img{width:100%;height:100%;display:block;}
.deliver-goods .wrapper{width:100%;background-color:#fff;}
.deliver-goods .wrapper .item{border-bottom:1px solid #f0f0f0;padding:0 0.3rem;height:0.96rem;font-size:0.32rem;color:#282828;position:relative;}
.deliver-goods .wrapper .item .mode{width:4.6rem;height:100%;text-align:right;}
.deliver-goods .wrapper .item .mode .iconfont{font-size:0.3rem;margin-left:0.13rem;}
.deliver-goods .wrapper .item .mode .goods~.goods{margin-left:0.3rem;}
.deliver-goods .wrapper .item .mode .goods{color:#bbb;}
.deliver-goods .wrapper .item .mode .goods.on{color:#477ef3;}
.deliver-goods .wrapper .item .icon-up{position:absolute;font-size:0.35rem;color:#2c2c2c;right:0.3rem;}
.deliver-goods .wrapper .item select{direction: rtl;padding-right:0.6rem;position: relative;z-index: 2;}
.deliver-goods .wrapper .item input::placeholder{color:#bbb;}
.deliver-goods .confirm{font-size:0.32rem;color:#fff;width:100%;height:1rem;background-color:#477ef3;text-align:center;line-height:1rem;position:fixed;bottom:0;}
</style>

View File

@@ -0,0 +1,433 @@
<template>
<div class="order-details pos-order-details">
<div class="header acea-row row-middle">
<div class="state">{{ title }}</div>
<div class="data">
<div class="order-num">订单{{ orderInfo.orderId }}</div>
<div>
<span class="time">{{ orderInfo.createTime }}</span>
</div>
</div>
</div>
<div
class="remarks acea-row row-between-wrapper"
v-if="$route.params.goname != 'looks'"
>
<span class="iconfont icon-zhinengkefu-"></span>
<input
type="button"
class="line1"
style="text-align: left;"
:value="
orderInfo.remark ? orderInfo.remark : '订单未备注,点击添加备注信息'
"
@click="modify(1)"
/>
</div>
<div class="orderingUser acea-row row-middle">
<span class="iconfont icon-yonghu2"></span>{{ orderInfo.realName }}
</div>
<div class="address">
<div class="name">
{{ orderInfo.realName
}}<span class="phone">{{ orderInfo.userPhone }}</span>
</div>
<div>{{ orderInfo.userAddress }}</div>
</div>
<div class="line"><img src="../../../assets/imgs/line.jpg" /></div>
<div class="pos-order-goods">
<div
class="goods acea-row row-between-wrapper"
v-for="(item, index) in orderInfo.orderInfo"
:key="index"
>
<div class="picTxt acea-row row-between-wrapper">
<div class="pictrue">
<img :src="item.info.productInfo.image"/>
</div>
<div class="text">
<div class="info line2">
{{ item.info.productInfo.storeName }}
</div>
<div class="attr">{{ item.info.productInfo.attrInfo.suk }}</div>
</div>
</div>
<div class="money">
<div class="x-money">{{ item.info.productInfo.price }}</div>
<div class="num">x{{ item.info.cartNum }}</div>
<div class="y-money">{{ item.info.productInfo.otPrice }}</div>
</div>
</div>
</div>
<div class="public-total">
{{ orderInfo.totalNum }}件商品应支付
<span class="money">{{ orderInfo.payPrice }}</span> ( 邮费 ¥{{
orderInfo.payPostage
}}
)
</div>
<div class="wrapper">
<div class="item acea-row row-between">
<div>订单编号</div>
<div class="conter acea-row row-middle row-right">
{{ orderInfo.orderId
}}
<span
class="copy copy-data"
:data-clipboard-text="orderInfo.orderId"
>复制</span
>
</div>
</div>
<div class="item acea-row row-between">
<div>下单时间</div>
<div class="conter">{{ orderInfo.createTime }}</div>
</div>
<div class="item acea-row row-between">
<div>支付状态</div>
<div class="conter">
{{ orderInfo.paid == 1 ? "已支付" : "未支付" }}
</div>
</div>
<div class="item acea-row row-between">
<div>支付方式</div>
<div class="conter">{{ orderInfo.payTypeStr }}</div>
</div>
<div class="item acea-row row-between">
<div>买家留言</div>
<div class="conter">{{ orderInfo.mark }}</div>
</div>
</div>
<div class="wrapper">
<div class="item acea-row row-between">
<div>支付金额</div>
<div class="conter">{{ orderInfo.totalPrice }}</div>
</div>
<div class="item acea-row row-between">
<div>优惠券抵扣</div>
<div class="conter">-{{ orderInfo.couponPrice }}</div>
</div>
<div class="item acea-row row-between">
<div>运费</div>
<div class="conter">{{ orderInfo.payPostage }}</div>
</div>
<div class="actualPay acea-row row-right">
实付款<span class="money font-color-red"
>{{ orderInfo.payPrice }}</span
>
</div>
</div>
<div
class="wrapper"
v-if="
orderInfo.deliveryType === 'express'"
>
<div class="item acea-row row-between">
<div>配送方式:</div>
<div class="conter" v-if="orderInfo.deliveryType === 'express'">
快递
</div>
<div class="conter" v-if="orderInfo.deliveryType === 'send'">送货</div>
</div>
<div class="item acea-row row-between">
<div v-if="orderInfo.deliveryType === 'express'">快递公司:</div>
<div v-if="orderInfo.deliveryType === 'send'">送货人:</div>
<div class="conter">{{ orderInfo.deliveryName }}</div>
</div>
<div class="item acea-row row-between">
<div v-if="orderInfo.deliveryType === 'express'">快递单号:</div>
<div v-if="orderInfo.deliveryType === 'send'">送货人电话:</div>
<div class="conter">
{{ orderInfo.deliveryId
}}<span
class="copy copy-data"
:data-clipboard-text="orderInfo.deliveryId"
>复制</span
>
</div>
</div>
</div>
<div style="height:1.2rem;"></div>
<div
class="footer acea-row row-right row-middle"
v-if="$route.params.goname != 'looks'"
>
<div class="more"></div>
<div class="bnt cancel" @click="modify(0)" v-if="types === 'unPaid'">
一键改价
</div>
<div class="bnt cancel" @click="modify(0)" v-if="types === 'refunding'">
立即退款
</div>
<div class="bnt cancel" @click="modify(1)">订单备注</div>
<!--<div-->
<!--class="bnt cancel"-->
<!--v-if="orderInfo.pay_type === 'offline' && orderInfo.paid === 0"-->
<!--@click="offlinePay"-->
<!--&gt;-->
<!--确认付款-->
<!--</div>-->
<router-link
class="bnt delivery"
v-if="types == 'notShipped'&& orderInfo.shippingType !== 2 && orderInfo.refundStatus !==2"
:to="'/javaMobile/orderDelivery/' + orderInfo.orderId + '/' + orderInfo.id"
>去发货</router-link
>
<router-link
class="bnt delivery"
v-if="types === 'toBeWrittenOff' && orderInfo.shippingType === 2 && isWriteOff && orderInfo.refundStatus === 0 && orderInfo.paid == true"
:to="'/operation/systemStore/orderCancellation'"
>去核销
</router-link>
</div>
<PriceChange
:change="change"
:orderInfo="orderInfo"
v-on:closechange="changeclose($event)"
:status="status"
></PriceChange>
</div>
</template>
<script>
import PriceChange from "../components/PriceChange";
import ClipboardJS from "clipboard";
import { orderDetailApi } from '@/api/order'
import { required, num } from "@/utils/validate";
import { validatorDefaultCatch } from "@/libs/dialog";
import { isWriteOff } from "@/utils";
export default {
name: "AdminOrder",
components: {
PriceChange
},
props: {},
data: function() {
return {
isWriteOff: isWriteOff(),
order: false,
change: false,
orderId: '',
orderInfo: {
},
status: 0,
title: "",
payType: "",
types: ""
};
},
watch: {
"$route.params.id": function(newVal) {
let that = this;
if (newVal != undefined) {
that.orderId = newVal;
that.getIndex();
}
}
},
mounted: function() {
// this.orderId = this.$route.params.id;
this.getIndex();
this.$nextTick(function() {
var copybtn = document.getElementsByClassName("copy-data");
const clipboard = new ClipboardJS(copybtn);
clipboard.on("success", () => {
this.$dialog.success("复制成功");
});
});
},
methods: {
more: function() {
this.order = !this.order;
},
modify: function(status) {
this.change = true;
this.status = status;
},
changeclose: function(msg) {
this.change = msg;
this.getIndex()
},
getIndex: function() {
let that = this;
orderDetailApi({id: this.$route.params.id}).then(
res => {
that.orderInfo = res;
that.types = res.statusStr.key;
that.title = res.statusStr.value;
that.payType = res.payTypeStr;
this.$nextTick(function() {
let copybtn = document.getElementsByClassName("copy-data");
const clipboard = new ClipboardJS(copybtn);
clipboard.on("success", () => {
this.$dialog.success("复制成功");
});
});
},
err => {
that.$dialog.error(err.msg);
}
);
},
// async savePrice(opt) {
// let that = this,
// data = {},
// price = opt.price,
// remark = opt.remark,
// refundStatus = that.orderInfo.refundStatus,
// refundPrice = opt.refundPrice;
// if (that.status == 0 && refundStatus === 0) {
// try {
// await this.$validator({
// price: [
// required(required.message("金额")),
// num(num.message("金额"))
// ]
// }).validate({ price });
// } catch (e) {
// return validatorDefaultCatch(e);
// }
// data.price = price;
// data.orderId = opt.orderId;
// setAdminOrderPrice(data).then(
// function() {
// that.change = false;
// that.$dialog.success("改价成功");
// that.getIndex();
// },
// function() {
// that.change = false;
// that.$dialog.error("改价失败");
// }
// );
// } else if (that.status == 0 && that.orderInfo.refund_status === 1) {
// try {
// await this.$validator({
// refund_price: [
// required(required.message("金额")),
// num(num.message("金额"))
// ]
// }).validate({ refund_price });
// } catch (e) {
// return validatorDefaultCatch(e);
// }
// data.price = refund_price;
// data.type = opt.type;
// setOrderRefund(data).then(
// res => {
// that.change = false;
// that.$dialog.success(res.msg);
// that.getIndex();
// },
// err => {
// that.change = false;
// that.$dialog.error(err.msg);
// that.getIndex();
// }
// );
// } else {
// try {
// await this.$validator({
// remark: [required(required.message("备注"))]
// }).validate({ remark });
// } catch (e) {
// return validatorDefaultCatch(e);
// }
// data.remark = remark;
// setAdminOrderRemark(data).then(
// res => {
// that.change = false;
// that.$dialog.success(res.msg);
// that.getIndex();
// },
// err => {
// that.change = false;
// that.$dialog.error(err.msg);
// }
// );
// }
// },
offlinePay: function() {
setOfflinePay({ orderId: this.orderInfo.orderId }).then(
res => {
this.$dialog.success(res.msg);
this.getIndex();
},
err => {
this.$dialog.error(err.msg);
}
);
}
}
};
</script>
<style scoped lang="scss">
.pos-order-goods{padding:0 0.3rem;background-color: #fff;}
.pos-order-goods .goods{height:1.85rem;}
.pos-order-goods .goods~.goods{border-top:1px dashed #e5e5e5;}
.pos-order-goods .goods .picTxt{width:5.15rem;}
.pos-order-goods .goods .picTxt .pictrue{width:1.3rem;height:1.3rem;}
.pos-order-goods .goods .picTxt .pictrue img{width:100%;height:100%;border-radius:0.06rem;}
.pos-order-goods .goods .picTxt .text{width:3.65rem;height:1.3rem;}
.pos-order-goods .goods .picTxt .text .info{font-size:0.28rem;color:#282828;}
.pos-order-goods .goods .picTxt .text .attr{font-size:0.2rem;color:#999;height: 0.8rem;
line-height: 0.8rem;}
.pos-order-goods .goods .money{width:1.64rem;text-align:right;font-size:0.28rem;}
.pos-order-goods .goods .money .x-money{color:#282828;}
.pos-order-goods .goods .money .num{color:#ff9600;margin:0.05rem 0;}
.pos-order-goods .goods .money .y-money{color:#999;text-decoration:line-through;}
.order-details .header{padding:0 0.3rem;height:1.5rem;}
.order-details .header.on{background-color:#666!important;}
.order-details .header .pictrue{width:1.1rem;height:1.1rem;}
.order-details .header .pictrue img{width:100%;height:100%;}
.order-details .header .data{color:rgba(255,255,255,0.8);font-size:0.24rem;margin-left:0.27rem;}
.order-details .header.on .data{margin-left:0;}
.order-details .header .data .state{font-size:0.3rem;font-weight:bold;color:#fff;margin-bottom:0.07rem;}
.order-details .nav{background-color:#fff;font-size:0.26rem;color:#282828;padding:0.25rem 0;}
.order-details .nav .navCon{padding:0 0.4rem;}
.order-details .nav .navCon .on{font-weight:bold;color:#e93323;}
.order-details .nav .progress{padding:0 0.65rem;margin-top:0.1rem;}
.order-details .nav .progress .line{width:1rem;height:0.02rem;background-color:#939390;}
.order-details .nav .progress .iconfont{font-size:0.25rem;color:#939390;margin-top:-0.02rem;width: 0.3rem;height: 0.3rem;
line-height: 0.33rem;text-align:center;margin-right: 0 !important;}
.order-details .address{font-size:0.26rem;color:#868686;background-color:#fff;padding: 0.25rem 0.3rem 0.3rem 0.3rem;}
.order-details .address .name{font-size:0.3rem;color:#282828;margin-bottom:0.1rem;}
.order-details .address .name .phone{margin-left:0.4rem;}
.order-details .line{width:100%;height:0.03rem;}
.order-details .line img{width:100%;height:100%;display:block;}
.order-details .wrapper{background-color:#fff;margin-top:0.12rem;padding:0.3rem;}
.order-details .wrapper .item{font-size:0.28rem;color:#282828;}
.order-details .wrapper .item~.item{margin-top:0.2rem;}
.order-details .wrapper .item .conter{color:#868686;width:5rem;text-align:right;}
.order-details .wrapper .item .conter .copy{font-size:0.2rem;color:#333;border-radius:0.03rem;border:1px solid #666;
padding:0.03rem 0.15rem;margin-left:0.24rem;}
.order-details .wrapper .actualPay{border-top:0.01rem solid #eee;margin-top:0.3rem;padding-top:0.3rem;}
.order-details .wrapper .actualPay .money{font-weight:bold;font-size:0.3rem;}
.order-details .footer{width:100%;height:1rem;position:fixed;bottom:0;left:0;background-color:#fff;padding:0 0.3rem;border-top:1px solid #eee;}
.order-details .footer .bnt{width:auto;height:0.6rem;text-align:center;line-height:0.6rem;border-radius:0.5rem;
color:#fff;font-size:0.27rem;padding: 0 3%;}
.order-details .footer .bnt.cancel{color:#aaa;border:1px solid #ddd;}
.order-details .footer .bnt.default{color: #444;border: 1px solid #444;}
.order-details .footer .bnt~.bnt{margin-left:0.18rem;}
.pos-order-details .header{background: linear-gradient(to right,#2291f8 0%,#1cd1dc 100%);background: -webkit-linear-gradient(to right, #2291f8 0%,#1cd1dc 100%);background: -moz-linear-gradient(to right,#2291f8 0%,#1cd1dc 100%);}
.pos-order-details .header .state{font-size:0.36rem;color:#fff;}
.pos-order-details .header .data{margin-left:0.35rem;font-size:0.28rem;}
.pos-order-details .header .data .order-num{font-size:0.3rem;margin-bottom:0.08rem;}
.pos-order-details .remarks{width:100%;height:0.86rem;background-color:#fff;padding:0 0.3rem;}
.pos-order-details .remarks .iconfont{font-size:0.4rem;color:#2a7efb;}
.pos-order-details .remarks input{width:6.3rem;height:100%;font-size:0.3rem;}
.pos-order-details .remarks input::placeholder{color:#666;}
.pos-order-details .orderingUser{font-size:0.26rem;color:#282828;padding:0 0.3rem;height:0.67rem;background-color:#fff;margin-top:0.16rem;border-bottom:1px solid #f5f5f5;}
.pos-order-details .orderingUser .iconfont{font-size:0.4rem;color:#2a7efb;margin-right:0.15rem;}
.pos-order-details .address{margin-top:0;}
.pos-order-details .pos-order-goods{margin-top:0.17rem;}
.pos-order-details .footer .more{font-size:0.27rem;color:#aaa;width:1rem;height:0.64rem;text-align:center;line-height:0.64rem;margin-right: 0.25rem;position:relative;}
.pos-order-details .footer .delivery{background: linear-gradient(to right,#2291f8 0%,#1cd1dc 100%);background: -webkit-linear-gradient(to right, #2291f8 0%,#1cd1dc 100%);background: -moz-linear-gradient(to right,#2291f8 0%,#1cd1dc 100%);}
.pos-order-details .footer .more .order .arrow{width: 0;height: 0;border-left: 0.11rem solid transparent;border-right: 0.11rem solid transparent;border-top: 0.2rem solid #e5e5e5;position:absolute;left: 0.15rem;bottom:-0.18rem;}
.pos-order-details .footer .more .order .arrow:before{content:'';width: 0;height: 0;border-left: 0.09rem solid transparent;border-right: 0.09rem solid transparent;border-top: 0.19rem solid #fff;position:absolute;left:-0.1rem;bottom:0;}
.pos-order-details .footer .more .order{width:2rem;background-color:#fff;border:1px solid #eee;border-radius:0.1rem;position:absolute;top:-2rem;z-index:9;}
.pos-order-details .footer .more .order .item{height:0.77rem;line-height:0.77rem;}
.pos-order-details .footer .more .order .item~.item{border-top:1px solid #f5f5f5;}
.pos-order-details .footer .more .moreName{width:100%;height:100%;}
.public-total{font-size:0.28rem;color:#282828;border-top:1px solid #eee;height:0.92rem;line-height:0.92rem;text-align:right;padding:0 0.3rem;background-color: #fff;}
.public-total .money{color:#ff4c3c;}
</style>

View File

@@ -0,0 +1,389 @@
<template>
<div class="pos-order-list" ref="container">
<div class="nav acea-row row-around row-middle">
<div
class="item"
:class="where.status == 'unPaid' ? 'on' : ''"
@click="changeStatus('unPaid')"
>
待付款
</div>
<div
class="item"
:class="where.status == 'notShipped' ? 'on' : ''"
@click="changeStatus('notShipped')"
>
待发货
</div>
<div
class="item"
:class="where.status == 'spike' ? 'on' : ''"
@click="changeStatus('spike')"
>
待收货
</div>
<div
class="item"
:class="where.status == 'toBeWrittenOff' ? 'on' : ''"
@click="changeStatus('toBeWrittenOff')"
>
待核销
</div>
<div
class="item"
:class="where.status == 'complete' ? 'on' : ''"
@click="changeStatus('complete')"
>
已完成
</div>
<div
class="item"
:class="where.status == 'refunding' ? 'on' : ''"
@click="changeStatus('refunding')"
>
退款
</div>
</div>
<div class="list">
<template v-if="list.length > 0">
<div class="item" v-for="(item, index) in list" :key="index">
<div class="order-num acea-row row-middle" @click="toDetail(item)">
订单号{{ item.orderId }}
<span class="time">下单时间{{ item.createTime }}</span>
</div>
<template if="item.productList && item.productList.length">
<div
class="pos-order-goods"
v-for="(val, key) in item.productList"
:key="key"
>
<div
class="goods acea-row row-between-wrapper"
@click="toDetail(item)"
>
<div class="picTxt acea-row row-between-wrapper">
<div class="pictrue">
<img :src="val.info.productInfo.image" />
</div>
<div class="text ">
<div class="info line2">
{{ val.info.productInfo.storeName }}
</div>
<div class="attr" v-if="val.info.productInfo.attrInfo.suk">
{{ val.info.productInfo.attrInfo.suk }}
</div>
</div>
</div>
<div class="money">
<div class="x-money">{{ val.info.productInfo.attrInfo.price }}</div>
<div class="num">x{{ val.info.cartNum }}</div>
<div class="y-money">
<!--{{ val.info.productInfo.attrInfo.otPrice }}-->
</div>
</div>
</div>
</div>
</template>
<div class="public-total">
{{ item.totalNum }}件商品应支付
<span class="money">{{ item.payPrice }}</span> ( 邮费 ¥{{
item.totalPostage
}}
)
</div>
<div class="operation acea-row row-between-wrapper">
<div class="more">
<!-- <div class="iconfont icon-gengduo" @click="more(index)"></div>-->
<!-- <div class="order" v-show="current === index">-->
<!-- <div class="items">-->
<!-- {{ where.status > 0 ? "删除" : "取消" }}订单-->
<!-- </div>-->
<!-- <div class="arrow"></div>-->
<!-- </div>-->
</div>
<div class="acea-row row-middle">
<div class="bnt" @click="modify(item, 0)" v-if="where.status === 'unPaid'">
一键改价
</div>
<div class="bnt" @click="modify(item, 1)">订单备注</div>
<div
class="bnt"
@click="modify(item, 2)"
v-if="where.status === 'refunding' && item.refundStatus === 1"
>
立即退款
</div>
<!--<div-->
<!--class="bnt cancel"-->
<!--v-if="item.pay_type === 'offline' && item.paid === 0"-->
<!--@click="offlinePay(item)"-->
<!--&gt;-->
<!--确认付款-->
<!--</div>-->
<router-link
class="bnt"
v-if="where.status === 'notShipped' && item.shippingType !== 2 && item.refundStatus !==2"
:to="'/javaMobile/orderDelivery/' + item.orderId + '/' + item.id"
>去发货
</router-link>
<router-link
class="bnt"
v-if="where.status === 'toBeWrittenOff' && item.shippingType === 2 && isWriteOff && item.refundStatus === 0 && item.paid == true"
:to="'/javaMobile/orderCancellation'"
>去核销
</router-link>
</div>
</div>
</div>
</template>
<template v-if="!loading && list.length === 0">
<div style="text-align: center;">暂无数据</div>
</template>
</div>
<Loading :loaded="loaded" :loading="loading"></Loading>
<PriceChange
v-if="orderInfo"
:change="change"
:orderInfo="orderInfo"
v-on:closechange="changeclose($event)"
:status="status"
></PriceChange>
</div>
</template>
<script>
import PriceChange from "../components/PriceChange";
import Loading from "../components/Loading";
import { orderRefuseApi, orderListApi, statisticsDataApi, orderMarkApi, editPriceApi, orderRefundApi } from '@/api/order';
import { required, num } from "@/utils/validate";
import { validatorDefaultCatch } from "@/libs/dialog";
import { isWriteOff } from "@/utils";
export default {
name: "AdminOrderList",
components: {
PriceChange,
Loading
},
props: {},
data: function() {
return {
isWriteOff: isWriteOff(),
current: "",
change: false,
types: 0,
where: {
page: 1,
limit: 10,
status: 'unPaid'
},
list: [],
loaded: false,
loading: false,
orderInfo: {},
status: null
};
},
watch: {
"$route.params.types": function(newVal) {
let that = this;
if (newVal != undefined) {
that.where.status = newVal;
that.init();
}
},
types: function() {
this.getIndex();
}
},
created() {
import('@/assets/js/media_750')
},
mounted() {
this.where.status = this.$route.params.types;
this.current = "";
this.getIndex();
this.$scroll(this.$refs.container, () => {
!this.loading && this.getIndex();
});
},
methods: {
more: function(index) {
if (this.current === index) this.current = "";
else this.current = index;
},
modify: function(item, status) {
this.change = true;
this.orderInfo = item;
this.status = status;
},
changeclose: function(msg) {
this.change = msg;
this.init()
},
// 拒绝退款
getRefuse(id) {
orderRefuseApi(data).then(() =>{
that.change = false;
that.$dialog.success("已拒绝退款");
that.init();
}).catch((error) => {
that.$dialog.error(error.message);
});
},
async savePrice(opt) {
let that = this,
data = {},
price = opt.price,
refundPrice = opt.refundPrice,
refundStatus = that.orderInfo.refundStatus,
remark = opt.remark;
if (that.status == 0 && refundStatus === 0) {
try {
await this.$validator({
price: [
required(required.message("金额"))
]
}).validate({ price });
} catch (e) {
return validatorDefaultCatch(e);
}
data.price = price;
data.orderId = opt.orderId;
editPriceApi(data).then(() =>{
that.change = false;
that.$dialog.success("改价成功");
that.init();
}).catch((error) => {
that.$dialog.error(error.message);
});
} else if (that.status == 0 && refundStatus === 1) {
try {
await this.$validator({
refundPrice: [
required(required.message("金额")),
num(num.message("金额"))
]
}).validate({ refundPrice });
} catch (e) {
return validatorDefaultCatch(e);
}
data.amount = refundPrice;
data.type = opt.type;
data.orderId = opt.orderId;
orderRefundApi(data).then(
res => {
that.change = false;
that.$dialog.success('退款成功');
that.init();
},
err => {
that.change = false;
that.$dialog.error(err.message);
}
);
} else {
try {
await this.$validator({
remark: [required(required.message("备注"))]
}).validate({ remark });
} catch (e) {
return validatorDefaultCatch(e);
}
data.mark = remark;
data.id = opt.id;
orderMarkApi(data).then(
res => {
that.change = false;
that.$dialog.success('提交成功');
that.init();
},
err => {
that.change = false;
that.$dialog.error(err.message);
}
);
}
},
init: function() {
this.list = [];
this.where.page = 1;
this.loaded = false;
this.loading = false;
this.getIndex();
this.current = "";
},
getIndex() {
if (this.loading || this.loaded) return;
this.loading = true;
orderListApi(this.where).then(
res => {
this.loading = false;
this.loaded = res.list.list.length < this.where.limit;
this.list.push.apply(this.list, res.list.list);
this.where.page = this.where.page + 1;
},
err => {
this.$dialog.error(err.message);
}
);
},
changeStatus(val) {
if (this.where.status != val) {
this.where.status = val;
this.init();
}
},
toDetail(item) {
this.$router.push({ path: "/javaMobile/orderDetail/" + item.id });
},
offlinePay(item) {
// setOfflinePay({ order_id: item.order_id }).then(
// res => {
// this.$dialog.success(res.message);
// this.init();
// },
// error => {
// this.$dialog.error(error.message);
// }
// );
}
}
};
</script>
<style scoped lang="scss">
.pos-order-goods{padding:0 0.3rem;background-color: #fff;}
.pos-order-goods .goods{height:1.85rem;}
.pos-order-goods .goods~.goods{border-top:1px dashed #e5e5e5;}
.pos-order-goods .goods .picTxt{width:5.15rem;}
.pos-order-goods .goods .picTxt .pictrue{width:1.3rem;height:1.3rem;}
.pos-order-goods .goods .picTxt .pictrue img{width:100%;height:100%;border-radius:0.06rem;}
.pos-order-goods .goods .picTxt .text{width:3.65rem;height:1.3rem;}
.pos-order-goods .goods .picTxt .text .info{font-size:0.28rem;color:#282828;}
.pos-order-goods .goods .picTxt .text .attr{font-size:0.2rem;color:#999;height: 0.8rem;
line-height: 0.8rem;}
.pos-order-goods .goods .money{width:1.64rem;text-align:right;font-size:0.28rem;height: 1.3rem;}
.pos-order-goods .goods .money .x-money{color:#282828;}
.pos-order-goods .goods .money .num{color:#ff9600;margin:0.05rem 0;}
.pos-order-goods .goods .money .y-money{color:#999;text-decoration:line-through;}
.pos-order-list{background: #f5f5f5;}
.pos-order-list .nav{width:100%;height:0.96rem;background-color:#fff;font-size:0.3rem;color:#282828;position:fixed;top:0;left:0;z-index: 66;}
.pos-order-list .nav .item.on{color:#2291f8;}
.pos-order-list .list{margin-top:0.2rem;}
.pos-order-list .list .item{background-color:#fff;width:100%;}
.pos-order-list .list .item~.item{margin-top:0.24rem;}
.pos-order-list .list .item .order-num{height:1.24rem;border-bottom:1px solid #eee;font-size:0.3rem;font-weight:bold;color:#282828;padding:0 0.3rem;}
.pos-order-list .list .item .order-num .time{font-size:0.26rem;font-weight:normal;color:#999;margin-top: -0.4rem;}
.pos-order-list .list .item .operation{padding:0.2rem 0.3rem;margin-top: 0.03rem;}
.pos-order-list .list .item .operation .more{position:relative;}
.pos-order-list .list .item .operation .icon-gengduo{font-size:0.5rem;color:#aaa;}
.pos-order-list .list .item .operation .order .arrow{width: 0;height: 0;border-left: 0.11rem solid transparent;border-right: 0.11rem solid transparent;border-top: 0.2rem solid #e5e5e5;position:absolute;left: 0.15rem;bottom:-0.18rem;}
.pos-order-list .list .item .operation .order .arrow:before{content:'';width: 0;height: 0;border-left: 0.07rem solid transparent;border-right: 0.07rem solid transparent;border-top: 0.2rem solid #fff;position:absolute;left:-0.07rem;bottom:0;}
.pos-order-list .list .item .operation .order{width:2rem;background-color:#fff;border:1px solid #eee;border-radius:0.1rem;position:absolute;top:-1rem;z-index:9;}
.pos-order-list .list .item .operation .order .items{height:0.77rem;line-height:0.77rem;text-align:center;}
.pos-order-list .list .item .operation .order .items~.items{border-top:1px solid #f5f5f5;}
.pos-order-list .list .item .operation .bnt{font-size:0.28rem;color:#5c5c5c;width:1.7rem;height:0.6rem;border-radius:0.3rem;border:1px solid #bbb;text-align:center;line-height:0.6rem;}
.pos-order-list .list .item .operation .bnt~.bnt{margin-left:0.14rem;}
.public-total{font-size:0.28rem;color:#282828;border-top:1px solid #eee;height:0.92rem;line-height:0.92rem;text-align:right;padding:0 0.3rem;background-color: #fff;}
.public-total .money{color:#ff4c3c;}
</style>

View File

@@ -64,6 +64,9 @@
<el-form-item label="商家备注:">
<span>{{ props.row.remark }}</span>
</el-form-item>
<el-form-item label="核销码:" v-if="props.row.shippingType === 2">
<span>{{ props.row.verifyCode }}</span>
</el-form-item>
</el-form>
</template>
</el-table-column>
@@ -132,9 +135,15 @@
<span>退款原因{{scope.row.refundReasonWap}}</span>
<span>备注说明{{scope.row.refundReasonWapExplain}}</span>
<span>退款时间{{scope.row.refundReasonTime}}</span>
<span>
<span class="acea-row">
退款凭证
<img :src="scope.row.refundReasonWapImg" v-if="scope.row.refundReasonWapImg">
<div class="demo-image__preview" v-if="scope.row.refundReasonWapImg" style="width: 35px;height: auto;display: inline-block;">
<el-image
:src="scope.row.refundReasonWapImg"
:preview-src-list="[scope.row.refundReasonWapImg]"
/>
</div>
<!--<img :src="scope.row.refundReasonWapImg" v-if="scope.row.refundReasonWapImg" >-->
<span v-else style="display: inline-block"></span>
</span>
</div>
@@ -149,7 +158,8 @@
<el-table-column label="操作" min-width="150" fixed="right" align="center">
<template slot-scope="scope">
<el-button v-if="scope.row.paid === false" type="text" size="small" @click="edit(scope.row)" class="mr10">编辑</el-button>
<el-button v-if="scope.row.statusStr.key === 'notShipped'" type="text" size="small" class="mr10" @click="sendOrder(scope.row)">发送货</el-button>
<el-button v-if="scope.row.statusStr.key === 'notShipped' && scope.row.shippingType === 1 && scope.row.refundStatus !==2" type="text" size="small" class="mr10" @click="sendOrder(scope.row)">发送货</el-button>
<el-button v-if="scope.row.shippingType === 2 && scope.row.statusStr.key === 'toBeWrittenOff' && scope.row.paid == true && scope.row.refundStatus === 0 && isWriteOff" type="text" size="small" class="mr10" @click="onWriteOff(scope.row)">立即核销</el-button>
<el-dropdown trigger="click">
<span class="el-dropdown-link">
更多<i class="el-icon-arrow-down el-icon--right" />
@@ -158,8 +168,8 @@
<el-dropdown-item @click.native="onOrderDetails(scope.row.id)">订单详情</el-dropdown-item>
<el-dropdown-item @click.native="onOrderLog(scope.row.id)">订单记录</el-dropdown-item>
<el-dropdown-item @click.native="onOrderMark(scope.row)">订单备注</el-dropdown-item>
<el-dropdown-item v-show="scope.row.statusStr.key === 'refunding'" @click.native="onOrderRefuse(scope.row)">拒绝退款</el-dropdown-item>
<el-dropdown-item v-show="scope.row.statusStr.key === 'refunding'" @click.native="onOrderRefund(scope.row)">立即退款</el-dropdown-item>
<el-dropdown-item v-show="scope.row.status === -1" @click.native="onOrderRefuse(scope.row)">拒绝退款</el-dropdown-item>
<el-dropdown-item v-show="scope.row.statusStr.key === 'refunding' && ((parseFloat(scope.row.payPrice) > parseFloat(scope.row.refundPrice) || (scope.row.payPrice == 0 && [0,1].indexOf(scope.row.refundStatus) !== -1)))" @click.native="onOrderRefund(scope.row)">立即退款</el-dropdown-item>
<el-dropdown-item @click.native="handleDelete(scope.row, scope.$index)">删除订单</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
@@ -274,11 +284,15 @@
</template>
<script>
import { orderListApi, orderUpdateApi, orderLogApi, orderMarkApi, orderDeleteApi, orderRefuseApi, orderRefundApi } from '@/api/order'
import { writeUpdateApi, orderListApi, orderUpdateApi, orderLogApi, orderMarkApi, orderDeleteApi, orderRefuseApi, orderRefundApi } from '@/api/order'
import cardsData from '@/components/cards/index'
import zbParser from '@/components/FormGenerator/components/parser/ZBParser'
import detailsFrom from './orderDetail'
import orderSend from './orderSend'
import { storeStaffListApi } from '@/api/storePoint'
import Cookies from 'js-cookie'
import { fromList } from '@/utils/constants.js'
import { isWriteOff } from "@/utils";
export default {
name: 'orderlistDetails',
components: {
@@ -322,29 +336,29 @@
},
orderChartType: {},
timeVal: [],
fromList: {
title: '选择时间',
custom: true,
fromTxt: [
{ text: '全部', val: '' },
{ text: '今天', val: 'today' },
{ text: '昨天', val: 'yesterday' },
{ text: '最近7天', val: 'lately7' },
{ text: '最近30天', val: 'lately30' },
{ text: '本月', val: 'month' },
{ text: '本年', val: 'year' }
]
},
fromList: fromList,
selectionList: [],
ids: '',
orderids: '',
cardLists: []
cardLists: [],
isWriteOff: isWriteOff()
}
},
mounted() {
this.getList()
},
methods: {
// 核销订单
onWriteOff(row) {
this.$modalSure('核销订单吗').then(() => {
writeUpdateApi(row.verifyCode).then(() => {
this.$message.success('核销成功')
this.tableFrom.status = 'toBeWrittenOff'
this.tableFrom.page = 1
this.getList()
})
})
},
seachList() {
this.tableFrom.page = 1
this.getList()
@@ -532,6 +546,11 @@
</script>
<style lang="scss" scoped>
.demo-table-expand{
/deep/label{
width: 83px !important;
}
}
.refunding{
span{
display: block;

View File

@@ -8,10 +8,10 @@
<div class="description" v-loading="loading">
<div class="title">用户信息</div>
<div class="acea-row">
<div class="description-term">用户昵称{{orderDatalist.realName}}</div>
<div class="description-term">用户昵称{{orderDatalist.user?orderDatalist.user.nickname:orderDatalist.realName}}</div>
<div class="description-term">收货人{{orderDatalist.realName}}</div>
<div class="description-term">联系电话{{orderDatalist.userPhone}}</div>
<div class="description-term">收货地址{{orderDatalist.userAddress}}</div>
<div class="description-term" v-if="orderDatalist.statusStr.key !== 'toBeWrittenOff'">收货地址{{orderDatalist.userAddress}}</div>
</div>
<el-divider></el-divider>
<div class="title">收货信息</div>
@@ -32,6 +32,7 @@
<div class="description-term" v-if="orderDatalist.shippingType === 2 && orderDatalist.statusStr.key === 'notShipped'">门店名称{{orderDatalist.storeName}}</div>
<div class="description-term" v-if="orderDatalist.shippingType === 2 && orderDatalist.statusStr.key === 'notShipped'">核销码{{orderDatalist.user_phone}}</div>
<div class="description-term">商家备注{{orderDatalist.remark}}</div>
<div class="description-term" v-if="orderDatalist.statusStr.key === 'toBeWrittenOff'">提货码{{orderDatalist.verifyCode}}</div>
</div>
<template v-if="orderDatalist.deliveryType === 'express'">
<el-divider></el-divider>

View File

@@ -168,7 +168,6 @@ export default {
this.$refs[name].validate((valid) => {
if (valid) {
registerApi(this.formInline).then(async res => {
console.log(res)
this.$message.success('注册成功')
setTimeout(() => {
this.changelogo()

View File

@@ -7,7 +7,7 @@
<div class="dashboard-workplace-header-tip">
<div class="dashboard-workplace-header-tip-title">{{ smsAccount }}祝您每一天开心</div>
<div class="dashboard-workplace-header-tip-desc">
<span class="mr10">修改密码</span>
<!--<span class="mr10">修改密码</span>-->
<span @click="signOut">退出登录</span>
</div>
</div>

View File

@@ -2,10 +2,11 @@
<div class="divBox">
<el-card class="box-card">
<zb-parser
:form-id="111"
:form-id="formId"
:is-create="isCreate"
:edit-data="editData"
@submit="handlerSubmit"
v-if="isShow"
/>
</el-card>
</div>
@@ -13,21 +14,51 @@
<script>
import zbParser from '@/components/FormGenerator/components/parser/ZBParser'
import { smsSaveApi } from '@/api/sms'
import { configSaveForm, configInfo } from '@/api/systemConfig.js'
export default {
name: "SmsMessage",
components: { zbParser },
data() {
return {
isShow: true,
isCreate: 0,
editData: {}
editData: {},
formId: 111
}
},
mounted() {
this.getFormInfo()
},
methods: {
handlerSubmit(formValue) {
smsSaveApi(formValue).then(data => {
this.$message.success('新增成功')
this.editData = {}
handlerSubmit(data) {
const tempArr = []
for (var key in data) {
const obj = {}
obj.name = key
obj.title = key
obj.value = data[key]
tempArr.push(obj)
}
const _pram = {
'fields': tempArr,
'id': this.formId,
'sort': 0,
'status': true
}
configSaveForm(_pram).then(res => {
this.getFormInfo()
this.$message.success('操作成功')
})
},
// 获取表单详情
getFormInfo() {
configInfo({ id: this.formId }).then(res => {
this.isShow = false
this.editData = res
this.isCreate = 1
setTimeout(() => { // 让表单重复渲染待编辑数据
this.isShow = true
}, 80)
})
}
}

View File

@@ -11,6 +11,13 @@
<el-option value="0" label="不可用"></el-option>
</el-select>
</el-form-item>
<el-form-item label="模板类型:" class="mr10">
<el-select v-model="tableFrom.type" placeholder="请选择" clearable class="filter-item selWidth mr20" @change="userSearchs">
<el-option value="1" label="验证码"></el-option>
<el-option value="2" label="通知"></el-option>
<el-option value="3" label="推广"></el-option>
</el-select>
</el-form-item>
<el-form-item label="模板名称:" class="mr10">
<el-input v-model="tableFrom.title" placeholder="请输入模板名称" class="selWidth">
<el-button slot="append" icon="el-icon-search" @click="userSearchs" />
@@ -136,7 +143,8 @@ export default {
page: 1,
limit: 20,
status: '',
title: ''
title: '',
type: ''
}
}
},

View File

@@ -54,7 +54,7 @@
v-for="(item,index) in formValidate.sliderImages"
:key="index"
class="pictrue"
draggable="false"
draggable="true"
@dragstart="handleDragStart($event, item)"
@dragover.prevent="handleDragOver($event, item)"
@dragenter="handleDragEnter($event, item)"

View File

@@ -143,6 +143,8 @@
title="复制淘宝、天猫、拼多多、京东、苏宁"
:visible.sync="dialogVisible"
width="1200px"
:modal="false"
class="taoBaoModal"
:before-close="handleClose">
<tao-bao v-if="dialogVisible"></tao-bao>
</el-dialog>
@@ -218,7 +220,6 @@ export default {
// 获取商品表单头数量
goodHeade () {
productHeadersApi().then(res => {
console.log(res)
this.headeNum = res
}).catch(res => {
this.$message.error(res.message);
@@ -227,7 +228,6 @@ export default {
// 商户分类;
getCategorySelect() {
categoryApi({ status: -1, type: 1 }).then(res => {
console.log(res)
this.merCateList = res
}).catch(res => {
this.$message.error(res.message)
@@ -277,6 +277,9 @@ export default {
</script>
<style scoped lang="scss">
.taoBaoModal{
z-index: 333 !important;
}
.demo-table-expand{
/deep/ label{
width: 82px;

View File

@@ -144,7 +144,6 @@
modalPicTap (tit) {
const _this = this
_this.$modalUpload(function(img) {
console.log(img)
tit==='1' ? _this.formValidate.avatar = img[0].sattDir : img.map((item) => {
_this.pics.push( item.sattDir)
})
@@ -166,7 +165,6 @@
}, 600);
})
} else {
console.log('error submit!!');
return false;
}
});

View File

@@ -22,7 +22,7 @@
</el-input>
</el-form-item>
<el-form-item label="用户名称:">
<el-select v-model="uids" style="width: 500px" reserve-keyword multiple remote filterable
<el-select v-model="uids" class="selWidth" reserve-keyword multiple remote filterable
:remote-method="remoteMethod" :loading="loading" placeholder="请输入用户名称" clearable @change="seachList">
<el-option
v-for="item in options"

View File

@@ -449,7 +449,7 @@
isBest: 0,
tempId: info.tempId,
attrValue: info.attrValue,
attr: info.attr,
attr: info.attr || [],
selectRule: info.selectRule,
isSub: false,
content: info.content,
@@ -458,9 +458,11 @@
giveIntegral: info.giveIntegral,
ficti: info.ficti
}
if(this.formValidate.attr){
for (var i = 0; i < this.formValidate.attr.length; i++) {
this.formValidate.attr[i].attrValue = JSON.parse(info.attr[i].attrValues)
}
}
this.loading = false;
}).catch(() => {
this.loading = false;

View File

@@ -12,7 +12,7 @@
:biztype="constants.categoryType[4]"
:select-model="true"
:row-select="pram.rules"
:select-model-keys="editData.rules"
:select-model-keys="editData.rules ? editData.rules.split(',') : []"
@rulesSelect="rulesSelect"
/>
</el-form-item>
@@ -38,16 +38,14 @@ export default {
},
editData: {
type: Object,
default: () => {
return { rules: [] }
}
default: null
}
},
data() {
return {
constants,
pram: {
level: 0,
level: 1,
roleName: null,
rules: [],
status: null,
@@ -65,7 +63,7 @@ export default {
initEditData() {
if (this.isCreate !== 1) return
const { level, roleName, rules, status, id } = this.editData
this.pram.rules = rules
this.pram.rules = rules.split(',')
this.pram.level = level
this.pram.roleName = roleName
this.pram.status = status
@@ -94,11 +92,6 @@ export default {
})
},
rulesSelect(selectKeys) {
// let _ids = []
// select.map(item => {
// _ids.push(item.id)
// })
// this.pram.rules = _ids.join(',')
this.pram.rules = selectKeys
}
}

View File

@@ -120,9 +120,7 @@ export default {
})
},
handlerOpenEdit(isCreate, editDate) {
if (isCreate === 1) { editDate.rules = editDate.rules.split(',') }
this.editDialogConfig.editData = editDate
isCreate === 1 ? this.editDialogConfig.editData = editDate : this.editDialogConfig.editData = {}
this.editDialogConfig.isCreate = isCreate
this.editDialogConfig.visible = true
},

View File

@@ -45,7 +45,6 @@ export default {
'sort': 0,
'status': true
}
console.log(_pram)
configSaveForm(_pram).then(res => {
this.getFormInfo()
this.$message.success('操作成功')

View File

@@ -9,22 +9,22 @@
:name="tab.extra"
>
<!-- 文件上传特殊处理-->
<template v-if="activeNamel1 == 4">
<el-radio-group v-model="activeNamel2" class="mb10">
<el-radio v-for="tabItem,itemIndex in tab.child"
:key="itemIndex"
:label="tabItem.name" @change="()=>handleItemTabClick(tabItem.extra)">{{tabItem.name}}</el-radio>
</el-radio-group>
<parser
v-if="formConfChild.render"
:is-edit="formConfChild.isEdit"
:form-conf="formConfChild.content"
:form-edit-data="currentEditData"
@submit="handlerSubmit"
/>
</template>
<!-- <template v-if="activeNamel1 == 4">-->
<!-- <el-radio-group v-model="activeNamel2" class="mb10">-->
<!-- <el-radio v-for="tabItem,itemIndex in tab.child"-->
<!-- :key="itemIndex"-->
<!-- :label="tabItem.name" @change="()=>handleItemTabClick(tabItem.extra)">{{tabItem.name}}</el-radio>-->
<!-- </el-radio-group>-->
<!-- <parser-->
<!-- v-if="formConfChild.render"-->
<!-- :is-edit="formConfChild.isEdit"-->
<!-- :form-conf="formConfChild.content"-->
<!-- :form-edit-data="currentEditData"-->
<!-- @submit="handlerSubmit"-->
<!-- />-->
<!-- </template>-->
<!-- 正常配置渲染-->
<template v-else>
<template>
<el-tabs v-if="tab.child.length > 0" v-model="activeNamel2"
type="border-card" @tab-click="handleItemTabClick">
<el-tab-pane
@@ -92,7 +92,6 @@ export default {
},
methods: {
handleTabClick(tab, event) {
console.log(tab)
if (tab.name) {
this.handlerGetLevel1FormConfig(tab.name)
} else if (tab.$children.length > 0 ) { // 初次加载第二层的第一个Tab数据
@@ -104,7 +103,6 @@ export default {
let _selected = tab.$children[0].panes[0]
// 设置特殊处理的文件长传表单默认选中第一个tab
this.activeNamel2 = _selected.name != 72 ? _selected.name : _selected.label
console.log(this.activeNamel2)
if(this.activeNamel2 == 108){
switch (this.currentSelectedUploadFlag) {
case 1:
@@ -229,7 +227,6 @@ export default {
handleAddArrt(treeData) {
// let _result = this.addTreeListLabel(treeData)
const _result = selfUtil.addTreeListLabel(treeData)
console.log(_result)
return _result
},
buildFormPram(formValue) {

View File

@@ -0,0 +1,147 @@
<template>
<div class="divBox">
<el-card class="box-card">
<div class="acea-row roomBox">
<div class="room-left">
<div class="acea-row room-left-list">
<div class="userHead mr10"><img src="../../../../assets/imgs/mobilehead.png"></div>
<div class="userName">
<span class="sp1" title="小红帽的外婆家">小红帽的外婆家</span>
<span class="sp2">是的你好</span>
</div>
</div>
<div class="acea-row room-left-list">
<div class="userHead mr10"><img src="../../../../assets/imgs/mobilehead.png"></div>
<div class="userName">
<span class="sp1" title="小红帽的外婆家">小红帽的外婆家</span>
<span class="sp2">是的你好</span>
</div>
</div>
<div class="acea-row room-left-list">
<div class="userHead mr10"><img src="../../../../assets/imgs/mobilehead.png"></div>
<div class="userName">
<span class="sp1" title="小红帽的外婆家">小红帽的外婆家</span>
<span class="sp2">是的你好</span>
</div>
</div>
<div class="acea-row room-left-list">
<div class="userHead mr10"><img src="../../../../assets/imgs/mobilehead.png"></div>
<div class="userName">
<span class="sp1" title="小红帽的外婆家">小红帽的外婆家</span>
<span class="sp2">是的你好</span>
</div>
</div>
<div class="acea-row room-left-list">
<div class="userHead mr10"><img src="../../../../assets/imgs/mobilehead.png"></div>
<div class="userName">
<span class="sp1" title="小红帽的外婆家">小红帽的外婆家</span>
<span class="sp2">是的你好</span>
</div>
</div>
<div class="acea-row room-left-list">
<div class="userHead mr10"><img src="../../../../assets/imgs/mobilehead.png"></div>
<div class="userName">
<span class="sp1" title="小红帽的外婆家">小红帽的外婆家</span>
<span class="sp2">是的你好</span>
</div>
</div>
<div class="acea-row room-left-list">
<div class="userHead mr10"><img src="../../../../assets/imgs/mobilehead.png"></div>
<div class="userName">
<span class="sp1" title="小红帽的外婆家">小红帽的外婆家</span>
<span class="sp2">是的你好</span>
</div>
</div>
<div class="acea-row room-left-list">
<div class="userHead mr10"><img src="../../../../assets/imgs/mobilehead.png"></div>
<div class="userName">
<span class="sp1" title="小红帽的外婆家">小红帽的外婆家</span>
<span class="sp2">是的你好</span>
</div>
</div>
<div class="acea-row room-left-list">
<div class="userHead mr10"><img src="../../../../assets/imgs/mobilehead.png"></div>
<div class="userName">
<span class="sp1" title="小红帽的外婆家">小红帽的外婆家</span>
<span class="sp2">是的你好</span>
</div>
</div>
</div>
<div class="room-med"></div>
<div class="room-right"></div>
</div>
</el-card>
</div>
</template>
<script>
export default {
name: "index"
}
</script>
<style scoped lang="scss">
.room{
&-left::-webkit-scrollbar {
display: none; /* Chrome Safari */
}
&-left{
width: 230px;
height: 600px;
border: 1px solid #e6ebf5;
padding: 0 0 15px 15px;
box-sizing: border-box;
scrollbar-width: none; /* firefox */
-ms-overflow-style: none; /* IE 10+ */
overflow-x: hidden;
overflow-y: auto;
&-list{
border-bottom: 1px solid #e6ebf5;
padding-bottom: 15px;
padding: 15px 0;
cursor: pointer;
}
}
&-med{
width: 400px;
height: 600px;
border-top: 1px solid #e6ebf5;
border-bottom: 1px solid #e6ebf5;
}
&-right{
width: 250px;
height: 600px;
border: 1px solid #e6ebf5;
}
}
.userHead{
width: 55px;
height: 55px;
img{
width: 100%;
height: 100%;
border-radius: 4px;
}
}
.userName{
.sp1{
font-size: 15px;
display: block;
width: 118px;
overflow: hidden;
text-overflow:ellipsis;
white-space: nowrap;
}
.sp2{
font-size: 14px;
display: block;
color: #C0C4CC;
margin-top: 21px;
width: 118px;
overflow: hidden;
text-overflow:ellipsis;
white-space: nowrap;
}
}
</style>

View File

@@ -0,0 +1,15 @@
<template>
<div>
<router-view />
</div>
</template>
<script>
export default {
}
</script>
<style lang="sass" scoped>
</style>

View File

@@ -0,0 +1,13 @@
<template>
</template>
<script>
export default {
name: "index"
}
</script>
<style scoped>
</style>

View File

@@ -1,18 +1,9 @@
<template>
<el-dialog v-model="dialogFormVisible" :title="id?'修改核销员':'添加核销员'" :visible.sync="dialogFormVisible" width="750px" @close="cancel">
<el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="150px" class="demo-ruleForm" @submit.native.prevent>
<el-form-item label="商城用户" prop="avatar">
<div class="publicPicBox" @click="upImg">
{{ruleForm.avatar}}
<div class="pictrue" v-if="ruleForm.avatar">
<el-image
:src="ruleForm.avatar"
fit="cover"></el-image>
</div>
<div class="upLoad acea-row row-center-wrapper" v-else>
<i class="el-icon-camera iconfont"></i>
</div>
</div>
<el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="150px" class="demo-ruleForm" @submit.native.prevent v-loading="loading">
<el-form-item label="管理员" prop="uid">
<span v-text="ruleForm.avatar"></span>
<el-button type="primary" size="small" @click="upImg">选择管理员</el-button>
</el-form-item>
<el-form-item label="所属提货点:" prop="storeId">
<el-select v-model="ruleForm.storeId" placeholder="请选择" style="width:50%" clearable>
@@ -25,22 +16,10 @@
</el-select>
</el-form-item>
<el-form-item label="核销员名称:">
<el-input v-model="ruleForm.staffName" placeholder="请输入提货点简介" class="dialogWidth"></el-input>
<el-input v-model="ruleForm.staffName" placeholder="请输入核销员名称" class="dialogWidth"></el-input>
</el-form-item>
<el-form-item label="手机号码:">
<el-input v-model="ruleForm.phone" placeholder="请输入提货点简介" class="dialogWidth"></el-input>
</el-form-item>
<el-form-item label="核销开关:">
<el-radio-group v-model="ruleForm.verifyStatus">
<el-radio :label="1">开启</el-radio>
<el-radio :label="0">关闭</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="状态:">
<el-radio-group v-model="ruleForm.status">
<el-radio :label="1">开启</el-radio>
<el-radio :label="0">关闭</el-radio>
</el-radio-group>
<el-input v-model="ruleForm.phone" placeholder="请输入手机号码" class="dialogWidth"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
@@ -55,6 +34,7 @@
<script>
import customerInfo from '@/components/customerInfo';
import { storeStaffSaveApi, storeStaffUpdateApi, storeStaffInfoApi, storeListApi } from '@/api/storePoint';
import { getStoreStaff } from '@/libs/public'
export default {
name: "addClerk",
components: { customerInfo },
@@ -70,20 +50,19 @@
}
};
return{
loading: false,
dialogFormVisible: false,
id:0,
ruleForm:{
avatar:'',
phone:'',
staffName:'',
status:1,
storeId:'',
verifyStatus:1,
uid:''
uid:'',
avatar: ''
},
name: '',
rules: {
avatar: [
{ required: true, validator: validateUpload, trigger: 'change' }
uid: [
{ required: true, message: '请选择管理员', trigger: 'change' }
],
storeId: [
{ required: true, message: '请选择提货点地址', trigger: 'change' }
@@ -99,9 +78,9 @@
},
methods:{
//接收来自子集的值;
upImgUid(id,img){
this.ruleForm.avatar = img;
this.ruleForm.uid = id;
upImgUid(row){
this.ruleForm.avatar = row.account
this.ruleForm.uid = row.id;
},
upImg(){
this.$refs.customer.dialogFormVisible = true;
@@ -109,12 +88,13 @@
},
//详情
getInfo (id) {
let that = this;
that.id = id;
this.id = id;
this.loading = true
storeStaffInfoApi({id:id}).then(res=>{
that.ruleForm = res;
this.ruleForm = res;
this.loading = false
}).catch(res=>{
this.$message.error(res.message);
this.loading = false
})
},
//取消
@@ -122,14 +102,13 @@
this.dialogFormVisible = false;
this.clearFrom();
this.resetForm('ruleForm');
this.ruleForm.avatar = '';
this.id = 0
},
//数据归为初始状态
clearFrom(){
this.ruleForm.phone = '';
this.ruleForm.staffName = '';
this.ruleForm.status = 1;
this.ruleForm.verifyStatus = 1;
},
//重置
resetForm (name) {
@@ -152,8 +131,7 @@
this.clearFrom();
this.resetForm(name);
this.id = 0;
}).catch(res => {
this.$message.error(res.message);
getStoreStaff()
})
} else {
return false;
@@ -177,8 +155,7 @@
this.clearFrom();
this.resetForm(name);
this.id = 0;
}).catch(res => {
this.$message.error(res.message);
getStoreStaff()
})
} else {
return false;

View File

@@ -34,50 +34,46 @@
<!--label="微信名称"-->
<!--min-width="150">-->
<!--</el-table-column>-->
<el-table-column
prop="avatar"
label="头像"
min-width="100">
<template slot-scope="{ row, index }" class="picMiddle">
<div class="demo-image__preview">
<el-image
style="width: 36px; height: 36px"
:src="row.avatar"
:preview-src-list="[row.avatar]"
/>
</div>
</template>
</el-table-column>
<el-table-column
prop="staffName"
label="核销员名称"
min-width="150">
</el-table-column>
<el-table-column
prop="avatar"
label="账号"
min-width="150">
</el-table-column>
<el-table-column
prop="phone"
label="手机号码"
min-width="100">
</el-table-column>
<el-table-column
prop="systemStore.detailedAddress"
label="所属提货点"
min-width="150">
min-width="200">
</el-table-column>
<el-table-column
prop="createTime"
label="添加时间"
min-width="180">
</el-table-column>
<el-table-column
prop="status"
label="状态"
min-width="100">
<template slot-scope="{ row, index }">
<el-switch
v-model="row.status"
:active-value="1"
:inactive-value="0"
active-text="显示"
inactive-text="隐藏"
@change="onchangeIsShow(row.id,row.status)">
</el-switch>
</template>
</el-table-column>
<!--<el-table-column-->
<!--prop="status"-->
<!--label="状态"-->
<!--min-width="100">-->
<!--<template slot-scope="{ row, index }">-->
<!--<el-switch-->
<!--v-model="row.status"-->
<!--:active-value="1"-->
<!--:inactive-value="0"-->
<!--active-text="显示"-->
<!--inactive-text="隐藏"-->
<!--@change="onchangeIsShow(row.id,row.status)">-->
<!--</el-switch>-->
<!--</template>-->
<!--</el-table-column>-->
<el-table-column
fixed="right"
label="操作"

View File

@@ -3,12 +3,12 @@
<el-card class="box-card">
<div slot="header" class="clearfix">
<div class="container">
<el-form size="small" label-width="100px">
<el-form size="small" label-width="100px" :inline="true" >
<el-form-item label="时间选择:" class="width100">
<el-radio-group v-model="tableFrom.dateLimit" type="button" class="mr20" size="small" @change="selectChange(tableFrom.dateLimit)">
<el-radio-button v-for="(item,i) in fromList.fromTxt" :key="i" :label="item.val">{{ item.text }}</el-radio-button>
</el-radio-group>
<el-date-picker v-model="timeVal" value-format="yyyy/MM/dd" format="yyyy/MM/dd" size="small" type="daterange" placement="bottom-end" placeholder="自定义时间" style="width: 250px;" @change="onchangeTime" />
<el-date-picker v-model="timeVal" value-format="yyyy-MM-dd" format="yyyy-MM-dd" size="small" type="daterange" placement="bottom-end" placeholder="自定义时间" style="width: 250px;" @change="onchangeTime" />
</el-form-item>
<el-form-item label="选择门店:">
<el-select v-model="tableFrom.storeId" clearable filterable placeholder="请选择" class="selWidth" clearable @change="seachList">
@@ -20,7 +20,7 @@
</el-option>
</el-select>
</el-form-item>
<el-form-item label="关键字:" class="width100">
<el-form-item label="关键字:">
<el-input v-model="tableFrom.keywords" placeholder="请输入姓名、电话、订单ID" class="selWidth" size="small">
<el-button slot="append" icon="el-icon-search" size="small" @click="seachList" />
</el-input>
@@ -59,18 +59,20 @@
label="商品信息"
min-width="330"
>
<!--<template slot-scope="scope">-->
<!--<div v-for="(val, i ) in scope.row.productList" :key="i" class="tabBox acea-row row-middle">-->
<!--<div class="demo-image__preview">-->
<!--<el-image-->
<!--:src="val.info.productInfo.image"-->
<!--:preview-src-list="[val.info.productInfo.image]"-->
<!--/>-->
<!--</div>-->
<!--<span class="tabBox_tit">{{ val.info.productInfo.storeName + ' | ' }}{{ val.info.productInfo.attrInfo.sku }}</span>-->
<!--<span class="tabBox_pice">{{ '¥'+ val.info.productInfo.price + ' x '+ val.info }}</span>-->
<!--</div>-->
<!--</template>-->
<template slot-scope="scope">
<div v-if=" scope.row.productList && scope.row.productList.length">
<div v-for="(val, i ) in scope.row.productList" :key="i" class="tabBox acea-row row-middle">
<div class="demo-image__preview">
<el-image
:src="val.info.productInfo.image"
:preview-src-list="[val.info.productInfo.image]"
/>
</div>
<span class="tabBox_tit mr10">{{ val.info.productInfo.storeName + ' | ' }}{{ val.info.productInfo.attrInfo.suk ? val.info.productInfo.attrInfo.suk:'-' }}</span>
<span class="tabBox_pice">{{ '¥'+ val.info.productInfo.attrInfo.price ? val.info.productInfo.attrInfo.price + ' x '+ val.info.cartNum : '-' }}</span>
</div>
</div>
</template>
</el-table-column>
<el-table-column
prop="payPrice"
@@ -100,7 +102,7 @@
min-width="100"
>
<template slot-scope="scope">
<span>{{ scope.row.status | orderStatusFilter }}</span>
<span>{{ scope.row.statusStr.value}}</span>
</template>
</el-table-column>
<el-table-column
@@ -190,7 +192,7 @@
// 具体日期
onchangeTime(e) {
this.timeVal = e
this.tableFrom.dateLimit = e ? this.timeVal.join('-') : ''
this.tableFrom.dateLimit = e ? this.timeVal.join(',') : ''
this.tableFrom.page = 1
this.getList()
},
@@ -231,7 +233,7 @@
}
}
.selWidth{
width: 350px;
width: 300px;
}
.el-dropdown-link {
cursor: pointer;

View File

@@ -1,18 +1,19 @@
<template>
<el-dialog v-model="dialogFormVisible" :title="id?'修改提货点':'添加提货点'" :visible.sync="dialogFormVisible" width="750px" @close="cancel">
<el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="150px" class="demo-ruleForm" @submit.native.prevent>
<template v-if="dialogFormVisible">
<el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="150px" class="demo-ruleForm" @submit.native.prevent v-loading="loading">
<el-form-item label="提货点名称:" prop="name">
<el-input v-model="ruleForm.name" placeholder="请输入提货点名称" class="dialogWidth"></el-input>
<el-input v-model="ruleForm.name" maxlength="40" placeholder="请输入提货点名称" class="dialogWidth"></el-input>
</el-form-item>
<el-form-item label="提货点简介:">
<el-input v-model="ruleForm.introduction" placeholder="请输入提货点简介" class="dialogWidth"></el-input>
<el-input v-model="ruleForm.introduction" maxlength="100" placeholder="请输入提货点简介" class="dialogWidth"></el-input>
</el-form-item>
<el-form-item label="提货点手机号:" prop="phone">
<el-input v-model="ruleForm.phone" placeholder="请输入提货点手机号" class="dialogWidth"></el-input>
</el-form-item>
<el-form-item label="提货点地址:" prop="address">
<el-cascader
class="cascaderW"
class="dialogWidth"
clearable
v-model="ruleForm.address"
:options="addresData"
@@ -45,7 +46,7 @@
</el-form-item>
<el-form-item label="经纬度:" prop="latitude">
<el-tooltip content="请点击查找位置选择位置">
<el-input v-model="ruleForm.latitude" placeholder="请查找位置" class="dialogWidth">
<el-input v-model="ruleForm.latitude" placeholder="请查找位置" class="dialogWidth" readOnly>
<el-button slot="append" @click="onSearch">查找位置</el-button>
</el-input>
</el-tooltip>
@@ -62,6 +63,7 @@
v-bind:src="keyUrl"
></iframe>
</el-dialog>
</template>
</el-dialog>
</template>
@@ -70,9 +72,10 @@
import { cityListTree } from '@/api/logistics';
import { configInfo } from '@/api/systemConfig';
import city from '@/utils/city';
import Templates from "../../../appSetting/wxAccount/wxTemplate/index";
export default {
name: "index",
components: {},
components: {Templates},
// props: {
// children: 'child',
// label: 'name',
@@ -96,6 +99,7 @@
}
};
return {
loading: false,
dialogFormVisible: false,
modalMap: false,
keyUrl: '',
@@ -107,7 +111,7 @@
address: '',
detailedAddress: '',
dayTime: '',
image:'http://admin.crmeb.net/uploads/attach/2020/05/20200515/d8dd47952e638c58c25633fa1009db1c.png',
image:'',
latitude: ''
},
id:0,
@@ -138,6 +142,7 @@
}
},
created(){
this.ruleForm.image = '';
this.addresData = city;
this.getKey();
},
@@ -156,18 +161,19 @@
getInfo (id) {
let that = this;
that.id = id;
this.loading = true;
storeInfoApi({id:id}).then(res=>{
that.ruleForm = res;
that.ruleForm.address = res.address.split(",");
that.dayTime = res.dayTime.split("-")
}).catch(res=>{
this.$message.error(res.message);
this.loading = false;
})
},
//取消
cancel (){
this.dialogFormVisible = false;
this.clearFrom();
this.ruleForm.image = '';
this.resetForm('ruleForm');
this.id = 0
},
@@ -187,8 +193,6 @@
this.clearFrom();
this.resetForm(name);
this.id = 0;
}).catch(res => {
this.$message.error(res.message);
})
} else {
return false;
@@ -207,8 +211,6 @@
this.clearFrom();
this.resetForm(name);
this.id = 0;
}).catch(res => {
this.$message.error(res.message);
})
} else {
return false;
@@ -233,9 +235,7 @@
},
//营业时间
onchangeTime(e){
let start = e[0];
let end = e[1];
this.ruleForm.dayTime = start + '-' + end;
this.ruleForm.dayTime = e ? e.join(',','-') : '';
},
//上传图片
modalPicTap (tit) {
@@ -259,8 +259,6 @@
configInfo(_pram).then(async res => {
let keys = res.tengxun_map_key;
this.keyUrl = `https://apis.map.qq.com/tools/locpicker?type=1&key=${keys}&referer=myapp`;
}).catch(res => {
this.$Message.error(res.message);
})
},
}

View File

@@ -118,7 +118,6 @@
tagId: res.tagId
}
this.labelData = res.tagId.split(',').map(Number)
console.log(this.labelData)
})
},
// 分组列表

Some files were not shown because too many files have changed in this diff Show More