Jelajahi Sumber

Merge branch 'dev'

# Conflicts:
#	src/api/http.js
Funny 2 tahun lalu
induk
melakukan
4ea207f281
93 mengubah file dengan 6346 tambahan dan 17941 penghapusan
  1. 4 0
      babel.config.js
  2. 0 15841
      package-lock.json
  3. 3 1
      package.json
  4. 8 3
      src/App.vue
  5. 15 0
      src/api/http.js
  6. 10 1
      src/api/order.js
  7. 25 1
      src/api/setting.js
  8. 71 0
      src/api/shop.js
  9. 41 11
      src/api/tool.js
  10. 52 0
      src/assets/font/font.css
  11. 0 1
      src/common/LodopFuncs.js
  12. 2 0
      src/common/areadata.js
  13. 5 2
      src/common/qrCode.vue
  14. 90 40
      src/common/sider.vue
  15. 31 28
      src/components/Home.vue
  16. 56 15
      src/components/accountCompoents/consumption.vue
  17. 96 112
      src/components/accountCompoents/coupon.vue
  18. 223 0
      src/components/accountCompoents/couponIndex.vue
  19. 221 0
      src/components/accountCompoents/invalidCoupon.vue
  20. 8 0
      src/components/accountCompoents/recharge.vue
  21. 132 124
      src/components/shopAccount.vue
  22. 354 121
      src/components/accountCompoents/wallet.vue
  23. 4 4
      src/components/about.vue
  24. 98 0
      src/components/help/customerService.vue
  25. 5 5
      src/components/downloadCenter.vue
  26. 135 111
      src/components/set.vue
  27. 190 0
      src/components/help/feedbackInfo.vue
  28. 2 2
      src/components/help.vue
  29. 166 0
      src/components/help/myFeedback.vue
  30. 179 16
      src/components/manualCreate.vue
  31. 393 13
      src/components/orderComponents/orderDetail.vue
  32. 172 87
      src/components/orderComponents/orderList.vue
  33. 155 106
      src/components/orderComponents/orderTrack.vue
  34. 2 14
      src/components/orderComponents/sendOrderPopup.vue
  35. 22 24
      src/components/orderSearch.vue
  36. 265 0
      src/components/platformAccount/index.vue
  37. 79 41
      src/components/addressManagement.vue
  38. 296 104
      src/components/settingComponents/deliverySetting.vue
  39. 2 2
      src/components/pictureManagement.vue
  40. 138 0
      src/components/settingComponents/print.vue
  41. 387 0
      src/components/settingComponents/print/a4Printer.vue
  42. 1086 0
      src/components/settingComponents/print/greetingCardPrinter.vue
  43. 46 23
      src/components/shopCompoents/printerAdd.vue
  44. 302 0
      src/components/settingComponents/print/printerList.vue
  45. 39 0
      src/components/settingComponents/system.vue
  46. 99 267
      src/components/settingComponents/voiceSetting.vue
  47. 146 0
      src/components/settingComponents/waimai.vue
  48. 209 23
      src/components/shopCompoents/bindDelivery.vue
  49. 0 404
      src/components/shopCompoents/bindPrinter.vue
  50. 21 6
      src/components/shopCompoents/bindTakeOut.vue
  51. 3 3
      src/components/shopCompoents/bindUsbPrint.vue
  52. 132 103
      src/components/shopCompoents/shopList.vue
  53. 0 221
      src/components/shopInfo.vue
  54. 2 0
      src/main.js
  55. 76 34
      src/router/index.js
  56. 40 22
      src/views/home.vue
  57. 8 5
      src/views/login.vue
  58. TEMPAT SAMPAH
      static/audio/test.mp3
  59. TEMPAT SAMPAH
      static/image/account-icon.png
  60. TEMPAT SAMPAH
      static/image/delete-icon.png
  61. TEMPAT SAMPAH
      static/image/edit-icon.png
  62. TEMPAT SAMPAH
      static/image/empty-img.png
  63. TEMPAT SAMPAH
      static/image/head-account2.png
  64. TEMPAT SAMPAH
      static/image/head-print2.png
  65. TEMPAT SAMPAH
      static/image/help-icon.png
  66. TEMPAT SAMPAH
      static/image/icon-add.png
  67. TEMPAT SAMPAH
      static/image/icon-big.png
  68. TEMPAT SAMPAH
      static/image/icon-center.png
  69. TEMPAT SAMPAH
      static/image/icon-customer.png
  70. TEMPAT SAMPAH
      static/image/icon-left.png
  71. TEMPAT SAMPAH
      static/image/icon-print.png
  72. TEMPAT SAMPAH
      static/image/icon-reset.png
  73. TEMPAT SAMPAH
      static/image/icon-right.png
  74. TEMPAT SAMPAH
      static/image/icon-small.png
  75. TEMPAT SAMPAH
      static/image/icon_choose.png
  76. TEMPAT SAMPAH
      static/image/invalid-coupon.png
  77. TEMPAT SAMPAH
      static/image/order-icon.png
  78. TEMPAT SAMPAH
      static/image/platform-icon.png
  79. TEMPAT SAMPAH
      static/image/print-icon.png
  80. TEMPAT SAMPAH
      static/image/printer-online-0.png
  81. TEMPAT SAMPAH
      static/image/printer-online-1.png
  82. TEMPAT SAMPAH
      static/image/printer-online-2.png
  83. TEMPAT SAMPAH
      static/image/recharge.png
  84. TEMPAT SAMPAH
      static/image/recharge_coupon.png
  85. TEMPAT SAMPAH
      static/image/setting-icon.png
  86. TEMPAT SAMPAH
      static/image/shop-address.png
  87. TEMPAT SAMPAH
      static/image/shop-contact.png
  88. TEMPAT SAMPAH
      static/image/shop-icon.png
  89. TEMPAT SAMPAH
      static/image/shop-name.png
  90. TEMPAT SAMPAH
      static/image/show-map-icon.png
  91. TEMPAT SAMPAH
      static/image/wallet1.png
  92. TEMPAT SAMPAH
      static/image/wallet2.png
  93. TEMPAT SAMPAH
      static/image/组 2396.png

+ 4 - 0
babel.config.js

@@ -1,5 +1,9 @@
 module.exports = {
   presets: [
     '@vue/cli-plugin-babel/preset'
+  ],
+  plugins: [
+    '@babel/plugin-proposal-optional-chaining',
+    '@babel/plugin-proposal-nullish-coalescing-operator'
   ]
 }

File diff ditekan karena terlalu besar
+ 0 - 15841
package-lock.json


+ 3 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "liebao-web",
-  "version": "0.2.0",
+  "version": "2.0.1",
   "private": true,
   "author": "优巨引擎",
   "description": "有运力的地方,就有猎豹AI。",
@@ -31,6 +31,8 @@
     "vuex": "^3.6.2"
   },
   "devDependencies": {
+    "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.7",
+    "@babel/plugin-proposal-optional-chaining": "^7.16.7",
     "@vue/cli-plugin-babel": "~4.5.0",
     "@vue/cli-plugin-eslint": "~4.5.0",
     "@vue/cli-service": "~4.5.0",

+ 8 - 3
src/App.vue

@@ -30,7 +30,7 @@ export default {
   name: "App",
   data() {
     return {
-      url: "https://pc.liebaoai.cn/audio/test.mp3",
+      url: "https://pc.liebaoai.cn/audio/alone.mp3",
       audioList: [
         "https://pc.liebaoai.cn/audio/new-order.mp3",
         "https://pc.liebaoai.cn/audio/lower-than.mp3",
@@ -78,13 +78,13 @@ export default {
     window.addEventListener("contextmenu", this.rightClick, false);
     // 进来准备关闭新订单提醒声音了
     bus.$on("closeGetSoundMsg", () => {
-      console.log("进来准备关闭新订单提醒声音了");
+      // console.log("进来准备关闭新订单提醒声音了");
       clearInterval(this.timer);
       this.timer = null;
     });
     // 进来准备开启新订单提醒声音了
     bus.$on("openGetSoundMsg", () => {
-      console.log("进来准备开启新订单提醒声音了");
+      // console.log("进来准备开启新订单提醒声音了");
       this.timer = setInterval(() => {
         this.getSoundMsg();
       }, 5000);
@@ -209,4 +209,9 @@ body {
   margin: 0;
   padding: 0;
 }
+.one-line {
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
 </style>

+ 15 - 0
src/api/http.js

@@ -2,6 +2,7 @@ import axios from 'axios';
 import qs from 'qs';
 import { message } from 'element-ui';
 import { config } from '../config.js';
+import packageInfo from "../../package.json";
 import md5 from 'js-md5'
 let appId = process.env.VUE_APP_APPID
 let appSecret = process.env.VUE_APP_APPSECRET
@@ -26,6 +27,7 @@ service.interceptors.request.use(config => {
     'token': token,
     'aliasId': '',
     'platformType': 'pc',
+    'version': packageInfo.version,
     'timeStamp': timeStamp,
     'appId': appId,
     'sign': sign
@@ -118,3 +120,16 @@ export function postJson(url, data = {}) {
   sendObject.data = qs.parse(qs.stringify(data), { arrayFormat: 'brackets' });
   return service(sendObject)
 }
+//上传图片
+export function uploadImg(url, data = {}) {
+  //默认配置
+  let sendObject = {
+    url: requestUrl + url,
+    method: "post",
+    headers: {
+      'Content-Type': 'multipart/form-data'
+    },
+    data: data
+  };
+  return service(sendObject)
+}

+ 10 - 1
src/api/order.js

@@ -115,4 +115,13 @@ export const getAddressList = (params) => {
 // 获取usb自动打印内容
 export const getPrintOrderInfos = (params) => {
   return get('app/order/printOrderInfos', params);
-}
+}
+// 获取物品来源
+export const getResource = (params) => {
+  return get('app/waimai/resource', params);
+}
+// 获取订单详情
+export const getOrderDetail = (params) => {
+  return get('app/order/info', params);
+}
+

+ 25 - 1
src/api/setting.js

@@ -1,4 +1,4 @@
-import { get, post, postJson } from './http.js';
+import { get, post, postJson, uploadImg } from './http.js';
 
 export const getSoundMsg = (params) => {
   return get('app/message/getSoundMsg', params)
@@ -54,3 +54,27 @@ export const defaultAddress = (params) => {
 export const syncFoodImg = (params) => {
   return get('app/waimai/syncFoodImg', params)
 }
+
+// 客服电话
+export const getCustomerPhone = (params) => {
+  return get('app/customerService/deliveryList', params)
+}
+
+//上传图片
+export const uploadFeedbackImg = (params) => {
+  return uploadImg('app/common/upload', params)
+}
+
+// 提交反馈
+export const saveFeedback = (params) => {
+  return post('app/feedback/save', params)
+}
+// 反馈列表 app/feedback/list
+export const getFeedbackList = (params) => {
+  return get('app/feedback/list', params)
+}
+
+// 获取当前最新版本
+export const getVersion = (params) => {
+  return get('app/common/version', params)
+}

+ 71 - 0
src/api/shop.js

@@ -3,10 +3,19 @@ import { get, post, postJson } from './http.js';
 export const getShopList = (params) => {
   return get('app/shop/list', params)
 }
+export const getNewShopList = (params) => {
+  return get('app/shop/listNew', params)
+}
+export const shopListNew = (params) => {
+  return get('app/shop/listSelect', params)
+}
 
 export const getShopDetail = (params) => {
   return get('app/shop/detail', params)
 }
+export const printTest = (params) => {
+  return get('app/order/print/test/waimai', params)
+}
 
 export const shopAdd = (params) => {
   return post('app/shop/add', params)
@@ -198,4 +207,66 @@ export const bindTakeOutNew = (params) => {
 // 外卖平台绑定门店更换
 export const bindChangeShop = (params) => {
   return post('app/waimai/changeShop', params)
+}
+
+// 获取平台账号
+export const getAccountList = (params) => {
+  return get('app/shop/user/list', params)
+}
+
+// 删除平台账号
+export const deletePlatformAccount = (params) => {
+  return post('app/shop/user/delete', params)
+}
+// 新增平台账号
+export const addPlatformAccount = (params) => {
+  return post('app/shop/user/add', params)
+}
+// 修改平台账号
+export const modifyPlatformAccount = (params) => {
+  return post('app/shop/user/modify', params)
+}
+
+// 获取云盒打印机信息
+export const getCloudDevice = (params) => {
+  return get('app/shop/device/getCloudDevice', params)
+}
+
+// 云盒打印
+export const cloudPrint = (params) => {
+  return post('app/order/print/card', params)
+}
+
+// 云盒配置列表
+export const cloudConfigList = (params) => {
+  return get('app/shop/cloud/card/list', params)
+}
+
+// 新增、编辑云盒配置
+export const cloudConfigAdd = (params) => {
+  return postJson('app/shop/cloud/card/add', params)
+}
+// 获取门店打印配置
+export const printConfig = (params) => {
+  return get('app/shop/cloud/card/getDevice', params)
+}
+
+// 绑定曹操送
+export const bindCCS = (params) => {
+  return post('app/deliveryBind/bindCaocaoSong', params)
+}
+
+// 绑定快跑者
+export const bindKPZ = (params) => {
+  return post('app/deliveryBind/keloop', params)
+}
+
+// 裹小递绑定获取验证码
+export const gxdCode = (params) => {
+  return post('app/deliveryBind/sendGxdCode', params)
+}
+
+// 绑定裹小递
+export const bindGXD = (params) => {
+  return post('app/deliveryBind/bindGxd', params)
 }

+ 41 - 11
src/api/tool.js

@@ -1,4 +1,42 @@
+/**
+ * 是否数组
+ */
+function isArray(value) {
+  if (typeof Array.isArray === 'function') {
+    return Array.isArray(value)
+  }
+  return Object.prototype.toString.call(value) === '[object Array]'
+}
+/**
+ * @description 深度克隆
+ * @param {object} obj 需要深度克隆的对象
+ * @returns {*} 克隆后的对象或者原值(不是对象)
+ */
+function deepClone(obj) {
+  // 对常见的“非”值,直接返回原来值
+  if ([null, undefined, NaN, false].includes(obj)) return obj
+  if (typeof obj !== 'object' && typeof obj !== 'function') {
+    // 原始类型直接返回
+    return obj
+  }
+  const o = isArray(obj) ? [] : {}
+  for (const i in obj) {
+    if (obj.hasOwnProperty(i)) {
+      o[i] = typeof obj[i] === 'object' ? deepClone(obj[i]) : obj[i]
+    }
+  }
+  return o
+}
+/**
+ * 验证手机格式
+ */
+function mobile(value) {
+  return /^1[23456789]\d{9}$/.test(value)
+}
 export default {
+  isArray,
+  deepClone,
+  mobile,
   /**
    * fun 需要防抖的方法
    * delay 最小抖动间隔
@@ -96,15 +134,6 @@ export default {
   },
 
   eosFormatTime2(oldTimes1, disparityTime) {
-    // let time1 = oldTimes1.split(" ");
-    // let time2 = time1[1].split(":");
-    // let time3 = time1[0].split("-");
-    // if (disparityTime % 1 === 0) {
-    //   return `${time3[1]}-${time3[2]} ${time2[0] - disparityTime}:00`;
-    // } else {
-    //   return `${time3[1]}-${time3[2]} ${time2[0] -
-    //     Math.ceil(disparityTime)}:30`;
-    // }
     var date = new Date(oldTimes1)
     let newDate = date - disparityTime * 60 * 60 * 1000
     let showDate = this.getFormatDate(newDate, 'MM-dd hh:mm:ss')
@@ -134,5 +163,6 @@ export default {
     else if (_min >= 1) result = "" + parseInt(_min) + "分钟";
     else result = "1分钟";
     return result;
-  }
-};
+  },
+
+}

+ 52 - 0
src/assets/font/font.css

@@ -0,0 +1,52 @@
+@font-face {
+  font-family: "FangZhengKaiTi";
+  src: url('https://h5.liebaoai.cn/font/FangZhengKaiTi.woff2');
+  font-weight: normal;
+  font-style: normal;
+}
+
+@font-face {
+  font-family: "HongLeiBanShu";
+  src: url('https://h5.liebaoai.cn/font/HongLeiBanShu.woff2');
+  font-weight: normal;
+  font-style: normal;
+}
+@font-face {
+  font-family: "KaTongTi";
+  src: url('https://h5.liebaoai.cn/font/KaTongTi.woff2');
+  font-weight: normal;
+  font-style: normal;
+}
+@font-face {
+  font-family: "PinRu";
+  src: url('https://h5.liebaoai.cn/font/PinRu.woff2');
+  font-weight: normal;
+  font-style: normal;
+}
+@font-face {
+  font-family: "QianTuBiFengShouXieTi";
+  src: url('https://h5.liebaoai.cn/font/QianTuBiFengShouXieTi.woff2');
+  font-weight: normal;
+  font-style: normal;
+}
+
+@font-face {
+  font-family: "slideyouran";
+  src: url('https://h5.liebaoai.cn/font/slideyouran.woff2');
+  font-weight: normal;
+  font-style: normal;
+}
+
+@font-face {
+  font-family: "YaoSuiXinShouXieTi";
+  src: url('https://h5.liebaoai.cn/font/YaoSuiXinShouXieTi.woff2');
+  font-weight: normal;
+  font-style: normal;
+}
+
+@font-face {
+  font-family: "ZhongQiZhiXingShu";
+  src: url('https://h5.liebaoai.cn/font/ZhongQiZhiXingShu.woff');
+  font-weight: normal;
+  font-style: normal;
+}

+ 0 - 1
src/common/LodopFuncs.js

@@ -145,7 +145,6 @@ export function getLodop(oOBJECT, oEMBED, fitstLogin = false) {
         }
         //===如下空白位置适合调用统一功能(如注册语句、语言选择等):==
         LODOP.SET_LICENSES("", "A4A7A0A3BA53E8548E00D14D5864728D8EA", "", "");
-        //=======================================================
         return LODOP;
     } catch (err) {
         alert("getLodop出错:" + err);

File diff ditekan karena terlalu besar
+ 2 - 0
src/common/areadata.js


+ 5 - 2
src/common/qrCode.vue

@@ -15,10 +15,10 @@
       <div class="code-bottom">
         <div id="qrcode" ref="qrcode" class="code-img"></div>
         <div class="des">请使用手机打开{{ paymentType == 1 ? '支付宝' : '微信' }}扫描二维码完成支付</div>
-        <!-- <div class="guo-qi">
+        <div class="guo-qi">
           <span @click.stop="refreshCode()">点击刷新</span>
           重新获取二维码
-        </div> -->
+        </div>
       </div>
     </div>
   </el-dialog>
@@ -113,6 +113,9 @@ export default {
 
 <style lang="scss" scoped>
 .pay-dialog {
+  /deep/ .el-dialog {
+    border-radius: 10px;
+  }
   /deep/ .el-dialog__header {
     padding: 0;
   }

+ 90 - 40
src/common/sider.vue

@@ -1,15 +1,14 @@
 <template>
-  <el-aside style="width: 254px;">
+  <el-aside>
     <div class="sidebar">
       <div class="side-logo">
         <img @click="$router.push({path:'/'})" src="../../static/image/logo.png" class="logo" />
       </div>
-      <el-menu class="sidebar-el-menu" :default-active="$route.path" :collapse="collapse" background-color="#00152A" text-color="#bfcbd9" active-text-color="#20a0ff" router>
+      <el-menu class="sidebar-el-menu" :default-active="$route.path" :collapse="collapse" background-color="#00152A" text-color="#FFFFFF" active-text-color="#FC7200" router>
         <template v-for="item in items">
           <template v-if="item.children">
             <el-submenu :index="item.path" :key="item.path">
               <template slot="title">
-                <!-- <i :class="[item.icon,'aliFamily']"></i> -->
                 <img v-if="item.icon" class="side-bar-icon" :src="item.icon" />
                 <span slot="title">{{ item.title }}</span>
               </template>
@@ -25,7 +24,6 @@
           </template>
           <template v-else>
             <el-menu-item :index="item.path" :key="item.path">
-              <!-- <i :class="[item.icon,'aliFamily']"></i> -->
               <img :src="item.icon" class="side-bar-icon" v-if="item.icon" />
               <span slot="title">{{ item.title }}</span>
             </el-menu-item>
@@ -47,7 +45,6 @@ export default {
       items: [
         {
           path: "/",
-          name: "home",
           title: "一键发单",
           icon: require("../../static/image/order-icon.png"),
           children: [
@@ -70,62 +67,113 @@ export default {
         },
         {
           path: "/shopInfo",
-          name: "shopInfo",
           title: "商户信息",
           icon: require("../../static/image/shop-icon.png"),
           children: [
             {
-              path: "/shopInfo/shopInfos",
-              name: "shopInfos",
-              title: "门店管理",
+              path: "/shop/shopList",
+              name: "shopList",
+              title: "我的店铺",
             },
             {
-              path: "/shopInfo/shopAccount",
-              name: "shopInfos",
-              title: "我的账户",
+              path: "/platformAccount/index",
+              name: "platformAccount",
+              title: "账号管理",
             },
           ],
         },
         {
-          path: "/setUp",
-          name: "setUp",
-          title: "设置",
-          icon: require("../../static/image/setting-icon.png"),
+          path: "/account",
+          title: "我的账户",
+          icon: require("../../static/image/account-icon.png"),
           children: [
             {
-              path: "/setUp/set",
-              name: "set",
-              title: "外卖设置",
+              path: "/account/wallet",
+              name: "wallet",
+              title: "我的钱包",
             },
             {
-              path: "/setUp/addressManagement",
-              name: "addressManagement",
-              title: "常用地址",
+              path: "/account/walletDetail",
+              name: "walletDetail",
+              title: "收支明细",
             },
             {
-              path: "/setUp/pictureManagement",
-              name: "pictureManagement",
-              title: "商品管理",
+              path: "/account/coupon",
+              name: "coupon",
+              title: "优惠券",
             },
           ],
         },
         {
-          path: "/help",
-          name: "help",
-          title: "帮助中心",
-          icon: require("../../static/image/help-icon.png"),
+          path: "/platform",
+          title: "平台管理",
+          icon: require("../../static/image/platform-icon.png"),
+          children: [
+            {
+              path: "/platform/bindTakeOut",
+              name: "bindTakeOut",
+              title: "绑定外卖平台",
+            },
+            {
+              path: "/platform/bindDelivery",
+              name: "bindDelivery",
+              title: "绑定配送平台",
+            },
+          ],
         },
         {
-          path: "/download",
-          name: "download",
-          title: "下载中心",
-          icon: require("../../static/image/download-icon.png"),
+          path: "/set",
+          title: "设置中心",
+          icon: require("../../static/image/setting-icon.png"),
+          children: [
+            {
+              path: "/set/waimai",
+              name: "waimai",
+              title: "外卖设置",
+            },
+            {
+              path: "/set/print",
+              name: "print",
+              title: "打印设置",
+            },
+            // {
+            //   path: "/set/system",
+            //   name: "system",
+            //   title: "系统设置",
+            // }
+          ],
         },
         {
-          path: "/about",
-          name: "about",
-          title: "关于我们",
-          icon: require("../../static/image/about-icon.png"),
+          path: "/help",
+          title: "帮助中心",
+          icon: require("../../static/image/help-icon.png"),
+          children: [
+            {
+              path: "/help/commonProblem",
+              name: "commonProblem",
+              title: "常见问题",
+            },
+            {
+              path: "/help/customerService",
+              name: "customerService",
+              title: "客服中心",
+            },
+            {
+              path: "/help/download",
+              name: "download",
+              title: "下载中心",
+            },
+            {
+              path: "/help/feedback",
+              name: "feedback",
+              title: "意见反馈",
+            },
+            {
+              path: "/help/about",
+              name: "about",
+              title: "关于我们",
+            },
+          ],
         },
       ],
     };
@@ -165,9 +213,11 @@ export default {
   padding-left: 76px !important;
 }
 /deep/ .el-menu-item.is-active {
-  color: #fff !important;
   background-color: #0c2b47 !important;
-  border-right: 6px solid #009cff;
+  border-right: 4px solid #fc7200;
+}
+/deep/ .el-submenu .el-submenu__title {
+  font-size: 15px !important;
 }
 .sidebar {
   display: block;
@@ -186,7 +236,7 @@ export default {
   position: absolute;
   top: 0;
   left: 0;
-  z-index: 400;
+  z-index: 2;
   background-color: #fff;
   font-size: 0;
   padding-left: 32px;

+ 31 - 28
src/components/Home.vue

@@ -18,26 +18,16 @@
               <el-option v-for="i in shopList" :key="i.id" :label="i.name" :value="i.id"></el-option>
             </el-select>
           </div>
-          <!-- <div class="inp-content">
-            <span>订单来源</span>
-            <el-select size="small" v-model="form.searchKeyType" slot="prepend" placeholder="请选择关键字">
-              <el-option label="流水号" value="1"></el-option>
-            </el-select>
-          </div> -->
-
           <el-input size="small" class="inp input-with-select" v-model="params.searchKey" placeholder="请输入关键字" @keydown.enter.native="seachEnterFun" clearable>
             <el-select v-model="params.searchKeyType" slot="prepend" placeholder="请选择关键字">
               <el-option label="流水号" value="1"></el-option>
               <el-option label="手机号" value="2"></el-option>
               <el-option label="姓名" value="3"></el-option>
               <el-option label="地址" value="4"></el-option>
-              <!-- <el-option label="订单号" value="5"></el-option> -->
               <el-option label="外卖订单号" value="6"></el-option>
             </el-select>
           </el-input>
           <el-button size="small" style="background: #0D1E40;color:#fff" type="info" @click.stop="search" slot="append" icon="el-icon-search"></el-button>
-          <!-- 1.0.0版本暂不开发该功能 -->
-          <!-- <el-button class="btn" size='small' @click="$router.push({path:'/manualCreate'})">手动发单</el-button> -->
         </div>
       </el-col>
     </el-row>
@@ -62,12 +52,10 @@
 import bus from "../common/bus.js";
 import sendOrderPopup from "./orderComponents/sendOrderPopup.vue";
 import OrderList from "./orderComponents/orderList.vue";
-import {
-  getOrderList,
-  getOrderMarker,
-  getRefreshOrder,
-} from "../api/order.js";
-import { getShopList } from "../api/shop";
+import { getOrderList, getOrderMarker, getRefreshOrder } from "../api/order.js";
+import { getShopList } from "../api/shop.js";
+import { getVersion } from "../api/setting.js";
+import config from "../../package.json";
 export default {
   name: "HomeIndex",
   data() {
@@ -107,12 +95,12 @@ export default {
           status: -2,
         },
         {
-          name: "取消",
+          name: "完成/取消",
           num: 0,
-          status: -1,
+          status: 93,
         },
         {
-          name: "近三日订单",
+          name: "全部",
           num: 0,
           status: 94,
         },
@@ -132,6 +120,7 @@ export default {
       markerNum: "",
       clickBool: false,
       timer: null,
+      timer1: null,
       timer2: null,
       shopList: [],
     };
@@ -168,18 +157,31 @@ export default {
         this.getRefreshOrder();
       }
     }, 5000);
+    this.timer1 = setInterval(() => {
+      this.checkUpdate();
+    }, 10000);
   },
   mounted() {},
   beforeDestroy() {
     clearInterval(this.timer);
     this.timer = null;
+    clearInterval(this.timer1);
+    this.timer1 = null;
   },
   destroyed() {
     bus.$off("pullData");
     bus.$off("refreshData");
   },
   methods: {
-   
+    checkUpdate() {
+      getVersion({ type: 3 }).then((res) => {
+        if (!res.data) return;
+        let version = res.data.name;
+        if (version !== config.version) {
+          window.location.reload();
+        }
+      });
+    },
     changeShopIds() {
       this.params.searchShopIdStr = String(this.searchShopIdStr);
       localStorage.setItem("searchShopIdStr", this.params.searchShopIdStr);
@@ -222,13 +224,6 @@ export default {
       }
     },
     search() {
-      // this.$router.push({
-      //   path: "/orderSearch",
-      //   query: {
-      //     searchKey: this.searchKey,
-      //   },
-      // });
-      //
       if (!this.params.searchKey) {
         this.params.pageNum = 1;
         this.orderList = [];
@@ -319,7 +314,8 @@ export default {
       });
     },
     getRefreshOrder() {
-      if (this.params.status === 94) {
+      let noRefresh = [93, 94];
+      if (noRefresh.includes(this.params.status)) {
         return;
       }
       let orderIds = this.orderList.map((v) => {
@@ -383,6 +379,13 @@ export default {
 </script>
 
 <style lang="scss" scoped="scoped">
+/deep/ .el-pagination.is-background .el-pager li:not(.disabled).active {
+  background-color: #fc7200;
+  color: #fff !important;
+}
+/deep/ .el-pagination.is-background .el-pager li:hover:not(.disabled) {
+  color: #fc7200;
+}
 /deep/ .el-input__inner {
   padding-right: 30px;
 }

+ 56 - 15
src/components/accountCompoents/consumption.vue

@@ -9,6 +9,12 @@
               <el-option v-for="(v,i) in shopList" :key="i" :label="v.name" :value="v.shopId"></el-option>
             </el-select>
           </div>
+          <div class="sel_item">
+            <span class="name">类型:</span>
+            <el-select size="small" class="item1" v-model="params.source" placeholder="请选择收入/支出">
+              <el-option v-for="(v,i) in consumptionList" :key="i" :label="v.name" :value="v.consumptionId"></el-option>
+            </el-select>
+          </div>
           <div class="sel_item sel_item2">
             <span class="name">日期:</span>
             <el-date-picker size="small" v-model="value1" class="item3" type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" :picker-options="pickerOptions">
@@ -29,7 +35,11 @@
         </el-table-column>
         <el-table-column prop="orderSn" label="平台订单号" min-width="120px"></el-table-column>
         <el-table-column prop="createTime" label="消费时间" min-width="110px"></el-table-column>
-        <el-table-column prop="remark" label="用途" min-width="100px"></el-table-column>
+        <el-table-column prop="remark" label="用途" min-width="100px">
+          <template slot-scope="scope">
+            <div :style="{color:scope.row.type===1?'#d81e06':'#46BB36'}">{{scope.row.remark}}</div>
+          </template>
+        </el-table-column>
         <el-table-column prop="" label="支付方式">
           <template slot-scope="scope">
             <div>{{showPayMent(scope.row.paymentType)}}</div>
@@ -54,12 +64,27 @@
 import { getAccountFlow } from "../../api/amount.js";
 import { getShopList } from "../../api/shop.js";
 export default {
+  name: "consumption",
   data() {
     return {
       flowList: [],
       shopList: [],
+      consumptionList: [
+        {
+          consumptionId: "",
+          name: "全部",
+        },
+        {
+          consumptionId: 1,
+          name: "收入",
+        },
+        {
+          consumptionId: 2,
+          name: "支出",
+        },
+      ],
       params: {
-        source: 2,
+        source: "",
         pageNum: 1,
         pageSize: 10,
         shopId: "",
@@ -181,45 +206,54 @@ export default {
         }
       });
     },
-    showType(type){
+    showType(type) {
       let name;
       switch (type) {
         case 1:
-          name="美团"
+          name = "美团";
           break;
         case 2:
-          name="饿了么"
+          name = "饿了么";
           break;
         case 3:
-          name="饿百"
+          name = "饿百";
+          break;
+         case 4:
+          name = "山塘";
+          break;
+         case 5:
+          name = "美团闪购";
+          break;
+         case 6:
+          name = "京东到家";
           break;
         case 99:
-          name="手动发单"
+          name = "手动发单";
           break;
-      
+
         default:
-          name= '--'
+          name = "--";
           break;
       }
-      return name
+      return name;
     },
     showPayMent(type) {
       let name;
       switch (type) {
         case 1:
-          name= '支付宝支付'
+          name = "支付宝支付";
           break;
         case 2:
-          name= '微信支付'
+          name = "微信支付";
           break;
         case 3:
-          name= '银联支付'
+          name = "银联支付";
           break;
         case 4:
-          name= '余额支付'
+          name = "余额支付";
           break;
         case 5:
-          name= '三方运力支付'
+          name = "三方运力支付";
           break;
 
         default:
@@ -233,6 +267,13 @@ export default {
 </script>
 
 <style lang="scss" scoped>
+/deep/ .el-pagination.is-background .el-pager li:not(.disabled).active {
+  background-color: #fc7200;
+  color: #fff !important;
+}
+/deep/ .el-pagination.is-background .el-pager li:hover:not(.disabled) {
+  color: #fc7200;
+}
 /deep/ .el-table td.el-table__cell {
   text-align: center !important;
 }

+ 96 - 112
src/components/accountCompoents/coupon.vue

@@ -1,143 +1,127 @@
 <template>
-  <div class="coupon">
-    <div class="list">
-      <div class="item" v-for="(v,i) in couponList" :key="i">
-        <div class="top-content">
-          <div class="money" v-if="v.type === 1">
-            <span class="samll-size">¥</span>
-            <span class="big-size">{{v.money}}</span>
+  <div class="shopInfo">
+    <el-row class="order_tab">
+      <el-col :span="24">
+        <div class="tabList">
+          <div class="tab_item" @click="changeTabs(i)" :class="{'tab_item_ac':tabNum==i?true:false}" v-for="(item,i) in tabList" :key="i">
+            <span class="item" :class="tabNum==i?'active-item':''" v-if="!item.children">{{item.name}}</span>
+            <el-dropdown v-else @command="chooseCoupon">
+              <span class="el-dropdown-link item" :class="tabNum==i?'active-item':''">
+                {{item.name}}<i class="el-icon-arrow-down el-icon--right"></i>
+              </span>
+              <el-dropdown-menu slot="dropdown">
+                <el-dropdown-item :command="v.command" v-for="(v,index) in item.children" :key="index">{{v.name}}</el-dropdown-item>
+              </el-dropdown-menu>
+            </el-dropdown>
+            <div class="tab_line"></div>
           </div>
-          <div class="money" v-if="v.type === 2">
-            <span class="big-size">{{v.discount}}</span>
-            <span class="samll-size">折</span>
-          </div>
-          <div class="man-jian" v-if="v.type === 2">最高可减{{v.maxDiscount}}元</div>
-          <div class="man-jian" v-if="v.type === 1">{{v.name}}</div>
-          <div class="time">{{v.validStartTime}} - {{v.validEndTime}}</div>
         </div>
-        <div class="bottom">
-          <div class="lei-xing">
-            类型:<span>{{v.type === 1 ? '满减劵' : '折扣券'}}</span>
-          </div>
-          <div class="lei-xing">
-            数量:<span>{{Number(v.num)}}张</span>
-          </div>
-        </div>
-      </div>
-    </div>
-    <div style="text-align: center;margin-top: 20px;">
-      <el-pagination :current-page.sync="params.pageNum" @size-change="handleSizeChange" @current-change="handleCurrentChange" :page-sizes="[10, 20, 50, 100]" :page-size="params.pageSize" layout="total, sizes, prev, pager, next, jumper" :total="total" background>
-      </el-pagination>
-    </div>
+      </el-col>
+    </el-row>
+    <el-row class="content">
+      <component v-if="renderComponent" :is="activeName"></component>
+    </el-row>
   </div>
 </template>
 
 <script>
-import { getCouponList, getCouponExplain } from "../../api/amount.js";
-import tool from '../../api/tool.js'
+import couponIndex from "./couponIndex.vue";
+import invalidCoupon from "./invalidCoupon.vue";
+
 export default {
+  name: "coupon",
+  components: {
+    couponIndex,
+    invalidCoupon,
+  },
   data() {
     return {
-      couponList: [],
-      params: {
-        pageNum: 1,
-        pageSize: 10,
-      },
-      total: 0,
+      activeName: "couponIndex",
+      tabList: [
+        { name: "我的优惠券", index: 0, activeName: "couponIndex" },
+        { name: "已过期", index: 1, activeName: "invalidCoupon" },
+      ],
+      tabNum: 0,
+      renderComponent: true,
     };
   },
   created() {
-    this.getCouponList();
+    this.changeTabs(0);
   },
   methods: {
-    handleSizeChange(val) {
-      this.params.pageNum = 1;
-      this.params.pageSize = val;
-      this.couponList = [];
-      this.getCouponList();
-    },
-    handleCurrentChange(val) {
-      this.params.pageNum = val;
-      this.couponList = [];
-      this.getCouponList();
-    },
-    getCouponList() {
-      getCouponList({ status: 0, isNew: 1 }).then((res) => {
-        if (res.code === 200) {
-          this.couponList = res.data.data.map(v=>{
-            v.validStartTime = tool.getFormatDate(new Date(v.validStartTime),'yyyy.MM.dd')
-            v.validEndTime = tool.getFormatDate(new Date(v.validEndTime),'yyyy.MM.dd')
-            return v
-          });
-          this.total = res.data.totalNums || 0;
-        } else {
-          this.$message({
-            type: "error",
-            message: res.msg,
-          });
-        }
+    forceRerender() {
+      // 从 DOM 中删除 my-component 组件
+      this.renderComponent = false;
+      this.$nextTick(() => {
+        // 在 DOM 中添加 my-component 组件
+        this.renderComponent = true;
       });
     },
+    changeTabs(i) {
+      if (i === this.tabNum) {
+        this.forceRerender();
+        return;
+      }
+      this.tabNum = i;
+      this.activeName = this.tabList[i].activeName;
+    },
   },
 };
 </script>
 
-<style lang="scss" scoped>
-.coupon {
-  height: calc(100vh - 274px);
-  background-color: #fff;
-  .list {
-    display: flex;
-    flex-wrap: wrap;
-    .item {
-      margin-right: 20px;
-      .top-content {
-        width: 244px;
-        height: 166px;
-        background: url(../../../static/image/coupon-bg.png) no-repeat;
-        background-size: cover;
-        text-align: center;
-        box-sizing: border-box;
-        padding: 30px;
-        .money {
-          font-family: PingFang SC;
-          font-weight: 600;
-          color: #ffffff;
-          .samll-size {
-            font-size: 22px;
-          }
-          .big-size {
-            font-size: 40px;
-          }
+<!-- Add "scoped" attribute to limit CSS to this component only -->
+<style scoped lang="scss">
+.shopInfo {
+  .order_tab {
+    width: 100%;
+    height: 74px;
+    background: #fff;
+
+    .tabList {
+      width: 100%;
+      height: 74px;
+      padding-top: 20px;
+      padding-left: 36px;
+      box-sizing: border-box;
+      display: flex;
+
+      .tab_item {
+        min-width: 58px;
+        margin-right: 56px;
+        .item {
+          font-size: 16px;
+          font-weight: 500;
+          color: #b1b1b1;
+          position: relative;
+          text-align: center;
+          cursor: pointer;
         }
-        .man-jian {
-          font-size: 14px;
-          font-family: PingFang SC;
-          font-weight: 400;
-          color: #ffffff;
+        .active-item {
+          color: #fc7200;
         }
-        .time {
-          font-size: 12px;
-          font-family: PingFang SC;
-          font-weight: 400;
-          color: #28888a;
-          margin-top: 30px;
+        .tab_line {
+          width: 58px;
+          height: 6px;
+          background: #fff;
+          border-radius: 3px;
+          margin: 15px auto 0;
         }
       }
-      .bottom {
-        padding: 10px;
-        .lei-xing {
-          font-size: 12px;
-          font-family: PingFang SC;
-          font-weight: 400;
-          color: #666666;
-          margin-bottom: 4px;
-          span {
-            color: #999;
-          }
+
+      .tab_item_ac {
+        color: #fc7200;
+
+        .tab_line {
+          background: #fc7200;
         }
       }
     }
   }
+
+  .content {
+    width: 100%;
+    margin-top: 10px;
+    box-sizing: border-box;
+  }
 }
 </style>

+ 223 - 0
src/components/accountCompoents/couponIndex.vue

@@ -0,0 +1,223 @@
+<template>
+  <div class="coupon">
+    <div class="recharge_coupon_bottom" v-if="couponList.length">
+      <div class="recharge_coupon_bottom_item" v-for="(item,index) in couponList" :key="index">
+        <div class="recharge_coupon_bottom_left">
+          <div class="recharge_coupon_bottom_left_num">
+            <span v-if="item.type == 1 || item.type == 3">¥</span>
+            <span class="num" v-if="item.type == 1 || item.type == 3">{{item.money}}</span>
+            <span class="num" v-if="item.type == 2">{{item.discount}}</span>
+            <span v-if="item.type == 2">折</span>
+          </div>
+          <div class="recharge_coupon_bottom_sub">
+            <span v-if="item.type == 2">最高减{{ item.maxDiscount }}元</span>
+            <span v-if="item.type == 1">满{{ item.limitFee }}元可用</span>
+          </div>
+        </div>
+        <div class="recharge_coupon_bottom_middle">
+          <div></div>
+        </div>
+        <div class="recharge_coupon_bottom_right">
+          <div class="recharge_coupon_bottom_date">
+            <div>{{item.name}}</div>
+            <div>有效期:{{item.validStartTime}} - {{item.validEndTime}}</div>
+          </div>
+          <div class="recharge_coupon_bottom_number">
+            <span>x{{item.num}}张</span>
+          </div>
+        </div>
+      </div>
+    </div>
+    <el-empty v-else style="padding-top:10%;" description="暂无可用优惠券"></el-empty>
+  </div>
+</template>
+
+<script>
+import { getCouponList, getCouponExplain } from "../../api/amount.js";
+import tool from "../../api/tool.js";
+export default {
+  name: "couponIndex",
+  data() {
+    return {
+      couponList: [],
+      params: {
+        pageNum: 1,
+        pageSize: 10,
+      },
+      total: 0,
+    };
+  },
+  created() {
+    this.getCouponList();
+  },
+  methods: {
+    showType(type) {
+      let name = "";
+      // v.type === 1 ? '满减劵' : '折扣券'
+      switch (type) {
+        case 1:
+          name = "满减劵";
+          break;
+        case 2:
+          name = "折扣券";
+          break;
+        case 3:
+          name = "立减劵";
+          break;
+        default:
+          break;
+      }
+      return name;
+    },
+    handleSizeChange(val) {
+      this.params.pageNum = 1;
+      this.params.pageSize = val;
+      this.couponList = [];
+      this.getCouponList();
+    },
+    handleCurrentChange(val) {
+      this.params.pageNum = val;
+      this.couponList = [];
+      this.getCouponList();
+    },
+    getCouponList() {
+      getCouponList({ status: 0, isNew: 1 }).then((res) => {
+        if (res.code === 200) {
+          this.couponList = res.data.data.map((v) => {
+            v.validStartTime = tool.getFormatDate(
+              new Date(v.validStartTime),
+              "yyyy.MM.dd"
+            );
+            v.validEndTime = tool.getFormatDate(
+              new Date(v.validEndTime),
+              "yyyy.MM.dd"
+            );
+            return v;
+          });
+          this.total = res.data.totalNums || 0;
+        } else {
+          this.$message({
+            type: "error",
+            message: res.msg,
+          });
+        }
+      });
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.coupon {
+  height: calc(100vh - 184px);
+  background-color: #fff;
+  .recharge_coupon_bottom {
+    padding: 15px 17px;
+    display: flex;
+    flex-wrap: wrap;
+    .recharge_coupon_bottom_item {
+      width: 410px;
+      height: 72px;
+      display: flex;
+      justify-content: flex-start;
+      margin-bottom: 10px;
+      margin-right: 24px;
+      .recharge_coupon_bottom_left {
+        display: flex;
+        flex-direction: column;
+        justify-content: center;
+        align-items: center;
+        width: 110px;
+        margin-top: 10px auto;
+        text-align: center;
+        border-radius: 8px;
+        background-color: #fff;
+        padding: 10px 0;
+        box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
+        .recharge_coupon_bottom_left_num {
+          span {
+            font-size: 14px;
+            font-family: PingFang SC;
+            font-weight: 400;
+            line-height: 20px;
+            margin-left: 2px;
+            color: #ec1414;
+          }
+          .num {
+            font-size: 26px;
+            font-family: PingFang SC;
+            font-weight: bold;
+            color: #ec1414;
+          }
+        }
+
+        .recharge_coupon_bottom_sub {
+          font-size: 14px;
+          font-family: PingFang SC;
+          font-weight: 400;
+          line-height: 20px;
+          color: #666666;
+        }
+      }
+      .recharge_coupon_bottom_middle {
+        display: flex;
+        align-items: center;
+        div {
+          height: 100%;
+          padding: 10px 0;
+          height: 55px;
+          border-right: 1px dashed #ec1414;
+          box-sizing: border-box;
+        }
+      }
+      .recharge_coupon_bottom_right {
+        border-radius: 8px;
+        background-color: #fff;
+        flex: 1;
+        position: relative;
+        padding: 10px;
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
+        .recharge_coupon_bottom_date {
+          font-size: 18px;
+          font-family: PingFang SC;
+          font-weight: bold;
+          line-height: 25px;
+          color: #333333;
+          div:last-child {
+            height: 20px;
+            font-size: 12px;
+            font-family: PingFang SC;
+            font-weight: 400;
+            line-height: 20px;
+            color: #999999;
+          }
+        }
+        .recharge_coupon_bottom_number {
+          display: flex;
+          align-items: center;
+          span {
+            width: 63px;
+            height: 22px;
+            line-height: 22px;
+            border: 1px solid #ec1414;
+            border-radius: 18px;
+            text-align: center;
+            font-size: 12px;
+            font-family: PingFang SC;
+            font-weight: 500;
+            color: #ec1414;
+            cursor: pointer;
+            &:hover {
+              background-color: #ec1414;
+              color: #ffffff;
+            }
+          }
+        }
+      }
+    }
+  }
+}
+</style>

+ 221 - 0
src/components/accountCompoents/invalidCoupon.vue

@@ -0,0 +1,221 @@
+<template>
+  <div class="coupon">
+    <div class="recharge_coupon_bottom" v-if="couponList.length">
+      <div class="recharge_coupon_bottom_item" v-for="(item,index) in couponList" :key="index">
+        <div class="recharge_coupon_bottom_left">
+          <div class="recharge_coupon_bottom_left_num">
+            <span v-if="item.type == 1 || item.type == 3">¥</span>
+            <span class="num" v-if="item.type == 1 || item.type == 3">{{item.money}}</span>
+            <span class="num" v-if="item.type == 2">{{item.discount}}</span>
+            <span v-if="item.type == 2">折</span>
+          </div>
+          <div class="recharge_coupon_bottom_sub">
+            <span v-if="item.type == 2">最高减{{ item.maxDiscount }}元</span>
+            <span v-if="item.type == 1">满{{ item.limitFee }}元可用</span>
+          </div>
+        </div>
+        <div class="recharge_coupon_bottom_middle">
+          <div></div>
+        </div>
+        <div class="recharge_coupon_bottom_right">
+          <div class="recharge_coupon_bottom_date">
+            <div>{{item.name}}</div>
+            <div>有效期:{{item.validStartTime}} - {{item.validEndTime}}</div>
+          </div>
+
+        </div>
+        <div class="recharge_coupon_bottom_number">
+          x{{item.num}}张
+        </div>
+        <img class="img" src="../../../static/image/invalid-coupon.png" alt="">
+      </div>
+    </div>
+    <el-empty v-else style="padding-top:10%;" description="暂无已过期优惠券"></el-empty>
+  </div>
+</template>
+
+<script>
+import { getCouponList, getCouponExplain } from "../../api/amount.js";
+import tool from "../../api/tool.js";
+export default {
+  name: "invalidCoupon",
+  data() {
+    return {
+      couponList: [],
+      params: {
+        pageNum: 1,
+        pageSize: 10,
+      },
+      total: 0,
+    };
+  },
+  created() {
+    this.getCouponList();
+  },
+  methods: {
+    showType(type) {
+      let name = "";
+      // v.type === 1 ? '满减劵' : '折扣券'
+      switch (type) {
+        case 1:
+          name = "满减劵";
+          break;
+        case 2:
+          name = "折扣券";
+          break;
+        case 3:
+          name = "立减劵";
+          break;
+        default:
+          break;
+      }
+      return name;
+    },
+    handleSizeChange(val) {
+      this.params.pageNum = 1;
+      this.params.pageSize = val;
+      this.couponList = [];
+      this.getCouponList();
+    },
+    handleCurrentChange(val) {
+      this.params.pageNum = val;
+      this.couponList = [];
+      this.getCouponList();
+    },
+    getCouponList() {
+      getCouponList({ status: -1, isNew: 1 }).then((res) => {
+        if (res.code === 200) {
+          this.couponList = res.data.data.map((v) => {
+            v.validStartTime = tool.getFormatDate(
+              new Date(v.validStartTime),
+              "yyyy.MM.dd"
+            );
+            v.validEndTime = tool.getFormatDate(
+              new Date(v.validEndTime),
+              "yyyy.MM.dd"
+            );
+            return v;
+          });
+          this.total = res.data.totalNums || 0;
+        } else {
+          this.$message({
+            type: "error",
+            message: res.msg,
+          });
+        }
+      });
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.coupon {
+  height: calc(100vh - 184px);
+  background-color: #fff;
+  .recharge_coupon_bottom {
+    padding: 15px 17px;
+    display: flex;
+    flex-wrap: wrap;
+    .recharge_coupon_bottom_item {
+      position: relative;
+      width: 410px;
+      height: 72px;
+      display: flex;
+      justify-content: flex-start;
+      margin-bottom: 10px;
+      margin-right: 24px;
+      .recharge_coupon_bottom_left {
+        display: flex;
+        flex-direction: column;
+        justify-content: center;
+        align-items: center;
+        width: 110px;
+        margin-top: 10px auto;
+        text-align: center;
+        border-radius: 8px;
+        background-color: #fff;
+        padding: 10px 0;
+        box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
+        .recharge_coupon_bottom_left_num {
+          span {
+            font-size: 14px;
+            font-family: PingFang SC;
+            font-weight: 400;
+            line-height: 20px;
+            margin-left: 2px;
+            color: #cccccc;
+          }
+          .num {
+            font-size: 26px;
+            font-family: PingFang SC;
+            font-weight: bold;
+            color: #cccccc;
+          }
+        }
+
+        .recharge_coupon_bottom_sub {
+          font-size: 14px;
+          font-family: PingFang SC;
+          font-weight: 400;
+          line-height: 20px;
+          color: #cccccc;
+        }
+      }
+      .recharge_coupon_bottom_middle {
+        display: flex;
+        align-items: center;
+        div {
+          height: 100%;
+          padding: 10px 0;
+          height: 55px;
+          border-right: 1px dashed #cccccc;
+          box-sizing: border-box;
+        }
+      }
+      .recharge_coupon_bottom_right {
+        border-radius: 8px;
+        background-color: #fff;
+        flex: 1;
+        position: relative;
+        padding: 10px;
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
+        .recharge_coupon_bottom_date {
+          font-size: 18px;
+          font-family: PingFang SC;
+          font-weight: bold;
+          line-height: 25px;
+          color: #cccccc;
+          div:last-child {
+            height: 20px;
+            font-size: 12px;
+            font-family: PingFang SC;
+            font-weight: 400;
+            line-height: 20px;
+            color: #cccccc;
+          }
+        }
+      }
+      .recharge_coupon_bottom_number {
+        position: absolute;
+        top: 40px;
+        right: 8px;
+        font-size: 12px;
+        font-family: PingFang SC;
+        font-weight: 500;
+        color: #cccccc;
+      }
+      .img {
+        position: absolute;
+        top: 0;
+        right: 0;
+        width: 52px;
+        height: 42px;
+      }
+    }
+  }
+}
+</style>

+ 8 - 0
src/components/accountCompoents/recharge.vue

@@ -30,6 +30,7 @@
 <script>
 import { balanceLogs } from "../../api/amount.js";
 export default {
+  name: 'recharge',
   data() {
     return {
       rechargeList: [],
@@ -111,6 +112,13 @@ export default {
 </script>
 
 <style lang="scss" scoped>
+/deep/ .el-pagination.is-background .el-pager li:not(.disabled).active {
+  background-color: #fc7200;
+  color: #fff !important;
+}
+/deep/ .el-pagination.is-background .el-pager li:hover:not(.disabled) {
+  color: #fc7200;
+}
 /deep/ .el-table td.el-table__cell {
   text-align: center !important;
 }

+ 132 - 124
src/components/shopAccount.vue

@@ -1,124 +1,132 @@
-<template>
-  <div class="shopInfo">
-    <el-row class="order_tab">
-      <el-col :span="15">
-        <div class="tabList">
-          <div class="tab_item" @click="changeTabs(i)" :class="{'tab_item_ac':tabNum==i?true:false}" v-for="(item,i) in tabList" :key="i">
-            <span>{{item.name}}</span>
-            <div class="tab_line"></div>
-          </div>
-        </div>
-      </el-col>
-    </el-row>
-    <el-row class="content">
-      <component v-if="renderComponent" :is="activeName"></component>
-    </el-row>
-  </div>
-</template>
-
-<script>
-import merchantAdd from "./merchantAdd.vue";
-import wallet from "./accountCompoents/wallet.vue";
-import coupon from "./accountCompoents/coupon.vue";
-import recharge from "./accountCompoents/recharge.vue";
-import consumption from "./accountCompoents/consumption.vue";
-export default {
-  name: "HelloWorld",
-  components: {
-    wallet,
-    coupon,
-    recharge,
-    consumption,
-  },
-
-  data() {
-    return {
-      activeName: "wallet",
-      tabList: [
-        { name: "我的钱包", index: 0, activeName: "wallet" },
-        { name: "优惠券", index: 1, activeName: "coupon" },
-        { name: "充值明细", index: 2, activeName: "recharge" },
-        { name: "消费明细", index: 3, activeName: "consumption" },
-      ],
-      tabNum: 0,
-      renderComponent: true,
-    };
-  },
-  created() {
-    this.changeTabs(0);
-  },
-  methods: {
-    forceRerender() {
-      // 从 DOM 中删除 my-component 组件
-      this.renderComponent = false;
-      this.$nextTick(() => {
-        // 在 DOM 中添加 my-component 组件
-        this.renderComponent = true;
-      });
-    },
-    changeTabs(i) {
-      if (i === this.tabNum) {
-        this.forceRerender();
-        return;
-      }
-      this.tabNum = i;
-      this.activeName = this.tabList[i].activeName;
-    },
-  },
-};
-</script>
-
-<!-- Add "scoped" attribute to limit CSS to this component only -->
-<style scoped lang="scss">
-.shopInfo {
-  .order_tab {
-    width: 100%;
-    height: 74px;
-    background: #fff;
-
-    .tabList {
-      width: 100%;
-      height: 74px;
-      padding-top: 20px;
-      padding-left: 36px;
-      box-sizing: border-box;
-      display: flex;
-
-      .tab_item {
-        min-width: 58px;
-        margin-right: 56px;
-        font-size: 16px;
-        font-weight: 500;
-        color: #b1b1b1;
-        position: relative;
-        text-align: center;
-        cursor: pointer;
-
-        .tab_line {
-          width: 58px;
-          height: 6px;
-          background: #fff;
-          border-radius: 3px;
-          margin: 15px auto 0;
-        }
-      }
-
-      .tab_item_ac {
-        color: #fc7200;
-
-        .tab_line {
-          background: #fc7200;
-        }
-      }
-    }
-  }
-
-  .content {
-    width: 100%;
-    margin-top: 10px;
-    padding: 20px;
-    box-sizing: border-box;
-    background: #fff;
-  }
-}
-</style>
+<template>
+  <div class="shopInfo">
+    <el-row class="order_tab">
+      <el-col :span="15">
+        <div class="tabList">
+          <div class="tab_item" @click="changeTabs(i)" :class="{'tab_item_ac':tabNum==i?true:false}" v-for="(item,i) in tabList" :key="i">
+            <span class="item" :class="tabNum==i?'active-item':''" v-if="!item.children">{{item.name}}</span>
+            <el-dropdown v-else @command="chooseCoupon">
+              <span class="el-dropdown-link item" :class="tabNum==i?'active-item':''">
+                {{item.name}}<i class="el-icon-arrow-down el-icon--right"></i>
+              </span>
+              <el-dropdown-menu slot="dropdown">
+                <el-dropdown-item :command="v.command" v-for="(v,index) in item.children" :key="index">{{v.name}}</el-dropdown-item>
+              </el-dropdown-menu>
+            </el-dropdown>
+            <div class="tab_line"></div>
+          </div>
+        </div>
+      </el-col>
+    </el-row>
+    <el-row class="content">
+      <component v-if="renderComponent" :is="activeName"></component>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import recharge from "./recharge.vue";
+import consumption from "./consumption.vue";
+export default {
+  name: "walletDetail",
+  components: {
+    recharge,
+    consumption,
+  },
+  data() {
+    return {
+      activeName: "recharge",
+      tabList: [
+        { name: "充值明细", index: 0, activeName: "recharge" },
+        { name: "消费明细", index: 1, activeName: "consumption" },
+      ],
+      tabNum: 0,
+      renderComponent: true,
+    };
+  },
+  created() {
+    this.changeTabs(0);
+  },
+  methods: {
+    chooseCoupon(e) {
+      this.tabNum = 1;
+      this.activeName = e;
+    },
+    forceRerender() {
+      // 从 DOM 中删除 my-component 组件
+      this.renderComponent = false;
+      this.$nextTick(() => {
+        // 在 DOM 中添加 my-component 组件
+        this.renderComponent = true;
+      });
+    },
+    changeTabs(i) {
+      if (i === this.tabNum) {
+        this.forceRerender();
+        return;
+      }
+      this.tabNum = i;
+      this.activeName = this.tabList[i].activeName;
+    },
+  },
+};
+</script>
+
+<!-- Add "scoped" attribute to limit CSS to this component only -->
+<style scoped lang="scss">
+.shopInfo {
+  .order_tab {
+    width: 100%;
+    height: 74px;
+    background: #fff;
+
+    .tabList {
+      width: 100%;
+      height: 74px;
+      padding-top: 20px;
+      padding-left: 36px;
+      box-sizing: border-box;
+      display: flex;
+
+      .tab_item {
+        min-width: 58px;
+        margin-right: 56px;
+        .item {
+          font-size: 16px;
+          font-weight: 500;
+          color: #b1b1b1;
+          position: relative;
+          text-align: center;
+          cursor: pointer;
+        }
+        .active-item {
+          color: #fc7200;
+        }
+        .tab_line {
+          width: 58px;
+          height: 6px;
+          background: #fff;
+          border-radius: 3px;
+          margin: 15px auto 0;
+        }
+      }
+
+      .tab_item_ac {
+        color: #fc7200;
+
+        .tab_line {
+          background: #fc7200;
+        }
+      }
+    }
+  }
+
+  .content {
+    width: 100%;
+    margin-top: 10px;
+    padding: 20px;
+    box-sizing: border-box;
+    background: #fff;
+  }
+}
+</style>

+ 354 - 121
src/components/accountCompoents/wallet.vue

@@ -1,29 +1,73 @@
 <template>
-  <div>
+  <div class="wallet">
     <el-col :span="24">
-      <div class="balance">
-        <div class="balance_name">账户余额(元)</div>
-        <div class="balance_price">{{amount}}</div>
-        <div class="balance_line"></div>
-        <div class="balance_sign"><img src="../../../static/image/1.png" alt="" srcset=""> 为了您能高效发单,请保持账户资金充足</div>
+      <div class="head-account">
+        <div class="balance" @click="goDetail">
+          <div class="balance_name">账户余额(元)</div>
+          <div class="balance_price">{{amount}}</div>
+          <div class="balance_sign"><img src="../../../static/image/1.png" alt="" srcset=""> 为了您能高效发单,请保持账户资金充足</div>
+        </div>
+        <div class="balance coupon" @click="goCoupon">
+          <div class="balance_name">优惠券(张)</div>
+          <div class="balance_price">{{$store.state.userInfo.couponNum}}</div>
+          <div class="balance_sign">可用优惠券</div>
+        </div>
       </div>
     </el-col>
-    <el-col :span="18"  v-if="memberType !==3">
+    <el-col class="wallet-content" :span="20" v-if="memberType !==3">
       <div class="recharge_title">充值金额</div>
-      <div class="recharge_list">
-        <div @click="chooseMoney(v,i)" :class="curIdx === i ? 'item item_ac' : 'item'" v-for="(v,i) in moneyList" :key="i">{{v.value}}元</div>
-        <el-input type='num' @focus="open" v-model="value" clearable :class="curIdx === -1 ? 'item item_ac' : 'item'" placeholder="其他金额(最多2位小数)" />
+      <div class="recharge_list recharge_list_m">
+        <div @click="chooseMoney(v,i)" :class="curIdx === i ? 'item item_ac' : 'item'" v-for="(v,i) in moneyList" :key="i"><span v-if="v.couponList || v.giveValue" class="item_tips">充值有礼</span>{{v.value}}元</div>
+        <el-input @focus="open" v-model="inputValue" clearable :class="curIdx === -1 ? 'item item_ac' : 'item'" placeholder="其他金额" />
+      </div>
+      <div class="recharge_coupon" v-if="curIdx!==-1 && (couponList.length || giveValue)">
+        <div class="recharge_coupon_top">
+          <img src="../../../static/image/recharge_coupon.png" alt="" srcset="">
+          <div class="recharge_coupon_top_left">充{{moneyList[curIdx].value}}元,
+            赠送<span v-if="giveValue">{{giveValue}}元</span><span v-if="moneyList[curIdx].giveCouponAmount">{{giveValue&&moneyList[curIdx].giveCouponAmount ? '和' : ''}}{{moneyList[curIdx].giveCouponAmount}}元优惠券</span>
+          </div>
+          <div class="recharge_coupon_top_right ">
+            <div v-for="(v,i) in couponList" :key="i">{{`${v.couponName} x${v.memberReciveNum}张  `}}</div>
+          </div>
+        </div>
+        <div class="recharge_coupon_bottom">
+          <div class="recharge_coupon_bottom_item" v-for="(item,index) in couponList" :key="index">
+            <div class="recharge_coupon_bottom_left">
+              <div class="recharge_coupon_bottom_left_num">
+                <span v-if="item.couponType == 1 || item.couponType == 3">¥</span>
+                <span class="num" v-if="item.couponType == 1 || item.couponType == 3">{{item.money}}</span>
+                <span class="num" v-if="item.couponType == 2">{{item.discount}}</span>
+                <span v-if="item.couponType == 2">折</span>
+              </div>
+              <div class="recharge_coupon_bottom_sub">
+                <span v-if="item.couponType == 2">最高减{{ item.maxDiscount }}元</span>
+                <span v-if="item.couponType == 1">满{{ item.limitFee }}元可用</span>
+              </div>
+            </div>
+            <div class="recharge_coupon_bottom_middle">
+              <div></div>
+            </div>
+            <div class="recharge_coupon_bottom_right">
+              <div class="recharge_coupon_bottom_date">
+                <div>{{item.couponName}}</div>
+                <div>有效期:{{item.days}}天(自领取后生效)</div>
+              </div>
+              <div class="recharge_coupon_bottom_number">
+                <span>x{{item.memberReciveNum}}张</span>
+              </div>
+            </div>
+          </div>
+        </div>
       </div>
       <div class="recharge_title">支付方式</div>
       <div class="recharge_list">
-        <div @click="paymentType = 1" :class="paymentType === 1 ? 'item item_ac' : 'item'"><img src="../../../static/image/alipay.png" alt="" srcset=""> 支付宝支付</div>
-        <div @click="paymentType = 2" :class="paymentType === 2 ? 'item item_ac' : 'item'"><img src="../../../static/image/we-chat.png" alt="" srcset="">微信支付</div>
+        <div @click="paymentType = 1" :class="paymentType === 1 ? 'item item_ac' : 'item'"><img class="img" src="../../../static/image/alipay.png" alt="" srcset=""> 支付宝支付<img class="choose" v-if="paymentType === 1" src="../../../static/image/icon_choose.png" alt=""></div>
+        <div @click="paymentType = 2" :class="paymentType === 2 ? 'item item_ac' : 'item'"><img class="img" src="../../../static/image/we-chat.png" alt="" srcset="">微信支付<img class="choose" v-if="paymentType === 2" src="../../../static/image/icon_choose.png" alt=""></div>
       </div>
       <div>
-        <el-checkbox v-model="checked">我已阅读并同意 <span @click="getExplain" class="agreement">《充值协议》</span> </el-checkbox>
+        <el-checkbox v-model="checked">充值即同意 <span @click="getExplain" class="agreement">《充值协议》</span> </el-checkbox>
       </div>
       <el-button @click="recharge" class="recharge_color">去充值</el-button>
-      <!-- <div class="agreement">充值即同意 <span @click="getExplain">《充值协议》</span> </div> -->
     </el-col>
     <!-- 支付二维码 -->
     <qr-code v-if="showCode" @paySuccess="paySuccess" @refreshCode="recharge" @closeCode="showCode = false" ref="code" :payAmount="payAmount" :link="link" :paymentType="paymentType" :orderSn="orderSn"></qr-code>
@@ -39,11 +83,11 @@ import {
   getWallet,
   getRechargeList,
   recharge,
-  getPayResult,
   getExplain,
 } from "../../api/amount.js";
 import qrCode from "../../common/qrCode.vue";
 export default {
+  name: "wallet",
   props: {
     products: {
       type: Array,
@@ -67,9 +111,11 @@ export default {
       payAmount: 0,
       centerDialogVisible: false,
       text: "",
-      value: "",
+      inputValue: "",
       checked: false,
       memberType: this.$store.state.userInfo.memberType,
+      couponList: [],
+      giveValue: 0,
     };
   },
   watch: {
@@ -86,10 +132,18 @@ export default {
   created() {
     this.getWallet();
     this.getRechargeList();
+    this.$store.dispatch("getUserInfo");
   },
   methods: {
+    goDetail() {
+      this.$router.push({ name: "walletDetail" });
+    },
+    goCoupon() {
+      this.$router.push({ name: "coupon" });
+    },
     paySuccess() {
       this.showCode = false;
+      this.$store.dispatch("getUserInfo");
       this.getWallet();
     },
     getExplain() {
@@ -110,6 +164,8 @@ export default {
       getRechargeList().then((res) => {
         if (res.code === 200) {
           this.moneyList = res.data;
+          this.couponList = this.moneyList[this.curIdx].couponList || [];
+          this.giveValue = this.moneyList[this.curIdx].giveValue;
           this.money = this.moneyList[this.curIdx].value;
           this.id = this.moneyList[this.curIdx].id;
         } else {
@@ -133,19 +189,22 @@ export default {
       });
     },
     chooseMoney(v, i) {
-      this.value = "";
+      this.inputValue = "";
       this.curIdx = i;
       this.money = v.value;
       this.id = v.id;
+      this.couponList = this.moneyList[i].couponList || [];
+      this.giveValue = this.moneyList[i].giveValue ?? 0;
     },
     open() {
       this.curIdx = -1;
-      this.money = ''
-      this.id = ''
+      this.money = "";
+      this.id = "";
+      this.couponList = [];
     },
     recharge() {
       let params = {
-        money: this.value ? this.value : this.money,
+        money: this.inputValue ? this.inputValue : this.money,
         paymentType: this.paymentType,
         createType: 1,
         id: this.id,
@@ -176,9 +235,6 @@ export default {
           this.orderSn = res.data.orderSn;
           this.payAmount = res.data.amount;
           this.showCode = true;
-          setInterval(() => {
-            // this.getPayResult();
-          }, 2000);
         } else {
           this.$message({
             type: "info",
@@ -187,121 +243,298 @@ export default {
         }
       });
     },
-    getPayResult() {
-      let params = {
-        orderSn: this.orderSn,
-        payType: this.paymentType === 1 ? this.paymentType : 0,
-      };
-      getPayResult(params).then((res) => {
-        if (res.code === 200) {
-          this.$message({
-            type: res.data === "success" ? "success" : "error",
-            message: res.data === "success" ? "支付成功!" : "支付失败!",
-          });
-        } else {
-          this.$message({
-            type: "error",
-            message: res.msg,
-          });
-        }
-      });
-    },
   },
 };
 </script>
 
 <style lang="scss" scoped>
-.balance {
+.wallet {
   width: 100%;
-  height: 200px;
-  border-radius: 5px;
-  background: linear-gradient(to right, #5664e2, #13b2c1);
-  padding-left: 42px;
-  box-sizing: border-box;
-  margin-bottom: 42px;
-  .balance_name {
-    font-size: 14px;
-    font-weight: 400;
-    color: #ffffff;
-    padding-top: 36px;
+  height: 100%;
+  background: #ffffff;
+  .head-account {
+    display: flex;
+    .balance {
+      border-radius: 5px;
+      background-image: url(../../../static/image/wallet1.png);
+      background-size: 100% 100%;
+      width: 618px;
+      height: 168px;
+      padding-left: 25px;
+      box-sizing: border-box;
+      margin-bottom: 42px;
+      cursor: pointer;
+      .balance_name {
+        font-size: 14px;
+        line-height: 22px;
+        font-weight: 400;
+        color: #ffffff;
+        padding-top: 24px;
+      }
+      .balance_price {
+        font-size: 42px;
+        line-height: 59px;
+        font-weight: bold;
+        color: #ffffff;
+        margin: 8px 0;
+      }
+      .balance_sign {
+        font-size: 12px;
+        font-weight: 400;
+        color: #ffffff;
+        opacity: 0.8;
+        line-height: 17px;
+        display: flex;
+        align-items: center;
+        img {
+          width: 12px;
+          height: 12px;
+          margin-right: 4px;
+        }
+      }
+    }
+    .coupon {
+      width: 298px;
+      height: 168px;
+      background-image: url(../../../static/image/wallet2.png);
+    }
   }
-  .balance_price {
-    font-size: 60px;
-    font-weight: bold;
-    color: #ffffff;
+  .wallet-content {
+    padding-left: 15px;
   }
-  .balance_line {
-    width: 100%;
-    height: 1px;
-    background: rgba($color: #ffffff, $alpha: 0.1);
-    margin-top: 10px;
+  .recharge_title {
+    font-size: 16px;
+    font-weight: 500;
+    color: #333333;
+  }
+  .recharge_color {
+    width: 160px;
+    background: #fc7200;
+    color: #fff;
   }
-  .balance_sign {
+  .agreement {
     font-size: 12px;
     font-weight: 400;
-    color: #ffffff;
-    opacity: 0.6;
-    line-height: 60px;
-    display: flex;
-    align-items: center;
-    img {
-      width: 13px;
-      height: 13px;
-      margin-right: 4px;
+    color: #fc7200;
+    margin-top: 10px;
+    span {
+      color: #3662a1;
+      cursor: pointer;
     }
   }
-}
-.recharge_title {
-  font-size: 16px;
-  font-weight: 500;
-  color: #333333;
-}
-.recharge_color {
-  background: #fc7200;
-  color: #fff;
-}
-.agreement {
-  font-size: 12px;
-  font-weight: 400;
-  color: #fc7200;
-  margin-top: 10px;
-  span {
-    color: #3662a1;
-    cursor: pointer;
+  .recharge_list /deep/ .el-input__inner {
+    padding: 0 15px;
+    height: 36px;
+    border: none !important;
+    text-align: center;
   }
-}
-.recharge_list /deep/ .el-input__inner {
-  border: none !important;
-  text-align: center;
-}
-.recharge_list {
-  width: 100%;
-  display: flex;
-  flex-wrap: wrap;
-  margin-top: 24px;
-  margin-bottom: 40px;
-  .item {
-    width: 210px;
-    height: 67px;
-    border: 1px solid #e3e3e3;
-    color: #222222;
-    font-size: 14px;
-    font-weight: 600;
+  .recharge_list /deep/ input::placeholder {
+    font-size: 14px !important;
+  }
+  .recharge_list {
+    width: 100%;
     display: flex;
-    align-items: center;
-    justify-content: center;
-    border-radius: 3px;
-    margin: 0 15px 15px 0;
-    cursor: pointer;
-    img {
-      width: 24px;
-      height: 24px;
-      margin-right: 6px;
+    flex-wrap: wrap;
+    margin-top: 24px;
+    margin-bottom: 10px;
+
+    .item {
+      position: relative;
+      width: 200px;
+      height: 40px;
+      border: 1px solid #e6e6e6;
+      color: #333333;
+      font-size: 16px;
+      font-weight: 500;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      border-radius: 3px;
+      margin: 0 15px 15px 0;
+      cursor: pointer;
+      .img {
+        width: 24px;
+        height: 24px;
+        margin-right: 6px;
+      }
+      .choose {
+        position: absolute;
+        top: 0;
+        right: 0;
+        width: 16px;
+        height: 16px;
+      }
+    }
+    .item_ac {
+      border-color: #fc7200;
+      color: #fc7200;
     }
   }
-  .item_ac {
-    border-color: #fc7200;
-    color: #fc7200;
+  .recharge_list_m {
+    .item {
+      width: 90px;
+      height: 36px;
+      margin: 0 24px 15px 0;
+      position: relative;
+      .item_tips {
+        height: 19px;
+        position: absolute;
+        right: -22px;
+        top: -28px;
+        padding: 5px;
+        background-image: url("../../../static/image/recharge.png");
+        background-position: center;
+        background-repeat: no-repeat;
+        background-size: contain;
+        font-size: 12px;
+        font-weight: 100;
+        color: #ffffff;
+      }
+    }
+  }
+  .recharge_coupon {
+    width: 880px;
+    background: #fef2e9;
+    border-radius: 8px;
+    padding: 3px 10px;
+    margin-bottom: 42px;
+    .recharge_coupon_top {
+      display: flex;
+      flex-wrap: wrap;
+      align-items: center;
+      img {
+        width: 28px;
+        height: 30px;
+      }
+      .recharge_coupon_top_left {
+        padding: 0 10px 0 8px;
+        display: flex;
+        align-items: center;
+        font-size: 16px;
+        font-family: PingFang SC;
+        font-weight: bold;
+        color: #fc7200;
+      }
+      .recharge_coupon_top_right {
+        display: flex;
+        flex-wrap: wrap;
+        align-items: flex-end;
+        font-size: 12px;
+        font-weight: 400;
+        color: #fc7200;
+        padding-top: 2px;
+        div {
+          margin-right: 10px;
+        }
+      }
+    }
+    .recharge_coupon_bottom {
+      margin: 15px 10px;
+      display: flex;
+      justify-content: space-between;
+      flex-wrap: wrap;
+      .recharge_coupon_bottom_item {
+        width: 410px;
+        height: 72px;
+        display: flex;
+        justify-content: flex-start;
+        margin-bottom: 10px;
+        // margin-right: 24px;
+        .recharge_coupon_bottom_left {
+          display: flex;
+          flex-direction: column;
+          justify-content: center;
+          align-items: center;
+          width: 110px;
+          margin-top: 10px auto;
+          text-align: center;
+          border-radius: 8px;
+          background-color: #fff;
+          padding: 10px 0;
+          .recharge_coupon_bottom_left_num {
+            span {
+              font-size: 14px;
+              font-family: PingFang SC;
+              font-weight: 400;
+              line-height: 20px;
+              margin-left: 2px;
+              color: #ec1414;
+            }
+            .num {
+              font-size: 26px;
+              font-family: PingFang SC;
+              font-weight: bold;
+              color: #ec1414;
+            }
+          }
+
+          .recharge_coupon_bottom_sub {
+            font-size: 14px;
+            font-family: PingFang SC;
+            font-weight: 400;
+            line-height: 20px;
+            color: #666666;
+          }
+        }
+        .recharge_coupon_bottom_middle {
+          display: flex;
+          align-items: center;
+          div {
+            height: 100%;
+            padding: 10px 0;
+            height: 55px;
+            border-right: 1px dashed #ec1414;
+            box-sizing: border-box;
+          }
+        }
+        .recharge_coupon_bottom_right {
+          border-radius: 8px;
+          background-color: #fff;
+          flex: 1;
+          position: relative;
+          padding: 10px;
+          display: flex;
+          justify-content: space-between;
+          align-items: center;
+          .recharge_coupon_bottom_date {
+            font-size: 18px;
+            font-family: PingFang SC;
+            font-weight: bold;
+            line-height: 25px;
+            color: #333333;
+            div:last-child {
+              height: 20px;
+              font-size: 14px;
+              font-family: PingFang SC;
+              font-weight: 400;
+              line-height: 20px;
+              color: #999999;
+            }
+          }
+          .recharge_coupon_bottom_number {
+            display: flex;
+            align-items: center;
+            span {
+              width: 63px;
+              height: 22px;
+              line-height: 22px;
+              border: 1px solid #ec1414;
+              border-radius: 18px;
+              text-align: center;
+              font-size: 12px;
+              font-family: PingFang SC;
+              font-weight: 500;
+              color: #ec1414;
+              cursor: pointer;
+              &:hover {
+                background-color: #ec1414;
+                color: #ffffff;
+              }
+            }
+          }
+        }
+      }
+    }
   }
 }
 </style>

+ 4 - 4
src/components/about.vue

@@ -3,10 +3,10 @@
     <div class="about-bg">
       <div class="name">猎豹AI</div>
       <div class="des">智能聚合运力平台</div>
-      <img class="download" src="../../static/image/download.png" alt="">
+      <img class="download" src="../../../static/image/download.png" alt="">
       <div class="scan">扫码下载APP</div>
       <div class="version">
-        <img class="pc" src="../../static/image/pc-icon.png" alt="">
+        <img class="pc" src="../../../static/image/pc-icon.png" alt="">
         <div class="versoin-num">猎豹AI聚合配送PC版版本V{{version}}</div>
       </div>
     </div>
@@ -14,7 +14,7 @@
 </template>
 
 <script>
-import config from "../../package.json";
+import config from "../../../package.json";
 export default {
   name: "about",
   data() {
@@ -45,7 +45,7 @@ export default {
     display: flex;
     flex-direction: column;
     align-items: center;
-    background: url("../../static/image/about-bg.png");
+    background: url("../../../static/image/about-bg.png");
     background-size: 100% 100%;
     width: 372px;
     height: 268px;

+ 98 - 0
src/components/help/customerService.vue

@@ -0,0 +1,98 @@
+<template>
+  <div class="customer-service">
+    <div class="phone-list">
+      <div class="item" v-for="(v,i) in phoneList" :key="i">
+        <img class="img" :src="v.logo" alt="">
+        <div class="name">{{v.name}}</div>
+        <div class="shop-name">{{v.customerPhone}}</div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { getCustomerPhone } from "../../api/setting.js";
+export default {
+  name: "customerService",
+  data() {
+    return {
+      phoneList: [],
+    };
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {},
+  // 方法集合
+  methods: {
+    getCustomerPhone() {
+      getCustomerPhone().then((res) => {
+        if (res.code === 200) {
+          this.phoneList = res.data;
+        } else {
+          this.$message.error(res.msg);
+        }
+      });
+    },
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  created() {
+    this.getCustomerPhone();
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {},
+  // 生命周期 - 创建之前
+  beforeCreate() {},
+  // 生命周期 - 挂载之前
+  beforeMount() {},
+  // 生命周期 - 更新之前
+  beforeUpdate() {},
+  // 生命周期 - 更新之后
+  updated() {},
+  // 生命周期 - 销毁之前
+  beforeDestroy() {},
+  // 生命周期 - 销毁完成
+  destroyed() {},
+  // 如果页面有keep-alive缓存功能,这个函数会触发
+  activated() {},
+};
+</script>
+
+<style lang="scss" scoped  type="text/css">
+.phone-list {
+  display: flex;
+  flex-wrap: wrap;
+  .item {
+    position: relative;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    width: 280px;
+    height: 120px;
+    background: #ffffff;
+    box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
+    border-radius: 8px;
+    margin: 10px 20px 0 0;
+    cursor: pointer;
+    .img {
+      width: 40px;
+      height: 40px;
+      border-radius: 50%;
+    }
+    .name {
+      font-size: 18px;
+      font-weight: 500;
+      line-height: 20px;
+      color: #333333;
+      margin: 10px 0;
+    }
+    .shop-name {
+      font-size: 14px;
+      font-weight: 400;
+      line-height: 20px;
+      color: #999999;
+    }
+  }
+}
+</style>

+ 5 - 5
src/components/downloadCenter.vue

@@ -52,7 +52,7 @@
     </div>
     <div class="lb-list">
       <div class="lb-app">
-        <img class="img" src="../../static/image/xiangrikui.png" alt="">
+        <img class="img" src="../../../static/image/xiangrikui.png" alt="">
         <div class="name">向日葵</div>
         <div class="tips">远程桌面控制软件,便于更好的排查解决问题,提供更优质的服务</div>
         <div @click="download('https://sunlogin.oray.com/download')" class="download">下载</div>
@@ -62,28 +62,28 @@
 </template>
 
 <script>
-import {name ,version} from '../../package.json'
+import {name ,version} from '../../../package.json'
 export default {
   name: "downloadCenter",
   data() {
     return {
       lbApp: [
         {
-          img: require("../../static/image/download.png"),
+          img: require("../../../static/image/download.png"),
           name: "Android手机版",
           tips: "适合大部分安卓手机使用",
           download: false,
           src: "",
         },
         {
-          img: require("../../static/image/download.png"),
+          img: require("../../../static/image/download.png"),
           name: "Iphone手机版",
           tips: "应用市场搜索[AI聚合配送]",
           download: false,
           src: "",
         },
         {
-          img: require("../../static/image/juhe-icon.png"),
+          img: require("../../../static/image/juhe-icon.png"),
           name: "Windows",
           tips: "客户端、支持Windows系统",
           download: true,

+ 135 - 111
src/components/set.vue

@@ -1,111 +1,135 @@
-<template>
-  <div class="setting">
-    <el-row class="order_tab">
-      <el-col :span="15">
-        <div class="tabList">
-          <div class="tab_item" @click="changeTabs(i)" :class="{'tab_item_ac':tabNum==i?true:false}" v-for="(item,i) in tabList" :key="i">
-            <span>{{item.name}}</span>
-            <div class="tab_line"></div>
-          </div>
-        </div>
-      </el-col>
-    </el-row>
-    <el-row class="content">
-      <el-col :span="24">
-        <component v-if="renderComponent" :is="activeName"></component>
-      </el-col>
-    </el-row>
-  </div>
-</template>
-
-<script>
-import voiceSetting from "./settingComponents/voiceSetting.vue";
-import deliverySetting from "./settingComponents/deliverySetting.vue";
-export default {
-  name: "HelloWorld",
-  data() {
-    return {
-      tabList: [
-        { name: "自动接单/语音设置", index: 0,activeName: 'voiceSetting' },
-        { name: "推荐/屏蔽运力", index: 1,activeName: 'deliverySetting' },
-      ],
-      tabNum: 0,
-      activeName: "voiceSetting",
-      renderComponent: true,
-    };
-  },
-  components: {
-    voiceSetting,
-    deliverySetting,
-  },
-  methods: {
-    forceRerender() {
-      // 从 DOM 中删除 my-component 组件
-      this.renderComponent = false;
-      this.$nextTick(() => {
-        // 在 DOM 中添加 my-component 组件
-        this.renderComponent = true;
-      });
-    },
-    changeTabs(i) {
-      if (i === this.tabNum) {
-        this.forceRerender();
-        return;
-      }
-      this.tabNum = i;
-      this.activeName = this.tabList[i].activeName;
-    },
-  },
-};
-</script>
-
-<!-- Add "scoped" attribute to limit CSS to this component only -->
-<style lang="scss" scoped="scoped">
-.setting {
-  .order_tab {
-    width: 100%;
-    height: 74px;
-    background: #fff;
-
-    .tabList {
-      width: 100%;
-      height: 74px;
-      padding-top: 20px;
-      padding-left: 36px;
-      box-sizing: border-box;
-      display: flex;
-
-      .tab_item {
-        min-width: 58px;
-        margin-right: 56px;
-        font-size: 16px;
-        font-weight: 500;
-        color: #b1b1b1;
-        position: relative;
-        text-align: center;
-        cursor: pointer;
-
-        .tab_line {
-          width: 58px;
-          height: 6px;
-          background: #fff;
-          border-radius: 3px;
-          margin: 15px auto 0;
-        }
-      }
-
-      .tab_item_ac {
-        color: #fc7200;
-
-        .tab_line {
-          background: #fc7200;
-        }
-      }
-    }
-  }
-  .content {
-    width: 100%;
-    margin-top: 10px;
-  }
-}
-</style>
+<template>
+  <div class="shopInfo">
+    <el-row class="order_tab">
+      <el-col :span="24">
+        <div class="tabList">
+          <div class="tab_item" @click="changeTabs(i)" :class="{'tab_item_ac':tabNum==i?true:false}" v-for="(item,i) in tabList" :key="i">
+            <span class="item" :class="tabNum==i?'active-item':''" v-if="!item.children">{{item.name}}</span>
+            <el-dropdown v-else @command="chooseCoupon">
+              <span class="el-dropdown-link item" :class="tabNum==i?'active-item':''">
+                {{item.name}}<i class="el-icon-arrow-down el-icon--right"></i>
+              </span>
+              <el-dropdown-menu slot="dropdown">
+                <el-dropdown-item :command="v.command" v-for="(v,index) in item.children" :key="index">{{v.name}}</el-dropdown-item>
+              </el-dropdown-menu>
+            </el-dropdown>
+            <div class="tab_line"></div>
+          </div>
+        </div>
+      </el-col>
+    </el-row>
+    <el-row class="content">
+      <component v-if="renderComponent" :is="activeName"></component>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import feedbackInfo from "./feedbackInfo.vue";
+import myFeedback from "./myFeedback.vue";
+export default {
+  name: "feedback",
+  components: {
+    feedbackInfo,
+    myFeedback,
+  },
+  data() {
+    return {
+      activeName: "feedbackInfo",
+      tabList: [
+        { name: "意见反馈", index: 0, activeName: "feedbackInfo" },
+        { name: "我的反馈", index: 1, activeName: "myFeedback" },
+      ],
+      tabNum: 0,
+      renderComponent: true,
+    };
+  },
+  created() {
+    this.changeTabs(0);
+    this.$bus.$on("goFeedbackList", (index) => {
+      this.changeTabs(index);
+    });
+  },
+  methods: {
+    chooseCoupon(e) {
+      this.tabNum = 2;
+      this.activeName = e;
+    },
+    forceRerender() {
+      // 从 DOM 中删除 my-component 组件
+      this.renderComponent = false;
+      this.$nextTick(() => {
+        // 在 DOM 中添加 my-component 组件
+        this.renderComponent = true;
+      });
+    },
+    changeTabs(i) {
+      if (i === this.tabNum) {
+        this.forceRerender();
+        return;
+      }
+      this.tabNum = i;
+      this.activeName = this.tabList[i].activeName;
+    },
+  },
+};
+</script>
+
+<!-- Add "scoped" attribute to limit CSS to this component only -->
+<style scoped lang="scss">
+.shopInfo {
+  .order_tab {
+    width: 100%;
+    height: 74px;
+    background: #fff;
+
+    .tabList {
+      width: 100%;
+      height: 74px;
+      padding-top: 20px;
+      padding-left: 36px;
+      box-sizing: border-box;
+      display: flex;
+
+      .tab_item {
+        min-width: 58px;
+        margin-right: 56px;
+        .item {
+          font-size: 16px;
+          font-weight: 500;
+          color: #b1b1b1;
+          position: relative;
+          text-align: center;
+          cursor: pointer;
+        }
+        .active-item {
+          color: #fc7200;
+        }
+        .tab_line {
+          width: 58px;
+          height: 6px;
+          background: #fff;
+          border-radius: 3px;
+          margin: 15px auto 0;
+        }
+      }
+
+      .tab_item_ac {
+        color: #fc7200;
+
+        .tab_line {
+          background: #fc7200;
+        }
+      }
+    }
+  }
+
+  .content {
+    width: 100%;
+    margin-top: 10px;
+    box-sizing: border-box;
+    background: #ffffff;
+    padding: 0 20px;
+  }
+}
+</style>

+ 190 - 0
src/components/help/feedbackInfo.vue

@@ -0,0 +1,190 @@
+<template>
+  <div class="feedback-info">
+    <div class="cell">
+      <div class="title">选择反馈类型</div>
+      <div class="type-list">
+        <div :class="params.type === v.type ? 'type active': 'type'" v-for="v in typeList" :key="v.type" @click="params.type = v.type">{{v.name}}</div>
+      </div>
+    </div>
+    <div class="cell">
+      <div class="title">问题描述</div>
+      <el-input class="descripe" clearable type="textarea" maxlength="200" show-word-limit placeholder="请详细描述您的问题,我们会尽快解决" v-model="params.content">
+      </el-input>
+    </div>
+    <div class="cell">
+      <div class="title">提交截图(最多3张)</div>
+      <el-upload action="" list-type="picture-card" :on-preview="handlePictureCardPreview" :on-remove="removeImg" :http-request="submitUpload">
+        <i class="el-icon-plus"></i>
+      </el-upload>
+    </div>
+    <el-button type="primary" :loading="loading" @click="submit">提交</el-button>
+    <el-dialog :visible.sync="dialogVisible">
+      <img width="100%" :src="dialogImageUrl" alt="">
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { uploadFeedbackImg, saveFeedback } from "../../api/setting.js";
+export default {
+  name: "feedbackInfo",
+  data() {
+    return {
+      typeList: [
+        {
+          name: "账号问题",
+          type: 1,
+        },
+        {
+          name: "功能问题",
+          type: 2,
+        },
+        {
+          name: "优化建议",
+          type: 3,
+        },
+        {
+          name: "其他问题",
+          type: 4,
+        },
+      ],
+      params: {
+        type: 1,
+        content: "",
+        pictures: [],
+      },
+      pictures: [],
+      baseUrl: process.env.VUE_APP_BASE_URL,
+      dialogImageUrl: "",
+      dialogVisible: false,
+      fileList: [],
+      loading: false,
+    };
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {},
+  // 方法集合
+  methods: {
+    submit() {
+      if (!this.params.content.trim()) {
+        return this.$message.warning("请描述你的问题");
+      }
+      this.params.pictures = this.pictures.map((v) => v.url);
+      console.log(this.params);
+      this.loading = true;
+      saveFeedback(this.params).then((res) => {
+        this.loading = false;
+        if (res.code === 200) {
+          this.$message.success("反馈成功");
+          this.params = {
+            type: 1,
+            content: "",
+            pictures: [],
+          };
+          this.pictures = [];
+          this.$bus.$emit('goFeedbackList',1)
+        } else {
+          this.$message.error(res.msg);
+        }
+      });
+    },
+    removeImg(file) {
+      console.log(file, fileList);
+      this.pictures = this.pictures.filter((v) => {
+        return v.fileName !== file.name;
+      });
+    },
+    submitUpload(params) {
+      let file = new FormData();
+      file.append("file", params.file);
+      uploadFeedbackImg(file).then((res) => {
+        if (res.code === 200) {
+          this.pictures.push(res.data);
+        } else {
+          this.$message.error(res.msg);
+        }
+        console.log(res);
+      });
+    },
+    handlePictureCardPreview(file) {
+      this.dialogImageUrl = file.url;
+      this.dialogVisible = true;
+    },
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  created() {},
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {},
+  // 生命周期 - 创建之前
+  beforeCreate() {},
+  // 生命周期 - 挂载之前
+  beforeMount() {},
+  // 生命周期 - 更新之前
+  beforeUpdate() {},
+  // 生命周期 - 更新之后
+  updated() {},
+  // 生命周期 - 销毁之前
+  beforeDestroy() {},
+  // 生命周期 - 销毁完成
+  destroyed() {},
+  // 如果页面有keep-alive缓存功能,这个函数会触发
+  activated() {},
+};
+</script>
+
+<style lang="scss" scoped  type="text/css">
+.cell {
+  margin: 40px 0;
+  .title {
+    position: relative;
+    font-size: 16px;
+    font-weight: bold;
+    line-height: 22px;
+    color: #333333;
+    padding-left: 10px;
+    margin: 24px 0 13px;
+  }
+  .title::before {
+    width: 3px;
+    height: 16px;
+    background: rgba(252, 114, 0, 0.39);
+    border-radius: 2px;
+    content: "";
+    position: absolute;
+    top: 2px;
+    left: 0;
+  }
+  .type-list {
+    display: flex;
+    .type {
+      width: 90px;
+      height: 36px;
+      line-height: 36px;
+      text-align: center;
+      border-radius: 2px 2px 2px 2px;
+      border: 1px solid #e6e6e6;
+      font-size: 14px;
+      font-weight: 500;
+      color: #333333;
+      margin-right: 24px;
+    }
+    .active {
+      border-color: #fc7200;
+      color: #fc7200;
+    }
+  }
+  .descripe {
+    width: 800px;
+    height: 200px;
+    border-radius: 8px 8px 8px 8px;
+    background: #f5f5f5;
+    /deep/ .el-textarea__inner {
+      border: none !important;
+      background: #f5f5f5 !important;
+      height: 200px !important;
+    }
+  }
+}
+</style>

+ 2 - 2
src/components/help.vue

@@ -26,9 +26,9 @@
 </template>
 
 <script>
-import { helpList, helpDetail } from "../api/help.js";
+import { helpList, helpDetail } from "../../api/help.js";
 export default {
-  name: "help",
+  name: "commonProblem",
   data() {
     return {
       helpList: [],

+ 166 - 0
src/components/help/myFeedback.vue

@@ -0,0 +1,166 @@
+<template>
+  <div class="my-feedback">
+    <div class="cell" v-for="(v,i) in feedbackList" :key="i">
+      <div class="cell-top">
+        <div class="title">{{showType(v.type)}}</div>
+        <div class="time">{{v.createTime}}</div>
+        <div class="status" :class="v.status === 2 ? 'active-status' : ''">{{v.status === 1 ? '待回复' : '已回复'}}</div>
+      </div>
+      <div class="content">{{v.content}}</div>
+      <div class="img-list">
+        <!-- <img v-for="(pic,idx) in v.pictures" :key="idx" :src="pic" alt=""> -->
+        <el-image class="img" v-for="(pic,idx) in v.pictures" :key="idx" :src="pic" :preview-src-list="v.pictures">
+        </el-image>
+      </div>
+      <div v-if="v.status === 2" class="cell-top cell-bot">
+        <div class="title1">平台回复</div>
+        <div class="time">{{v.updateTime}}</div>
+      </div>
+      <div v-if="v.answer" class="content">{{v.answer}}</div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { getFeedbackList } from "../../api/setting.js";
+export default {
+  name: "myFeedback",
+  data() {
+    return {
+      feedbackList: [],
+    };
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {},
+  // 方法集合
+  methods: {
+    showType(type) {
+      let name = "";
+      switch (type) {
+        case 1:
+          name = "账号问题";
+          break;
+        case 2:
+          name = "功能问题";
+          break;
+        case 3:
+          name = "优化建议";
+          break;
+        case 4:
+          name = "其他问题";
+          break;
+
+        default:
+          break;
+      }
+      return name;
+    },
+    getFeedbackList() {
+      getFeedbackList().then((res) => {
+        if (res.code === 200) {
+          this.feedbackList = res.data.data;
+        } else {
+          this.$message.error(res.msg);
+        }
+      });
+    },
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  created() {
+    this.getFeedbackList();
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {},
+  // 生命周期 - 创建之前
+  beforeCreate() {},
+  // 生命周期 - 挂载之前
+  beforeMount() {},
+  // 生命周期 - 更新之前
+  beforeUpdate() {},
+  // 生命周期 - 更新之后
+  updated() {},
+  // 生命周期 - 销毁之前
+  beforeDestroy() {},
+  // 生命周期 - 销毁完成
+  destroyed() {},
+  // 如果页面有keep-alive缓存功能,这个函数会触发
+  activated() {},
+};
+</script>
+
+<style lang="scss" scoped  type="text/css">
+.cell {
+  background: #f7f7f7;
+  margin-top: 20px;
+  padding: 20px;
+  border-radius: 8px;
+  .cell-top {
+    display: flex;
+    align-items: center;
+    .title {
+      position: relative;
+      font-size: 16px;
+      font-weight: bold;
+      line-height: 22px;
+      color: #333333;
+      padding-left: 10px;
+    }
+    .title::before {
+      width: 3px;
+      height: 16px;
+      background: rgba(252, 114, 0, 0.39);
+      border-radius: 2px;
+      content: "";
+      position: absolute;
+      top: 2px;
+      left: 0;
+    }
+    .time {
+      font-size: 14px;
+      font-weight: 400;
+      color: #999999;
+      margin: 0 5px;
+    }
+    .status {
+      font-size: 14px;
+      font-weight: 400;
+      color: #e70012;
+      border: 1px solid #e70012;
+      padding: 0 5px;
+      border-radius: 2px;
+    }
+    .active-status {
+      color: #007aff;
+      border-color: #007aff;
+    }
+  }
+  .cell-bot {
+    margin-top: 40px;
+    .title1 {
+      line-height: 22px;
+      font-size: 16px;
+      font-weight: bold;
+      color: #333333;
+    }
+  }
+  .content {
+    font-size: 14px;
+    font-weight: 400;
+    color: #333333;
+    line-height: 20px;
+    margin-top: 10px;
+  }
+  .img-list {
+    display: flex;
+    margin-top: 10px;
+    .img {
+      width: 120px;
+      height: 120px;
+      margin-right: 20px;
+      cursor: pointer;
+    }
+  }
+}
+</style>

+ 179 - 16
src/components/manualCreate.vue

@@ -11,7 +11,6 @@
               个人地址发单
             </div>
           </div>
-
           <el-form-item :label="sendType ? '发件门店' : '发件人姓名'" required>
             <el-input v-show="!sendType" size="small" class="input" v-model="form.sendAddress.contact" placeholder="请填写发件人姓名" clearable></el-input>
             <el-input v-show="sendType" disabled size="small" class="input" v-model="name" placeholder="请填写发件门店"></el-input>
@@ -71,6 +70,14 @@
               <el-radio class="item" v-for="(item,i) in products" :key="i" :label="item.id">{{item.name}}</el-radio>
             </el-radio-group>
           </el-form-item>
+          <el-form-item label="物品来源" required>
+            <el-select size="small" class="item1" v-model="form.platformType" placeholder="请选择物品来源">
+              <el-option v-for="(v,i) in goodsSource" :key="i" :label="v.name" :value="v.type"></el-option>
+            </el-select>
+            <!-- <el-input v-if="form.platformType" type="number" class="item2" v-model="form.daySeq" size="small" placeholder="请输入订单流水号"></el-input> -->
+            <el-input v-if="form.platformType" type="text" class="item2" v-model="form.daySeq" @input="checkDaySeq()" size="small" :min="1" placeholder="请输入订单流水号"></el-input>
+            <div class="tips" v-else>系统将自动为您分配订单流水号</div>
+          </el-form-item>
           <el-form-item label="物品重量" required>
             <div class="printer-num">
               <img @click="reduce()" src="../../static/image/icon_reduce.png" class="reduce" alt="" srcset="" />
@@ -94,7 +101,7 @@
             </el-date-picker>
           </el-form-item>
           <el-form-item label="发单备注">
-            <el-input type="text" size="small" v-model="form.takeRemark" maxlength="20" placeholder="请添加备注信息,最多输入20个字!" clearable show-word-limit>
+            <el-input type="text" size="small" v-model="form.takeRemark" maxlength="80" placeholder="请添加备注信息,最多输入20个字!" clearable show-word-limit>
             </el-input>
           </el-form-item>
         </div>
@@ -123,11 +130,14 @@
           </el-input>
         </div>
         <div class="shop-list">
-          <div @dblclick="chooseShop" @click="curIdx = index" :class=" curIdx === index ? 'shop-item active' : 'shop-item'" v-for="(shop,index) in addressList" :key="index">
-            <div class="name">{{shop.name}}</div>
-            <div class="phone">{{shop.contact + ' ' + shop.phone}}</div>
-            <div class="address">{{shop.districtName + shop.address}}</div>
-          </div>
+          <template v-if="addressList.length">
+            <div @dblclick="chooseShop" @click="curIdx = index" :class=" curIdx === index ? 'shop-item active' : 'shop-item'" v-for="(shop,index) in addressList" :key="index">
+              <div class="name">{{shop.name}}</div>
+              <div class="phone">{{shop.contact + ' ' + shop.phone}}</div>
+              <div class="address">{{shop.districtName + shop.address}}</div>
+            </div>
+          </template>
+          <el-empty v-else :description="`暂无可用${addressType === 1 ? '门店' : '地址'}`"></el-empty>
         </div>
         <span slot="footer" class="dialog-footer">
           <el-button size="small" @click="showChooseShop = false">取 消</el-button>
@@ -149,15 +159,22 @@
 </template>
 <script>
 import orderMap from "./orderComponents/orderAMap.vue";
-import addressManagement from "./addressManagement.vue";
+import addressManagement from "./settingComponents/addressManagement.vue";
 import { getProductList } from "../api/shop.js";
 import { getConfig } from "../api/setting.js";
-import { sendValuation, saveOrder, getAddressList } from "../api/order.js";
+import {
+  sendValuation,
+  saveOrder,
+  getAddressList,
+  getResource,
+  getOrderDetail,
+} from "../api/order.js";
 import sendOrderPopup from "../components/orderComponents/sendOrderPopup.vue";
 export default {
   name: "manualCreate",
   data() {
     return {
+      goodsSource: [],
       products: [],
       addressType: 1,
       name: "",
@@ -198,6 +215,7 @@ export default {
         invoiceTitle: "",
         taxpayerId: "",
         transport: "0",
+        platformType: 0,
       },
       chooseMapAddress: 1, // 1 发件选择地址2 收件选择地址
       showChooseShop: false,
@@ -221,6 +239,7 @@ export default {
       showAddress: false,
       personalSendAddressId: "",
       personalReceiptAddressId: "",
+      orderId: "",
     };
   },
   components: {
@@ -261,11 +280,129 @@ export default {
   },
   // 生命周期 - 创建完成(可以访问当前this实例)
   created() {
+    this.orderId = this.$route.params.orderId;
+    if (this.orderId) {
+      this.sendType = 0;
+      this.getOrderDetail();
+    }
     this.getProductList();
     this.getData();
+    this.getResource();
   },
   // 方法集合
   methods: {
+    checkDaySeq() {
+      console.log("checkDaySeq:", typeof this.form.daySeq);
+      this.form.daySeq = this.form.daySeq.replace(/\D|^0/g, "");
+    },
+    getOrderDetail() {
+      getOrderDetail({ orderId: this.orderId }).then((res) => {
+        console.log("再来一单订单详情:", res);
+        if (res.code === 200) {
+          let data = res.data;
+          let nowTime = new Date().getTime();
+          let takeTime = new Date(data.takeTime).getTime();
+          if (
+            nowTime - takeTime >
+              this.$store.state.userInfo.privateNumberInvalidTime *
+                60 *
+                60 *
+                1000 &&
+            data.receiptPhone.length > 11
+          ) {
+            this.$confirm(
+              "当前收件人手机号为隐私号,骑手可能无法联系收件人!建议填写用户真实手机号",
+              "提醒",
+              {
+                confirmButtonText: "我知道了",
+                showCancelButton: false,
+                center: true,
+              }
+            );
+          }
+          let receiptPhone = data.receiptPhone;
+          let receiptExtension = data.receiptExtension;
+          let sendPhone = data.sendPhone;
+          let sendExtension = data.sendExtension;
+          if (data.receiptPhone.length > 11) {
+            receiptPhone = data.receiptPhone.slice(0, 11);
+            receiptExtension = data.receiptPhone.slice(12);
+          }
+          if (data.sendPhone.length > 11) {
+            sendPhone = data.sendPhone.slice(0, 11);
+            sendExtension = data.sendPhone.slice(12);
+          }
+          this.form = {
+            createType: "",
+            invoiceTitle: "",
+            isWaimai: false,
+            name: "",
+            productAmount: data.productAmount,
+            productId: data.productId,
+            receiptAddress: {
+              name: "",
+              address: data.receiptAddress,
+              cityCode: data.receiptCityCode,
+              cityName: data.receiptCityName,
+              contact: data.receiptContactName,
+              districtName: data.receiptDistrictName,
+              id: data.receiptAddressId,
+              isDefault: "",
+              lat: data.receiptLat,
+              lng: data.receiptLng,
+              phone: receiptPhone,
+              extension: receiptExtension ?? "",
+              provinceName: data.receiptProvinceName || data.sendProvinceName,
+              street: data.receiptStreet,
+              type: "",
+            },
+            sendAddress: {
+              name: "",
+              address: data.sendAddress,
+              cityCode: data.sendCityCode,
+              cityName: data.sendCityName,
+              contact: data.sendContactName,
+              districtName: data.sendDistrictName,
+              id: data.sendAddressId,
+              lat: data.sendLat,
+              lng: data.sendLng,
+              phone: sendPhone,
+              extension: sendExtension ?? "",
+              provinceName: data.sendProvinceName,
+              street: data.sendStreet,
+            },
+            shopId: data.waimaiOrderId ? data.shopId : "",
+            takeRemark: data.caution ?? "" + data.takeRemark ?? "",
+            takeTime: "",
+            takeType: "",
+            taxpayerId: "",
+            transport: 0,
+            type: "",
+            weight: data.weight,
+            platformType: data.orderType ?? data.platformType,
+            daySeq: data.daySeq,
+          };
+        } else {
+          this.$message({
+            type: "error",
+            message: res.msg,
+          });
+        }
+      });
+    },
+    getResource() {
+      getResource().then((res) => {
+        if (res.code === 200) {
+          this.goodsSource = res.data;
+          this.form.platformType = this.goodsSource[0].type;
+        } else {
+          this.$message({
+            type: "error",
+            message: res.msg,
+          });
+        }
+      });
+    },
     closeAddress() {
       this.getData();
     },
@@ -330,7 +467,6 @@ export default {
             this.curIdx = this.addressList.findIndex((v) => {
               return v.id === shopId;
             });
-            console.log("sendAddress1", sendAddress);
             Object.keys(this.form.sendAddress).map((v) => {
               this.form.sendAddress[v] = sendAddress ? sendAddress[v] : "";
             });
@@ -353,7 +489,6 @@ export default {
                 return v.isDefault;
               });
             }
-            console.log("sendAddress2", sendAddress);
             Object.keys(this.form.sendAddress).map((v) => {
               this.form.sendAddress[v] = sendAddress ? sendAddress[v] : "";
             });
@@ -366,7 +501,6 @@ export default {
             this.curIdx = this.addressList.findIndex((v) => {
               return v.id === this.personalReceiptAddressId;
             });
-            console.log("receiptAddress", receiptAddress);
             Object.keys(this.form.receiptAddress).map((v) => {
               this.form.receiptAddress[v] = receiptAddress
                 ? receiptAddress[v]
@@ -458,8 +592,18 @@ export default {
           message: "请先选择收件人地址!",
         });
       }
-      let reg = new RegExp(/^([1-4][0-9]{0,1}|50)$/);
-      if (!reg.test(Number(this.form.weight))) {
+      if (this.form.platformType && !this.form.daySeq) {
+        return this.$message({
+          type: "error",
+          message: "请填写平台流水号!",
+        });
+      }
+
+      let reg = new RegExp(/^[1-9]\d*$/g);
+      if (
+        !reg.test(Number(this.form.weight)) ||
+        Number(this.form.weight) > 50
+      ) {
         this.$refs.weight.focus();
         return this.$message({
           type: "error",
@@ -520,7 +664,6 @@ export default {
                   });
                 })
                 .catch((action) => {
-                  console.log("action:", action);
                   if (action === "close") {
                     return;
                   } else {
@@ -567,6 +710,12 @@ export default {
       sendValuation(this.form).then((res) => {
         this.isLoading = false;
         if (res.code == 200) {
+          if (!res.data.optionals || !res.data.optionals.length) {
+            return this.$message({
+              type: "error",
+              message: `暂无可用运力!`,
+            });
+          }
           res.data.optionals.forEach((item) => {
             item.optionals = item.optionals ? item.optionals : [];
             item.lowOptionals = item.lowOptionals ? item.lowOptionals : [];
@@ -676,6 +825,20 @@ export default {
       .phone-after {
         width: 70px;
       }
+      .item1 {
+        width: 190px;
+      }
+      .item2 {
+        margin-left: 20px;
+        width: 50%;
+      }
+      /deep/ .item2 .el-input__inner {
+        text-align: center;
+      }
+      .tips {
+        margin-left: 20px;
+        color: #999999;
+      }
       .map {
         height: 25px;
         width: 25px;
@@ -797,7 +960,7 @@ export default {
     }
   }
   .shop-list {
-    height: 60vh;
+    height: 55vh;
     overflow: scroll;
     .shop-item {
       border: 1px solid #999;

+ 393 - 13
src/components/orderComponents/orderDetail.vue

@@ -6,7 +6,9 @@
         <div class="detail_title2">商品详情</div>
         <div class="shop_detail" v-for="(item,i) in orderDetail.detailItems" :key="i">
           <div class="info">
-            <img v-if="item.foodPic" :src="item.foodPic" alt="" srcset="">
+            <el-image v-if="item.foodPic" class="img" :src="item.foodPic" :preview-src-list="showPreview">
+            </el-image>
+            <img v-else class="img" src="../../../static/image/empty-img.png" alt="" srcset="">
             <div class="shop_title">{{item.foodName}}</div>
           </div>
           <div class="shop_num">x{{item.quantity}}</div>
@@ -25,15 +27,23 @@
         </div>
         <div class="detail_ine"></div>
       </template>
+      <template v-if="orderDetail.cardInfo">
+        <div class="info2">
+          <div class="title">贺卡内容:</div>
+          <div class="cont cont1">{{initCardInfo(orderDetail.cardInfo)}}</div>
+        </div>
+        <div class="card" v-if="$store.state.userInfo.isOpenCardPrint">
+          <div @click="showPrintCard" class="print-card">打印贺卡{{orderDetail.cardPrintNum ? `(${orderDetail.cardPrintNum})` : ''}}</div>
+        </div>
+        <div class="detail_ine"></div>
+      </template>
       <template v-if="orderDetail.caution || orderDetail.takeRemark">
         <div class="info2" v-if="orderDetail.caution">
           <div class="title">用户备注:</div>
-          <!-- <div class="cont cont1">{{orderDetail.caution.length > 60 ? orderDetail.caution.slice(0,60) + '...' : orderDetail.caution}}</div> -->
           <div class="cont cont1">{{orderDetail.caution}}</div>
         </div>
         <div class="info2 info3" v-if="orderDetail.takeRemark">
           <div class="title">发单备注:</div>
-          <!-- <div class="cont cont1">{{orderDetail.takeRemark.length > 60 ? orderDetail.takeRemark.slice(0,60) + '...' : orderDetail.takeRemark}}</div> -->
           <div class="cont cont1">{{orderDetail.takeRemark}}</div>
         </div>
         <div class="detail_ine"></div>
@@ -53,11 +63,11 @@
       <template v-if="orderDetail.sendAddress || orderDetail.receiptAddress">
         <div class="detail_title2">地址信息</div>
         <div class="info2 info4" v-if="orderDetail.sendAddress">
-          <div class="title">发件地址:</div>
+          <div class="title">{{orderDetail.outOrderId ? '发货门店:' : '发货地址:'}}</div>
           <div class="cont">{{orderDetail.sendAddress}}</div>
         </div>
         <div class="info2 info4" v-if="orderDetail.receiptAddress">
-          <div class="title">收地址:</div>
+          <div class="title">收地址:</div>
           <div class="cont">{{orderDetail.receiptAddress}}</div>
         </div>
         <div class="detail_ine"></div>
@@ -87,15 +97,23 @@
       </template>
       <div class="detail_ine"></div>
       <div class="detail_title2">订单金额</div>
-      <div class="info2 info4">
+      <!-- <div class="info2 info4">
         <div class="title">商品金额:</div>
         <div class="cont">{{orderDetail.productAmount ? '¥' + orderDetail.productAmount : '--'}}</div>
+      </div> -->
+      <div class="info2 info4">
+        <div class="title">顾客实付:</div>
+        <div class="cont">{{orderDetail.productAmount ? '¥' + orderDetail.productAmount : '--'}}</div>
       </div>
+      <!-- <div class="info2 info4">
+        <div class="title">商户实收:</div>
+        <div class="cont">{{orderDetail.productAmount ? '¥' + orderDetail.productAmount : '--'}}</div>
+      </div> -->
       <div class="detail_ine"></div>
       <div class="detail_title2">订单信息</div>
       <div class="info2 info4" v-if="orderDetail.waimaiOrderId">
-        <div class="title">送达时间:</div>
-        <div class="cont cont2">{{ !orderDetail.exceptTime ? '立即送达' : orderDetail.exceptTime}}</div>
+        <div class="title">期望送达时间:</div>
+        <div class="cont cont2">{{ exceptTimeFn()}}</div>
       </div>
       <div class="info2 info4" v-if="orderDetail.deliveryTime && buttonStatus === 10 && !orderDetail.waimaiOrderId">
         <div class="title">预约发单时间:</div>
@@ -122,21 +140,134 @@
         <div class="cont">{{orderDetail.outOrderId}}</div>
       </div>
     </div>
+    <!-- 打印贺卡 -->
+    <div class="wrap-card" @click="dialogVisible=false" v-show="dialogVisible">
+      <div @click.stop="" class="print-con" :style="`width:${this.params.cardWidth+10}mm;`">
+        <div class="print-head">
+          <div class="but-item" :class="[fontSize===50?'disabled':'']" @click="fontEnlarge">
+            <img class="img" src="../../../static/image/icon-big.png" alt="">
+            <div class="name">放大</div>
+          </div>
+          <div class="but-item" :class="[fontSize===20?'disabled':'']" @click="fontNarrow">
+            <img class="img" src="../../../static/image/icon-small.png" alt="">
+            <div class="name">缩小</div>
+          </div>
+          <div class="but-item" @click="fontLeft">
+            <img class="img" src="../../../static/image/icon-left.png" alt="">
+            <div class="name">居左</div>
+          </div>
+          <div class="but-item" @click="fontCenter">
+            <img class="img" src="../../../static/image/icon-center.png" alt="">
+            <div class="name">居中</div>
+          </div>
+          <div class="but-item" @click="fontRight">
+            <img class="img" src="../../../static/image/icon-right.png" alt="">
+            <div class="name">居右</div>
+          </div>
+          <div class="but-item" @click="resetPrint">
+            <img class="img" src="../../../static/image/icon-reset.png" alt="">
+            <div class="name">恢复</div>
+          </div>
+          <div class="but-item" @click="print">
+            <img class="img" src="../../../static/image/icon-print.png" alt="">
+            <div class="name name1">打印</div>
+          </div>
+        </div>
+        <div class="print-html">
+          <i class="el-icon-arrow-down icon1" :style="`top:${params.paddingTop}mm;left:${params.paddingLeft}mm;`"></i>
+          <i class="el-icon-arrow-down icon2" :style="`top:${params.paddingTop}mm;right:${params.paddingRight}mm;`"></i>
+          <i class="el-icon-arrow-down icon3" :style="`bottom:${params.paddingBottom}mm;left:${params.paddingLeft}mm;`"></i>
+          <i class="el-icon-arrow-down icon4" :style="`bottom:${params.paddingBottom}mm;right:${params.paddingRight}mm;`"></i>
+          <div ref="html" v-html="printHtml"></div>
+        </div>
+      </div>
+    </div>
   </div>
 
 </template>
     
 <script>
+import { cloudPrint, printConfig } from "../../api/shop";
+import bus from "../../common/bus.js";
 export default {
   name: "OrderDetail",
   data() {
-    return {};
+    return {
+      dialogVisible: false,
+      printContent: "",
+      fontSize: 30,
+      textAlign: "center",
+      params: {
+        cardWidth: 210,
+        cardHeight: 297,
+        paddingTop: 10,
+        paddingBottom: 10,
+        paddingLeft: 10,
+        paddingRight: 10,
+        direction: 1, // 1:竖向 2:横向左 3:横向右
+        fontFamily: "FangZhengKaiTi",
+        shopIdList: [0],
+        sizeType: 9, // 纸张尺寸
+      },
+    };
   },
   props: {
     buttonStatus: Number,
     orderDetail: Object,
   },
+  computed: {
+    showPreview() {
+      return this.orderDetail.detailItems.map((v) => {
+        return v.foodPic;
+      });
+    },
+    printHtml() {
+      return `<style type="text/css">
+                @font-face {
+                  font-family: ${this.params.fontFamily};
+                  src: url("https://h5.liebaoai.cn/font/${
+                    this.params.fontFamily
+                  }.woff2") format('woff2'),
+                        url("https://h5.liebaoai.cn/font/${
+                          this.params.fontFamily
+                        }.woff") format('woff'),
+                        url("https://h5.liebaoai.cn/font/${
+                          this.params.fontFamily
+                        }.ttf") format('truetype');
+                  font-weight: normal;
+                  font-style: normal;
+                }
+                .card-left {
+                  position: relative;
+                  height: ${this.params.cardHeight}mm;
+                  width: ${this.params.cardWidth}mm;
+                  display:flex;
+                  ${this.contentStyle(1)[0]}
+                }
+                .card-con {
+                  margin-top: ${this.params.paddingTop}mm;
+                  margin-right: ${this.params.paddingRight}mm;
+                  margin-bottom: ${this.params.paddingBottom}mm;
+                  margin-left: ${this.params.paddingLeft}mm;
+                  text-align: ${this.textAlign};
+                  outline:none;
+                  font-family: ${this.params.fontFamily};
+                  font-size:${this.fontSize}px;
+                  ${this.contentStyle(1)[1]}
+                }
+              </style>
+              <div class="card-left">
+                <div id="card-con" class="card-con" contenteditable="true">
+                  ${this.printContent}
+                </div>
+              </div>`;
+    },
+  },
   methods: {
+    exceptTimeFn() {
+      let con = this.orderDetail.exceptTime || this.orderDetail.takeDate;
+      return con || "立即送达";
+    },
     takeOUtType(type) {
       let name = "";
       switch (type) {
@@ -156,6 +287,162 @@ export default {
       }
       return name;
     },
+    initCardInfo(cardInfo) {
+      let info = cardInfo.split("[其他备注]")[0].slice(6);
+      return info;
+    },
+    async showPrintCard() {
+      let res = await printConfig({ shopId: this.orderDetail.shopId });
+      console.log(res);
+      if (res.code !== 200) {
+        this.$message.error(res.msg);
+        return;
+      }
+      this.params = res.data;
+      this.dialogVisible = true;
+      this.printContent = this.initCardInfo(this.orderDetail.cardInfo);
+    },
+    print() {
+      let html = this.$refs.html.innerHTML;
+      if (this.params.direction === 2) {
+        html = html.replace(
+          `height: ${this.params.cardHeight}mm;`,
+          `height: ${this.params.cardWidth}mm;`
+        );
+        html = html.replace(
+          `width: ${this.params.cardWidth}mm;`,
+          `width: ${this.params.cardHeight}mm;`
+        );
+        console.log("html:", html);
+      }
+      let params = {
+        orderId: this.orderDetail.orderId,
+        shopId: this.orderDetail.shopId,
+        jobFile: html,
+      };
+      cloudPrint(params).then((res) => {
+        console.log("云盒打印信息", res);
+        if (res.code === 200) {
+          this.$message({
+            type: "success",
+            message: `成功发送云盒打印任务!`,
+          });
+          this.$emit("getDetailOrder");
+          this.dialogVisible = false;
+        } else {
+          this.$message({
+            type: "error",
+            message: res.msg,
+          });
+        }
+      });
+    },
+    fontEnlarge() {
+      if (this.fontSize === 50) return;
+      this.printContent = document.getElementById("card-con").innerHTML;
+      this.fontSize += 5;
+    },
+    fontNarrow() {
+      if (this.fontSize === 20) return;
+      this.printContent = document.getElementById("card-con").innerHTML;
+      this.fontSize -= 5;
+    },
+    fontLeft() {
+      this.printContent = document.getElementById("card-con").innerHTML;
+      this.textAlign = "left";
+    },
+    fontCenter() {
+      this.printContent = document.getElementById("card-con").innerHTML;
+      this.textAlign = "center";
+    },
+    fontRight() {
+      this.printContent = document.getElementById("card-con").innerHTML;
+      this.textAlign = "right";
+    },
+    resetPrint() {
+      this.fontSize = 35;
+      this.textAlign = "center";
+    },
+    contentStyle(direction) {
+      let style = ``;
+      let transform = ``;
+      if (direction === 1) {
+        switch (this.params.textAlign) {
+          case 1:
+            style = `justify-content:flex-start;align-items:flex-start;`;
+            break;
+          case 2:
+            style = `justify-content:flex-start;align-items:center;`;
+            break;
+          case 3:
+            style = `justify-content:flex-start;align-items:flex-end;`;
+            break;
+          case 4:
+            style = `justify-content:center;align-items:flex-start;`;
+            break;
+          case 5:
+            style = `justify-content:center;align-items:center;`;
+            break;
+          case 6:
+            style = `justify-content:center;align-items:flex-end;`;
+            break;
+          case 7:
+            style = `justify-content:flex-end;align-items:flex-start;`;
+            break;
+          case 8:
+            style = `justify-content:flex-end;align-items:center;`;
+            break;
+          case 9:
+            style = `justify-content:flex-end;align-items:flex-end;`;
+            break;
+          default:
+            break;
+        }
+      } else {
+        switch (this.params.textAlign) {
+          case 1:
+            style = `justify-content:flex-end;align-items:flex-start;`;
+            transform = `transform: translateX(100%) rotate(90deg);transform-origin: left top;`;
+            break;
+          case 2:
+            style = `justify-content:center;align-items:flex-start;`;
+            transform = `transform: translateX(50%) translateY(-50%) rotate(90deg);transform-origin: left;`;
+            break;
+          case 3:
+            style = `justify-content:flex-start;align-items:flex-start;`;
+            transform = `transform: translateY(-100%) rotate(90deg);transform-origin: left bottom;`;
+            break;
+          case 4:
+            style = `justify-content:flex-end;align-items:center;`;
+            transform = `transform: translateX(50%) rotate(90deg);transform-origin: center top;`;
+            break;
+          case 5:
+            style = `justify-content:center;align-items:center;`;
+            transform = `transform: rotate(90deg);`;
+            break;
+          case 6:
+            style = `justify-content:flex-start;align-items:center;`;
+            transform = `transform: translateX(-50%) rotate(90deg);`;
+            break;
+          case 7:
+            style = `justify-content:flex-end;align-items:flex-end;`;
+            transform = `transform: translatey(100%) rotate(90deg);transform-origin: right top;`;
+            break;
+          case 8:
+            style = `justify-content:center;align-items:flex-end;`;
+            transform = `transform: translateX(-50%) translateY(50%) rotate(90deg);transform-origin:right;`;
+            break;
+          case 9:
+            style = `justify-content:flex-start;align-items:flex-end;`;
+            transform = `transform: translateX(-100%) rotate(90deg);transform-origin:right bottom;`;
+            break;
+          default:
+            break;
+        }
+      }
+
+      return [style, transform];
+    },
   },
 };
 </script>
@@ -170,9 +457,9 @@ export default {
   box-sizing: border-box;
   .detail_title2 {
     width: 100%;
-    font-size: 12px;
+    font-size: 13px;
     font-weight: 600;
-    color: #777777;
+    color: #333333;
     margin-bottom: 15px;
   }
   .shop_detail {
@@ -184,7 +471,8 @@ export default {
       flex-grow: 1;
       display: flex;
       align-items: flex-start;
-      img {
+      .img {
+        flex-shrink: 0;
         width: 47px;
         height: 47px;
         border-radius: 4px 4px 4px 4px;
@@ -208,6 +496,23 @@ export default {
     border-top: 2px dotted #f0f0f0;
     margin: 16px 0;
   }
+  .card {
+    display: flex;
+    justify-content: flex-end;
+    .print-card {
+      font-size: 12px;
+      width: 80px;
+      height: 25px;
+      line-height: 25px;
+      text-align: center;
+      border: 1px solid #fc7200;
+      background: #fc7200;
+      color: #ffffff;
+      border-radius: 4px;
+      cursor: pointer;
+      margin-bottom: 10px;
+    }
+  }
   .info2 {
     width: 100%;
     display: flex;
@@ -217,7 +522,7 @@ export default {
       font-size: 14px;
       font-weight: 400;
       // width: 80px;
-      color: #b1b1b1;
+      color: #999999;
     }
     .cont {
       font-size: 14px;
@@ -242,4 +547,79 @@ export default {
     justify-content: space-between;
   }
 }
+
+.wrap-card {
+  position: fixed;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  left: 0;
+  overflow: auto;
+  background: rgba($color: #000000, $alpha: 0.5);
+  z-index: 2004;
+  .print-con {
+    border: 1px solid #ebe7e7;
+    background: #fff;
+    margin: 15vh auto 0;
+    .print-head {
+      display: flex;
+      align-items: center;
+      justify-content: space-around;
+      background: #ebe7e7;
+      padding: 10px 0;
+      .disabled {
+        opacity: 0.5;
+        cursor: not-allowed !important;
+      }
+      .but-item {
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        cursor: pointer;
+        flex: 1;
+        .img {
+          width: 25px;
+          height: 25px;
+        }
+        .name {
+          font-size: 13px;
+          font-weight: bold;
+          color: #333333;
+          margin-top: 5px;
+        }
+        .name1 {
+          color: #fc7200;
+        }
+      }
+    }
+    .print-html {
+      position: relative;
+      padding: 5mm;
+      /deep/ .el-icon-arrow-down {
+        position: absolute;
+        font-size: 30px;
+      }
+      .icon1 {
+        top: 10mm;
+        left: 10mm;
+        transform: rotate(-45deg);
+      }
+      .icon2 {
+        top: 10mm;
+        right: 10mm;
+        transform: rotate(45deg);
+      }
+      .icon3 {
+        bottom: 10mm;
+        left: 10mm;
+        transform: rotate(-135deg);
+      }
+      .icon4 {
+        bottom: 10mm;
+        right: 10mm;
+        transform: rotate(135deg);
+      }
+    }
+  }
+}
 </style>

+ 172 - 87
src/components/orderComponents/orderList.vue

@@ -13,14 +13,14 @@
             </div>
           </div>
           <order-track v-show="showTrack" :riderArriveTime="riderArriveTime" :buttonStatus="buttonStatus" :trackOrder="trackOrder" v-if="!orderDetailStutus && needTrack"></order-track>
-          <order-detail v-show="showDetail" :buttonStatus="buttonStatus" :orderDetail="orderDetail" v-else></order-detail>
+          <order-detail v-show="showDetail" :buttonStatus="buttonStatus" @getDetailOrder="getDetailOrder" :orderDetail="orderDetail" v-else></order-detail>
           <!-- 订单跟踪、订单详情底部按钮 -->
           <div class="bottom-btns" v-show="showDetail || showTrack">
             <!-- 新订单 -->
             <div class="btns" v-if="buttonStatus === 0">
               <el-button size="small" @click.native="itemAddRemark(list[curIdx].id, list[curIdx])" class="btn_bots">添加备注</el-button>
-              <el-button size="small" @click.native="iGnoreOrder(list[curIdx].id)" class="btn_bots">忽略订单</el-button>
               <el-button size="small" @click.native="orderPrinter(list[curIdx].waimaiOrderId,list[curIdx].id)" class="btn_bots">补打小票</el-button>
+              <el-button size="small" @click.native="iGnoreOrder(list[curIdx].id)" class="btn_bots btn">忽略订单</el-button>
               <el-button size="small" @click.native="sendNow(list[curIdx])" class="btn_bots btn">发起配送</el-button>
             </div>
             <!-- 预约单 -->
@@ -30,19 +30,17 @@
                   <span class="el-dropdown-link">更多</span>
                   <el-dropdown-menu slot="dropdown">
                     <el-dropdown-item @click.native="orderPrinter(list[curIdx].waimaiOrderId,list[curIdx].id)"><span style="color: #fc7200">补打小票</span></el-dropdown-item>
-                    <el-dropdown-item @click.native="iGnoreOrder(list[curIdx].id)">忽略订单</el-dropdown-item>
+                    <el-dropdown-item @click.native="itemAddRemark(list[curIdx].id, list[curIdx])">添加备注</el-dropdown-item>
                   </el-dropdown-menu>
                 </el-dropdown>
               </div>
-              <el-button size="small" @click.native="itemAddRemark(list[curIdx].id, list[curIdx])" class="btn_bots">添加备注</el-button>
+              <el-button v-else size="small" @click.native="itemAddRemark(list[curIdx].id, list[curIdx])" class="btn_bots">添加备注</el-button>
               <el-button v-if="list[curIdx].waimaiOrderId" size="small" @click.native="settingTime(list[curIdx])" class="btn_bots btn">{{
-                  list[curIdx].delayTime ? "修改定时" : "定时发单"
+                  list[curIdx].delayTime ? "修改定时" : "预约发单"
                 }}</el-button>
               <el-button v-else size="small" @click.native="cancelOrder(list[curIdx].id)" class="btn_bots">取消订单</el-button>
-
+              <el-button size="small" @click.native="iGnoreOrder(list[curIdx].id)" class="btn_bots btn">忽略订单</el-button>
               <el-button size="small" @click.native="sendNow(list[curIdx])" class="btn_bots btn">发起配送</el-button>
-              <!-- <el-dropdown-item @click.native="orderPrinter(list[curIdx].waimaiOrderId,list[curIdx].id)"><span style="color: #fc7200">补打小票</span></el-dropdown-item> -->
-
             </div>
             <!-- 待接单 -->
             <div class="btns" v-if="buttonStatus === 1">
@@ -58,15 +56,26 @@
             <!-- 配送中 -->
             <div class="btns" v-if="buttonStatus === 3">
               <el-button size="small" @click.native="orderPrinter(list[curIdx].waimaiOrderId)" v-if="list[curIdx].waimaiOrderId" class="btn_bots btn">补打小票</el-button>
+              <!-- <el-button size='small' @click.native="againOrder(list[curIdx])" class="btn_bots btn">再来一单</el-button> -->
             </div>
             <!-- 异常单 -->
             <div class="btns" v-if="buttonStatus === -2">
               <el-button size="small" @click.native="orderPrinter(list[curIdx].waimaiOrderId,list[curIdx].id)" v-if="list[curIdx].waimaiOrderId" class="btn_bots">补打小票</el-button>
               <el-button size="small" @click.native="orderBack(list[curIdx].id)" class="btn_bots btn">撤回订单</el-button>
+              <el-button size="small" @click.native="againSend(list[curIdx])" class="btn_bots btn">再次配送</el-button>
             </div>
             <!-- 已取消 -->
             <div class="btns" v-if="buttonStatus === -1">
-              <!-- <el-button size='small' @click.native="orderPrinter(list[curIdx].waimaiOrderId,list[curIdx].id)" class="btn_bots btn">再来一单</el-button> -->
+              <el-button size="small" @click.native="orderPrinter(list[curIdx].waimaiOrderId)" v-if="list[curIdx].waimaiOrderId&&list[curIdx].cancelType===4" class="btn_bots">补打小票</el-button>
+              <el-button size='small' @click.native="againSend(list[curIdx])" class="btn_bots btn">再次配送</el-button>
+            </div>
+            <!-- 已完成 -->
+            <div class="btns" v-if="buttonStatus === 97">
+              <el-button size='small' @click.native="againSend(list[curIdx])" class="btn_bots btn">再次配送</el-button>
+            </div>
+            <!-- 其他平台已完成 -->
+            <div class="btns" v-if="buttonStatus === 98">
+              <el-button size='small' @click.native="againSend(list[curIdx])" class="btn_bots btn">再次配送</el-button>
             </div>
           </div>
         </div>
@@ -75,23 +84,23 @@
     <el-row class="list-info">
       <el-col :span="17">
         <div v-loading="isLoading" element-loading-text="正在计算中...">
-          <div :class="
-              curIdx === i ? 'order_item active-order-item' : 'order_item'
-            " @click="chooseOrder(item, i)" v-for="(item, i) in list" :key="i">
+          <div class="order_item" @click="chooseOrder(item, i)" v-for="(item, i) in list" :key="i">
             <div class="order_item_header">
               <div class="order_item_header_l">
-                <div v-if="item.daySeq" class="Serial_number">
+                <div v-if="item.daySeq" class="Serial_number" :style="daySeqColor(item.orderType)">
                   #{{ item.daySeq }}
                 </div>
                 <img :src="item.logo || item.waimaiLogo" class="logo" />
                 <span class="name">{{ item.shopName }}</span>
-                <!-- <span class="name">{{item.sendAddress}}</span> -->
-                <div class="sign_time" v-if="item.waimaiOrderId && [1,2].includes(item.takeType)">
+                <div class="sign_txt">
+                  {{ exceptTimeFn(item) }}
+                </div>
+                <!-- <div class="sign_time" v-if="item.waimaiOrderId && [1,2].includes(item.takeType)">
                   {{ item.exceptTime.slice(5,16) }}前送达
                 </div>
                 <div class="sign_txt" v-if="item.buttonStatus === 0 && item.waimaiOrderId && item.takeType == 0">
                   立即送达,{{item.orderTime.slice(-8,-3)}}下单
-                </div>
+                </div> -->
                 <div class="sign_d" v-if="item.buttonStatus === 10 && item.timeTxt">{{item.timeTxt}}自动发起配送</div>
 
                 <div v-if="item.buttonStatus === 10 && !item.waimaiOrderId" class="sign_d">{{item.deliveryTime.slice(5)}}自动发起配送</div>
@@ -100,18 +109,16 @@
               </div>
               <!-- 新订单 -->
               <div class="order_item_header_r" v-if="item.buttonStatus === 0">
-                <!-- <span class="header_r">已发单1分钟</span> -->
                 <el-tag v-if="[-1,7].includes(tabNum)" class="header_r">新订单</el-tag>
                 <el-button size="small" class="btn" @click.stop="sendNow(item)">发起配送</el-button>
               </div>
               <!-- 预约单 -->
               <div class="order_item_header_r" v-if="item.buttonStatus === 10">
-                <!-- <span class="header_r">已发单1分钟</span> -->
                 <el-tag v-if="[-1,7].includes(tabNum)" class="header_r">预约单</el-tag>
                 <!-- <el-button size='small' @click.stop="iGnoreOrder(item.id)">忽略订单</el-button> -->
                 <!-- <el-button size='small' @click.stop="itemAddRemark(item.id, item)">添加备注</el-button> -->
                 <el-button v-if="item.waimaiOrderId" size="small" class="btn" @click.stop="settingTime(item)">{{
-                  item.delayTime ? "修改定时" : "定时发单"
+                  item.delayTime ? "修改定时" : "预约发单"
                 }}</el-button>
 
                 <el-button v-else size="small" class="btn" @click.stop="sendNow(item)">立即配送</el-button>
@@ -149,31 +156,31 @@
                 <el-tag class="header_r">{{
                   showCancelType(item.cancelType)
                 }}</el-tag>
-                <!-- <el-button size='small' class="btn" @click.stop="orderBack(item.id)">撤回订单</el-button> -->
+                <!-- <el-button v-if="item.cancelType===4&&item.waimaiOrderId" size='small' class="btn" @click.stop="orderPrinter(item.waimaiOrderId,item.id)">补打小票</el-button> -->
+                <el-button size="small" class="btn" @click.stop="againSend(item)">再次配送</el-button>
               </div>
               <!-- 猎豹平台已完成 -->
               <div class="order_item_header_r" v-if="item.buttonStatus === 97">
                 <el-tag v-if="[-1,7].includes(tabNum)" class="header_r">已完成</el-tag>
+                <el-button size="small" class="btn" @click.stop="againSend(item)">再次配送</el-button>
               </div>
               <!-- 其他平台已完成 -->
               <div class="order_item_header_r" v-if="item.buttonStatus === 98">
                 <el-tag v-if="[-1,7].includes(tabNum)" class="header_r">其他平台已完成</el-tag>
+                <el-button size="small" class="btn" @click.stop="againSend(item)">再次配送</el-button>
               </div>
             </div>
-            <div class="order_item_cont">
-              <div class="content">
-                {{ item.receiptContactName
-                }}<span>{{ item.receiptPhone }}{{item.receiptExtension ? "_" + item.receiptExtension : ""}}</span>
-              </div>
+            <div class="order_item_cont" :class="curIdx === i ?  'active_order_item_cont' : ''">
               <div class="address">
-                <!-- {{ item.receiptProvinceName }}
-                {{ item.receiptCityName }} -->
-                <!-- {{ item.receiptDistrictName }} -->
                 {{ item.receiptAddress }}
-                <span class="distance" @click.stop="checkMap(item)">
-                  <i class="el-icon-location"></i>
-                  <span>查看地图</span>
-                </span>
+                <div class="distance" @click.stop="checkMap(item)">
+                  <img class="img" src="../../../static/image/show-map-icon.png" alt="">
+                  <span class="show-map">查看地图</span>
+                </div>
+              </div>
+              <div class="content">
+                {{ item.receiptContactName
+                }}<span>{{ item.receiptPhone }}{{item.receiptExtension ? "," + item.receiptExtension : ""}}</span>
               </div>
               <div v-if="item.caution" class="itme_r">
                 备注:{{ item.caution }}
@@ -225,7 +232,7 @@
         </div>
       </div>
       <div class="text-area">
-        <el-input show-word-limit :rows="4" type="textarea" resize="none" :maxlength="50" placeholder="请输入其他原因" v-model="cancelReason"></el-input>
+        <el-input :disabled="reasonIndex < 8" show-word-limit :rows="4" type="textarea" resize="none" :maxlength="50" placeholder="请输入其他原因" v-model="cancelReason"></el-input>
       </div>
       <div style="text-align: center; margin-top: 20px">
         <el-button @click.stop="cancelStatus = false">取消</el-button>
@@ -290,8 +297,6 @@ import {
   detailOrder,
   tips,
   getRiderArriveTime,
-  getPayResult,
-  getMapData,
 } from "../../api/order.js";
 export default {
   name: "OrderList",
@@ -357,6 +362,7 @@ export default {
       exceptTime: "",
       delayTime: "", // 预约延迟时间
       riderArriveTime: {}, //骑手预计取货送达时间
+      showParentOrderSn: false,
     };
   },
   props: {
@@ -391,11 +397,75 @@ export default {
       immediate: true,
     },
   },
-  destroyed() {},
   computed: {
     ...mapState(["userInfo"]),
   },
   methods: {
+    exceptTimeFn(item) {
+      let con = item.exceptTime || item.takeDate;
+      return con ? `${con.slice(5)}前送达` : "立即送达";
+    },
+    daySeqColor(type) {
+      let bgColor = "";
+      switch (type) {
+        case 1:
+          bgColor = "#FDC502";
+          break;
+        case 2:
+          bgColor = "#2491FF";
+          break;
+        case 3:
+          bgColor = "#2491FF";
+          break;
+        case 5:
+          bgColor = "#FDC502";
+          break;
+        case 6:
+          bgColor = "#00A82D";
+          break;
+        case 7:
+          bgColor = "#2788FE";
+          break;
+        case 8:
+          bgColor = "#EE0000";
+          break;
+
+        default:
+          bgColor = "#fc7200";
+          break;
+      }
+      return { background: bgColor };
+    },
+    againSend(order) {
+      let orderCopy = this.$tool.deepClone(order);
+      if ([97, 98].includes(order.buttonStatus)) {
+        this.$confirm("当前订单已完成,确认要再次发起配送吗?", "提示", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          center: true,
+        })
+          .then(() => {
+            this.beforeValuation(orderCopy);
+          })
+          .catch(() => {});
+      } else {
+        this.beforeValuation(orderCopy);
+      }
+    },
+    beforeValuation(orderCopy) {
+      this.showParentOrderSn = true;
+      if (
+        orderCopy.waimaiOrderId &&
+        !orderCopy.addDelivery &&
+        orderCopy.buttonStatus !== -2
+      ) {
+        orderCopy.waimaiOrderId = null;
+        orderCopy.id = null;
+        orderCopy.waimaiId = null;
+        orderCopy.weight = 1;
+      }
+      this.getValuation(orderCopy);
+    },
     paySuccess() {
       this.showCode = false;
       this.addTipStatus = false;
@@ -582,6 +652,7 @@ export default {
       this.cancelStatus = true;
     },
     chooseOrder(v, index) {
+      this.curIdx = index;
       this.buttonStatus = this.list[index].buttonStatus;
       if (this.buttonStatus === 0 || this.buttonStatus === 10) {
         this.needTrack = false;
@@ -590,7 +661,6 @@ export default {
         this.needTrack = true;
         this.orderDetailStutus = 0;
       }
-      this.curIdx = index;
       this.getDetailOrder();
       this.getTrackOrder();
       this.getRiderArriveTime();
@@ -638,12 +708,6 @@ export default {
     },
     // 一键发单备注
     commitRemark(orderId, item) {
-      // if(!this.remark.trim()){
-      //   return this.$message({
-      //       message: '请输入发单备注再确认!',
-      //       type: "error",
-      //     });
-      // }
       let params = {
         orderId,
         remark: this.remark.trim(),
@@ -657,14 +721,6 @@ export default {
           });
           bus.$emit("refreshData");
           bus.$emit("refreshData2");
-          // this.$set(
-          //   this.list.find((v) => {
-          //     return item.id == v.id;
-          //   }),
-          //   "takeRemark",
-          //   this.remark
-          // );
-          // this.$forceUpdate();
         } else {
           this.$message({
             message: res.msg,
@@ -720,6 +776,7 @@ export default {
     },
     // 计价
     getValuation(order) {
+      console.log("order:", order);
       let requestData = {
         productId: order.productId,
         transport: 0,
@@ -761,6 +818,10 @@ export default {
         takeRemark: order.takeRemark || "",
         orderId: order.id,
       };
+      if (order.parentOrderSn && this.showParentOrderSn) {
+        requestData["parentOrderSn"] = order.parentOrderSn;
+      }
+      this.showParentOrderSn = false;
       this.isLoading = true;
       sendValuation(requestData).then((res) => {
         console.log(res, "发起配送计算");
@@ -811,6 +872,7 @@ export default {
       trackOrder({ orderId: this.orderId }).then((res) => {
         if (res.code === 200) {
           this.trackOrder = res.data;
+          this.trackOrder.list = res.data2.list;
           this.showTrack = true;
         } else {
           this.$message({
@@ -870,15 +932,20 @@ export default {
       if (item.deliveryStatus === -1) {
         return (name = "已取消");
       }
-      // if (item.deliveryStatus === -2) {
-      //   return this.showCancelType(item.cancelType);
-      // }
     },
   },
 };
 </script>
-<!-- Add "scoped" attribute to limit CSS to this component only -->
 <style lang="scss" scoped="scoped">
+/deep/ .el-button--default:hover {
+  background-color: rgba(252, 114, 0, 0.2);
+  border-color: rgba(252, 114, 0, 0.2);
+  color: #fc7200;
+}
+/deep/ .el-button--primary {
+  background-color: #fc7200;
+  border-color: #fc7200;
+}
 .el-row {
   position: absolute !important;
   width: 100%;
@@ -890,7 +957,6 @@ export default {
   justify-content: flex-end;
   height: calc(100vh - 210px);
   /deep/ .el-col {
-    // margin-right: 15px;
     height: 100%;
     z-index: 2;
   }
@@ -1032,9 +1098,6 @@ export default {
     margin-right: 20px;
     margin-bottom: 20px;
     cursor: pointer;
-    &:last-child {
-      color: #d7d7d7;
-    }
     &.active {
       color: #fc7101;
       border-color: #fc7101;
@@ -1072,18 +1135,17 @@ export default {
   border: none !important;
   background-color: #fc7200;
 }
-.active-order-item {
-  border: 2px solid #fc7200;
-  height: 136px !important;
-  width: calc(100% - 4px) !important;
-}
 .order_item {
   width: 100%;
   height: 140px;
   background: #fff;
   margin-bottom: 10px;
   border-radius: 5px;
-
+  overflow: hidden;
+  cursor: pointer;
+  &:hover {
+    background: rgba(254, 241, 233, 0.39) !important;
+  }
   .order_item_header {
     width: 100%;
     height: 49px;
@@ -1096,6 +1158,7 @@ export default {
     justify-content: space-between;
     padding-right: 10px;
     box-sizing: border-box;
+    background: rgba(254, 241, 233, 0.39);
 
     .order_item_header_l,
     .order_item_header_r {
@@ -1106,7 +1169,6 @@ export default {
     .Serial_number {
       width: 60px;
       height: 26px;
-      background: #fc7200;
       border-radius: 0 30px 30px 0;
       font-size: 10px;
       font-weight: 500;
@@ -1144,7 +1206,6 @@ export default {
     }
 
     .sign_txt {
-      // width: 64px;
       height: 20px;
       border: 1px solid #009cff;
       background: #f2faff;
@@ -1189,7 +1250,6 @@ export default {
       font-size: 14px;
       font-weight: 400;
       color: #333333;
-      // margin-right: 22px;
     }
 
     .btn {
@@ -1197,33 +1257,58 @@ export default {
       border-color: #fc7200;
       color: #fff;
       margin-left: 20px;
-      //  position: absolute;
-      //  right: 10px;
     }
   }
+  .active_order_item_cont {
+    border-color: #fc7200 !important;
+  }
   .order_item_cont {
     display: flex;
     flex-direction: column;
     justify-content: space-evenly;
-    padding: 5px 20px;
-    height: 80px;
-  }
-  .address {
-    .distance {
-      margin-left: 10px;
-      color: #409eff;
-      cursor: pointer;
+    padding: 0 20px;
+    height: calc(100% - 52px);
+    border-bottom: 3px solid #ffffff;
+
+    .address {
+      display: flex;
+      align-items: center;
       font-size: 16px;
+      font-weight: bold;
+      .distance {
+        display: flex;
+        align-items: center;
+        margin-left: 10px;
+        color: #fc7200;
+        cursor: pointer;
+        .img {
+          width: 15px;
+          height: 20px;
+          margin-right: 5px;
+        }
+        .show-map {
+          font-size: 12px;
+          font-weight: bold;
+          font-weight: 500;
+          color: #fc7200;
+        }
+      }
+    }
+    .content {
+      font-size: 14px;
+      font-weight: 400;
+      line-height: 20px;
+      color: #999999;
+    }
+    .itme_r {
+      font-size: 15px;
+      font-weight: 400;
+      color: #333333;
+      word-wrap: break-word;
     }
   }
 }
 
-.itme_r {
-  font-size: 14px;
-  font-weight: 400;
-  color: #b1b1b1;
-  word-wrap: break-word;
-}
 .order_detail {
   position: relative;
   width: 100%;
@@ -1248,14 +1333,14 @@ export default {
     box-sizing: border-box;
     display: flex;
     align-items: center;
-    font-size: 12px;
-    font-weight: 600;
+    font-weight: bold;
     display: flex;
     align-items: flex-end;
 
     .detail_txt {
       color: #b1b1b1;
-      padding-bottom: 13px;
+      padding-bottom: 7px;
+      font-size: 15px;
       border-bottom: 2px solid #fafafa;
       margin-right: 28px;
       cursor: pointer;

+ 155 - 106
src/components/orderComponents/orderTrack.vue

@@ -2,10 +2,10 @@
   <div class="order-detail">
     <!-- 取货中 -->
     <div class="picking-up">
-      <div class="top-cancel" v-if="buttonStatus === -1 || buttonStatus === -2">
+      <!-- <div class="top-cancel" v-if="buttonStatus === -1 || buttonStatus === -2">
         <img src="../../../static/image/icon_warn.png" alt="" srcset="">
         {{showCancelType(trackOrder.cancelType)}}
-      </div>
+      </div> -->
       <div class="top" v-if="
           (buttonStatus === 2 && riderArriveTime.riderArriveMinute) ||
           (buttonStatus === 3 && riderArriveTime.estimateArriveTime)
@@ -17,92 +17,84 @@
         <span v-if="buttonStatus === 2" class="top-tlt-l">{{ riderArriveTime.riderArriveMinute }}分钟后到店取件</span>
         <span v-if="buttonStatus === 3" class="top-tlt-l">{{ riderArriveTime.estimateArriveTime }}送达</span>
       </div>
-      <!-- 配送信息 ( 待接单无配送信息 ) -->
-      <div class="send-info" v-if="trackOrder.deliveryName">
-        <div class="send-tlt">配送信息</div>
-        <div class="label">
-          <div class="label-tlt">接单平台:</div>
-          <div class="label-right">
-            <img :src="trackOrder.deliveryLogo" class="send-logo" />
-            <span>{{ trackOrder.deliveryName }}</span>
-          </div>
-        </div>
-        <div class="label">
-          <div class="label-tlt">骑手信息:</div>
-          <div class="label-right">
-            <span>{{ trackOrder.shipperName }}({{
-                trackOrder.shipperPhone
-              }})</span>
-          </div>
-        </div>
-        <div class="label">
-          <div class="label-tlt">{{ trackOrder.deliveryName }}客服:</div>
-          <div class="label-right">
-            <span>{{ trackOrder.customerPhone }}</span>
-          </div>
-        </div>
-        <div class="label">
-          <div class="label-tlt">接单时间:</div>
-          <div class="label-right">
-            <span>{{ trackOrder.receiveTime }}</span>
-          </div>
-        </div>
-        <div class="label">
-          <div class="label-tlt">{{ trackOrder.deliveryName }}订单号:</div>
-          <div class="label-right">
-            <span>{{ trackOrder.deliveryOrderSn }}</span>
-          </div>
-        </div>
-      </div>
-      <!-- 发单信息 -->
-      <div class="send-info">
-        <div class="send-tlt">发单信息</div>
-        <div class="label">
-          <div class="label-tlt">配送费用:</div>
-          <div class="label-right">
-            <span>¥{{ trackOrder.payAmount }}</span>
-          </div>
-        </div>
-        <div class="label">
-          <div class="label-tlt">发单时间:</div>
-          <div class="label-right">
-            <span>{{ trackOrder.sendTime || '--' }}</span>
-          </div>
-        </div>
-      </div>
-      <!-- 收件地址信息、配送进度 -->
-      <div class="address-box">
-        <!-- <div class="address-info">
-          <img src="../../../static/image/address-shou.png" class="address-icon" />
-          <div class="address-content">【苏州市工业园区】娄葑街道通园路80号(56文创园)C栋1楼 18015468888-1157</div>
-        </div> -->
-        <!-- 进度列表 -->
-        <div class="process">
-          <el-timeline>
-            <el-timeline-item class="p-item" v-for="(v, i) in trackOrder.itemList" :key="i" type="info" size="large" :icon="i ? 'el-icon-success' : 'el-icon-circle-check'">
-              <div class="p-right">
-                <div class="p-top">
-                  <span class="p-status">{{ v.orderStatus === -1 ? showCancelType(trackOrder.cancelType) : orderStatus(v.orderStatus) }}</span>
-                  <span class="p-time">{{ v.nodeTime }}</span>
+      <el-collapse v-model="activeNames">
+        <el-collapse-item v-for="(v,i) in list" :key='i' :title="`第${list.length - i}次配送`" :name="i">
+          <!-- 配送信息 ( 待接单无配送信息 ) -->
+          <div class="send-info" v-if="v.deliveryName">
+            <div class="send-tlt">配送信息</div>
+            <div class="delivery">
+              <img v-if="v.deliveryLogo" class="img" :src="v.deliveryLogo" alt="">
+              <div class="con">
+                <div class="delivery-top">
+                  <div class="left">{{v.shipperName}}</div>
+                  <div class="right">{{v.shipperPhone}}</div>
                 </div>
-                <div class="p-bottom" v-if="v.orderStatus === 1">
-                  <span>20分钟内无骑手接单将自动取消订单</span>
-                </div>
-                <div class="p-bottom" v-if="v.orderStatus === 2">
-                  {{ trackOrder.deliveryName }}骑手
-                  <span class="has-driver">{{ trackOrder.shipperName }}({{
-                      trackOrder.shipperPhone
-                    }})</span>
-                  已接单
-                </div>
-                <div class="p-bottom" v-if="v.orderStatus === 3 && buttonStatus === 3">
-                  <span class="send">正在派送中</span>
+                <div class="delivery-bot" v-if="v.customerPhone">
+                  <div class="left">{{v.deliveryName}}客服</div>
+                  <div class="right">{{ v.customerPhone }}</div>
                 </div>
               </div>
-            </el-timeline-item>
-          </el-timeline>
-        </div>
-      </div>
+            </div>
+            <div class="label">
+              <div class="label-tlt">接单时间:</div>
+              <div class="label-right">
+                <span>{{ shipperReceiveTime(v.itemList) }}</span>
+              </div>
+            </div>
+            <div class="label">
+              <div class="label-tlt">{{ v.deliveryName }}订单号:</div>
+              <div class="label-right">
+                <span>{{ v.outTradeNo }}</span>
+              </div>
+            </div>
+          </div>
+          <!-- 发单信息 -->
+          <div class="send-info">
+            <div class="send-tlt">发单信息</div>
+            <div class="label">
+              <div class="label-tlt">支付金额:</div>
+              <div class="label-right">
+                <span>¥{{ v.payAmount }}</span>
+                <!-- <div class="detail">明细</div> -->
+              </div>
+            </div>
+            <div class="label">
+              <div class="label-tlt">发单时间:</div>
+              <div class="label-right">
+                <span>{{ sendOrderTime(v.itemList) }}</span>
+              </div>
+            </div>
+          </div>
+          <!-- 收件地址信息、配送进度 -->
+          <div class="address-box">
+            <div class="process">
+              <el-timeline>
+                <el-timeline-item class="p-item" v-for="(item, i) in v.itemList" :key="i" type="info" size="large" :icon="i ? 'el-icon-success' : 'el-icon-circle-check'">
+                  <div class="p-right">
+                    <div class="p-top">
+                      <span class="p-status">{{ item.orderStatus === -1 ? showCancelType(v.cancelType) : orderStatus(item.orderStatus) }}</span>
+                      <span class="p-time">{{ item.nodeTime }}</span>
+                    </div>
+                    <div class="p-bottom" v-if="item.orderStatus === 1">
+                      <span>20分钟内无骑手接单将自动取消订单</span>
+                    </div>
+                    <div class="p-bottom" v-if="item.orderStatus === 2">
+                      {{ v.deliveryName }}骑手
+                      <span class="has-driver">{{ v.shipperName }}({{
+                      v.shipperPhone
+                    }})</span>
+                      已接单
+                    </div>
+                    <div class="p-bottom" v-if="item.orderStatus === 3 && buttonStatus === 3">
+                      <span class="send">正在派送中</span>
+                    </div>
+                  </div>
+                </el-timeline-item>
+              </el-timeline>
+            </div>
+          </div>
+        </el-collapse-item>
+      </el-collapse>
     </div>
   </div>
 </template>
@@ -116,9 +108,32 @@ export default {
     riderArriveTime: Object,
   },
   data() {
-    return {};
+    return {
+      activeNames: 0,
+    };
+  },
+  computed: {
+    list() {
+      return (
+        this.trackOrder &&
+        this.trackOrder.list &&
+        this.$tool.deepClone(this.trackOrder.list).reverse()
+      );
+    },
   },
   methods: {
+    sendOrderTime(itemList) {
+      let data = itemList.find((v) => {
+        return v.orderStatus === 5;
+      });
+      return (data && data.nodeTime) || "--";
+    },
+    shipperReceiveTime(itemList) {
+      let data = itemList.find((v) => {
+        return v.orderStatus === 2;
+      });
+      return (data && data.nodeTime) || "--";
+    },
     showCancelType(type) {
       let name = "";
       switch (type) {
@@ -183,22 +198,6 @@ export default {
       }
       return name;
     },
-    getTrackOrder() {
-      if (!this.orderInfo) return;
-      trackOrder({ orderId: this.orderInfo.id }).then((res) => {
-        if (res.code === 200) {
-          this.trackOrder = res.data;
-          this.trackOrder.itemList = this.trackOrder.itemList.filter((v) => {
-            return v.orderStatus !== -2;
-          });
-        } else {
-          this.$message({
-            message: res.msg,
-            type: "error",
-          });
-        }
-      });
-    },
   },
 };
 </script>
@@ -210,6 +209,10 @@ export default {
 /deep/ .el-timeline-item__wrapper {
   width: 100%;
 }
+/deep/ .el-collapse-item__header {
+  font-size: 14px !important;
+  font-weight: bold !important;
+}
 .clearfix:after {
   content: "";
   font-size: 0;
@@ -220,7 +223,7 @@ export default {
 .order-detail {
   width: 100%;
   box-sizing: border-box;
-  padding: 16px 16px 40px;
+  padding: 16px 16px 80px;
   .picking-up {
     .top-cancel {
       display: flex;
@@ -269,11 +272,51 @@ export default {
       margin-bottom: 20px;
       border-bottom: 2px dotted #f0f0f0;
       .send-tlt {
-        font-size: 12px;
+        font-size: 13px;
         font-weight: bold;
-        color: #777777;
+        color: #777;
         margin-bottom: 15px;
       }
+      .delivery {
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        margin-bottom: 10px;
+        .img {
+          flex-shrink: 0;
+          width: 44px;
+          height: 44px;
+          background: rgba(255, 255, 255, 0.39);
+          box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.16);
+          border-radius: 8px;
+          margin-right: 10px;
+        }
+        .con {
+          flex: 1;
+          display: flex;
+          flex-direction: column;
+          justify-content: space-between;
+          width: calc(100% - 54px);
+          .delivery-top,
+          .delivery-bot {
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
+            font-size: 14px;
+            line-height: 20px;
+            color: #007aff;
+            .left {
+              max-width: 60%;
+              overflow: hidden;
+              white-space: nowrap;
+              text-overflow: ellipsis;
+            }
+          }
+          .delivery-bot {
+            color: #999999;
+          }
+        }
+      }
       .label {
         display: flex;
         justify-content: space-between;
@@ -282,12 +325,18 @@ export default {
           flex-shrink: 0;
           font-size: 14px;
           font-weight: 400;
-          color: #b1b1b1;
+          color: #999999;
         }
         .label-right {
           display: flex;
           flex-wrap: wrap;
           align-items: center;
+          .detail {
+            color: #fc7200;
+            font-size: 14px;
+            margin-left: 10px;
+            cursor: pointer;
+          }
           .send-logo {
             width: 16px;
             height: 16px;

+ 2 - 14
src/components/orderComponents/sendOrderPopup.vue

@@ -6,7 +6,7 @@
           <div class="left-content">
             <div class="juhe-icon">
               <!-- <img src="../../../static/image/juhe-icon.png" /> -->
-              <img  style="width:40px;height:40px;" src="../../../static/image/juhe-icon.png" alt="">
+              <img style="width:40px;height:40px;" src="../../../static/image/juhe-icon.png" alt="">
             </div>
             <div>
               <div class="juhe-title">聚合配送</div>
@@ -409,6 +409,7 @@ export default {
       this.showCode = false;
       this.dialogTableVisible = false;
       this.loading = false;
+      this.$store.dispatch("getUserInfo");
       if (this.tabNum === -1) {
         bus.$emit("refreshData2");
         return;
@@ -451,19 +452,6 @@ export default {
       sendOrder(params).then((res) => {
         if (res.code == 200) {
           if (this.payId == 4) {
-            // this.dialogTableVisible = false;
-            // this.loading = false;
-            // if (this.tabNum === -1) {
-            //   bus.$emit("refreshData2");
-            //   return;
-            // }
-            // bus.$emit("pullData", 2);
-            // if (this.$route.name === "manualCreate") {
-            //   this.$route.push({
-            //     name: "HomeIndex",
-            //     params:{tabNum:2}
-            //   });
-            // }
             this.paySuccess();
           } else if (
             (this.payId == 1 || this.payId == 2) &&

+ 22 - 24
src/components/orderSearch.vue

@@ -27,7 +27,7 @@
           <div class="sel_item">
             <span class="name">订单来源:</span>
             <el-select size="small" class="item1" v-model="params.orderType" placeholder="请选择订单来源">
-              <el-option v-for="(v,i) in originList" :key="i" :label="v.name" :value="v.status"></el-option>
+              <el-option v-for="(v,i) in originList" :key="i" :label="v.name" :value="v.type"></el-option>
             </el-select>
           </div>
           <div class="sel_item">
@@ -68,7 +68,7 @@ import bus from "../common/bus.js";
 import sendOrderPopup from "./orderComponents/sendOrderPopup.vue";
 import OrderList from "./orderComponents/orderList.vue";
 import { getOrderList } from "../api/order.js";
-import { getShopList } from "../api/shop.js";
+import { getShopList, getTakeOutList } from "../api/shop.js";
 export default {
   data() {
     return {
@@ -87,28 +87,7 @@ export default {
         pageSize: 10,
       },
       shopList: [],
-      originList: [
-        {
-          name: "全部",
-          status: 0,
-        },
-        {
-          name: "美团",
-          status: 1,
-        },
-        {
-          name: "饿了么",
-          status: 2,
-        },
-        {
-          name: "饿百",
-          status: 3,
-        },
-        {
-          name: "手动发单",
-          status: 99,
-        },
-      ],
+      originList: [],
       tabList: [
         {
           name: "全部",
@@ -190,6 +169,7 @@ export default {
     },
   },
   created() {
+    this.getTakeOutList();
     let searchKey = this.$route.query.searchKey;
     if (searchKey) {
       this.params.searchKey = searchKey;
@@ -206,6 +186,17 @@ export default {
     bus.$off("refreshData2");
   },
   methods: {
+    getTakeOutList() {
+      getTakeOutList().then((res) => {
+        if (res.code === 200) {
+          this.originList = res.data;
+          this.originList.push({ type: 99, name: "手动发单" });
+          this.originList.unshift({ type: 0, name: "全部" });
+        } else {
+          this.$message.error(res.msg);
+        }
+      });
+    },
     seachEnterFun(e) {
       var keyCode = window.event ? e.keyCode : e.which;
       if (keyCode == 13) {
@@ -308,6 +299,13 @@ export default {
 </script>
 
 <style lang="scss" scoped="scoped">
+/deep/ .el-pagination.is-background .el-pager li:not(.disabled).active {
+  background-color: #fc7200;
+  color: #fff !important;
+}
+/deep/ .el-pagination.is-background .el-pager li:hover:not(.disabled) {
+  color: #fc7200;
+}
 /deep/ .el-input__inner {
   padding-right: 30px;
 }

+ 265 - 0
src/components/platformAccount/index.vue

@@ -0,0 +1,265 @@
+<template>
+  <div class="platform-account">
+    <div class="address-list">
+      <div class="item" v-for="(v,i) in accountList" :key="i" @click.stop="showAccount(1,v)">
+        <div class="name">{{v.name}} {{v.mobile}}</div>
+        <div class="shop-name">{{v.shopName}}</div>
+        <div class="btns">
+          <img @click.stop="showAccount(1,v)" src="../../../static/image/edit-icon.png" alt="">
+          <img @click.stop="deleteAccount(v)" src="../../../static/image/delete-icon.png" alt="">
+        </div>
+      </div>
+      <div class="item1" @click.stop="showAccount(0)">
+        <img class="img" src="../../../static/image/icon-add.png" alt="">
+        <div class="shop-name">添加账号</div>
+      </div>
+    </div>
+    <!-- /新增编辑账号 -->
+    <el-dialog :title="isEdit ? '编辑账号': '新增账号'" :visible.sync="centerDialogVisible" width="600px" center append-to-body>
+      <el-form ref="form" :model="form" label-width="100px" label-position="left" size="small">
+        <el-form-item label="所属门店">
+          <el-select v-model="form.shopId" placeholder="请选择关联门店">
+            <el-option v-for="v in shopList" :key="v.id" :label="v.name" :value="v.id"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="员工称呼" required>
+          <el-input clearable v-model="form.name" placeholder="请填写员工称呼"></el-input>
+        </el-form-item>
+        <el-form-item label="手机号" required>
+          <el-input clearable v-model="form.mobile" placeholder="请填写手机号"></el-input>
+        </el-form-item>
+        <el-form-item label="登录密码">
+          <el-input clearable v-model="password" maxlength="11" :placeholder="passwordTips"></el-input>
+        </el-form-item>
+      </el-form>
+      <span slot="footer" class="dialog-footer">
+        <el-button size="small" @click="centerDialogVisible=false">取 消</el-button>
+        <el-button size="small" type="primary" @click="addAccount">确 定</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  getAccountList,
+  deletePlatformAccount,
+  addPlatformAccount,
+  modifyPlatformAccount,
+  shopListNew,
+} from "../../api/shop.js";
+export default {
+  name: "platformAccount",
+  data() {
+    return {
+      isEdit: 0,
+      centerDialogVisible: false,
+      accountList: [],
+      shopList: [],
+      form: {
+        shopId: "",
+        name: "",
+        mobile: "",
+      },
+      password: "",
+      passwordTips: "",
+    };
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {},
+  // 方法集合
+  methods: {
+    addAccount() {
+      if (!this.form.shopId) {
+        return this.$message.error(`请选择账号所属的门店!`);
+      }
+      if (!this.form.name) {
+        return this.$message.error(`请填写员工称呼!`);
+      }
+      if (!this.$tool.mobile(this.form.mobile)) {
+        return this.$message.error(`请填写正确的手机号!`);
+      }
+      if (this.isEdit) {
+        if (this.password) {
+          this.form.password = this.password;
+        }
+        modifyPlatformAccount(this.form).then((res) => {
+          if (res.code === 200) {
+            this.getAccountList();
+            this.$message.success("账号修改成功");
+            this.centerDialogVisible = false;
+          } else {
+            this.$message.error(res.msg);
+          }
+        });
+      } else {
+        this.form.password = this.password || "123456";
+        addPlatformAccount(this.form).then((res) => {
+          if (res.code === 200) {
+            this.getAccountList();
+            this.$message.success("账号添加成功");
+            this.centerDialogVisible = false;
+          } else {
+            this.$message.error(res.msg);
+          }
+        });
+      }
+    },
+    showAccount(flag, form) {
+      this.isEdit = flag;
+      if (flag) {
+        this.form = form;
+        this.password = form.password;
+        if (!this.form.password) {
+          delete this.form.password;
+        }
+        this.passwordTips = !this.password ? "为空时则不修改密码" : "";
+      } else {
+        this.form = {};
+        this.password = "";
+        this.passwordTips = "默认密码:123456";
+      }
+      this.centerDialogVisible = true;
+    },
+    deleteAccount(v) {
+      this.$confirm("此操作将删除该账号, 是否继续?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        center: true,
+        type: "warning",
+      }).then(() => {
+        deletePlatformAccount({ id: v.id }).then((res) => {
+          if (res.code === 200) {
+            this.$message({
+              type: "success",
+              message: "删除成功!",
+            });
+            this.getAccountList();
+          } else {
+            this.$message({
+              type: "error",
+              message: res.msg,
+            });
+          }
+        });
+      });
+    },
+    getAccountList() {
+      getAccountList().then((res) => {
+        if (res.code === 200) {
+          this.accountList = res.data.data;
+        } else {
+          this.$message({
+            type: "error",
+            message: res.msg,
+          });
+        }
+      });
+    },
+    getShopList() {
+      shopListNew().then((res) => {
+        if (res.code === 200) {
+          this.shopList = res.data;
+        } else {
+          this.$message({
+            type: "error",
+            message: res.msg,
+          });
+        }
+      });
+    },
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  created() {
+    this.getAccountList();
+    this.getShopList();
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {},
+  // 生命周期 - 创建之前
+  beforeCreate() {},
+  // 生命周期 - 挂载之前
+  beforeMount() {},
+  // 生命周期 - 更新之前
+  beforeUpdate() {},
+  // 生命周期 - 更新之后
+  updated() {},
+  // 生命周期 - 销毁之前
+  beforeDestroy() {},
+  // 生命周期 - 销毁完成
+  destroyed() {},
+  // 如果页面有keep-alive缓存功能,这个函数会触发
+  activated() {},
+};
+</script>
+
+<style lang="scss" scoped  type="text/css">
+.address-list {
+  display: flex;
+  flex-wrap: wrap;
+  .item {
+    position: relative;
+    display: flex;
+    flex-direction: column;
+    width: 280px;
+    height: 120px;
+    background: #ffffff;
+    border-radius: 8px;
+    margin: 10px 20px 0 0;
+    padding: 35px 20px 0;
+    cursor: pointer;
+    &:hover {
+      background: rgba(255, 255, 255, 0.39);
+      box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
+    }
+    .img {
+      width: 80px;
+      height: 80px;
+    }
+    .name {
+      font-size: 18px;
+      font-weight: 500;
+      line-height: 20px;
+      color: #333333;
+      margin-bottom: 10px;
+    }
+    .shop-name {
+      font-size: 14px;
+      font-weight: 400;
+      line-height: 20px;
+      color: #999999;
+    }
+    .btns {
+      position: absolute;
+      top: 10px;
+      right: 0;
+      img {
+        width: 20px;
+        height: 20px;
+        margin-right: 10px;
+      }
+    }
+  }
+  .item1 {
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+    background: #ffffff;
+    width: 320px;
+    height: 155px;
+    box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
+    border-radius: 8px;
+    margin: 10px 20px 0 0;
+    cursor: pointer;
+    .shop-name {
+      font-size: 16px;
+      font-weight: 500;
+      line-height: 22px;
+      color: #333333;
+    }
+  }
+}
+</style>

+ 79 - 41
src/components/addressManagement.vue

@@ -1,30 +1,25 @@
 <template>
   <div class="address-management">
-    <div class="header">
-      <div class="num">已保存<span>{{addressList.length}}</span>/100条,最多还可以添加<span>{{100-addressList.length}}</span>条</div>
-      <el-button class="btn" round @click="showAddress(false)" size="mini" type="primary" plain>添加+</el-button>
+    <div class="printer-list">
+      <div class="item" v-for="(v,i) in addressList" :key="i">
+        <div class="name">{{v.contact}} {{v.phone}}</div>
+        <div class="shop-name">{{v.address}}</div>
+        <div class="btns">
+          <img @click.stop="showAddress(1,v)" src="../../../static/image/edit-icon.png" alt="">
+          <img @click.stop="deleteAddress(v)" src="../../../static/image/delete-icon.png" alt="">
+        </div>
+      </div>
+      <div class="item1" @click.stop="showAddress(0,v)">
+        <img class="img" src="../../../static/image/icon-add.png" alt="">
+        <div class="shop-name">添加常用地址</div>
+      </div>
     </div>
-    <el-table @cell-click="editAddress" :data="addressList" stripe style="width: 100%">
-      <el-table-column prop="contact" label="姓名" width="300">
-      </el-table-column>
-      <el-table-column prop="phone" label="电话" width="300">
-      </el-table-column>
-      <el-table-column prop="address" label="地址">
-      </el-table-column>
-      <el-table-column label="删除" width="100">
-        <template slot-scope="scope">
-          <i @click="deleteAddress(scope.row)" class="el-icon-delete"></i>
-          <!-- <el-button type="text" size="small" @click="showAddress(true,scope.row)">编辑</el-button>
-          <el-button @click="deleteAddress(scope.row)" type="text" size="small">删除</el-button> -->
-        </template>
-      </el-table-column>
-    </el-table>
     <!-- //新增编辑地址 -->
     <el-dialog :title="isEdit ? '编辑地址': '新增地址'" :visible.sync="centerDialogVisible" width="600px" center append-to-body>
       <el-form ref="form" :model="form" label-width="100px" label-position="left" size="small">
         <el-form-item label="位置" required>
           <el-input v-model="form.address" placeholder="请选择位置!" disabled>
-            <img @click="showMap" slot="append" class="map" src="../../static/image/icon_map.png" />
+            <img @click="showMap" slot="append" class="map" src="../../../static/image/icon_map.png" />
           </el-input>
         </el-form-item>
         <el-form-item label="门牌号">
@@ -51,7 +46,7 @@
 </template>
 
 <script>
-import orderMap from "./orderComponents/orderAMap.vue";
+import orderMap from "../orderComponents/orderAMap.vue";
 import {
   getAddressList,
   deleteAddress,
@@ -59,7 +54,7 @@ import {
   updateAddress,
   getAddressDetail,
   defaultAddress,
-} from "../api/setting.js";
+} from "../../api/setting.js";
 export default {
   name: "addressManagement",
   data() {
@@ -97,11 +92,6 @@ export default {
   mounted() {},
   // 方法集合
   methods: {
-    editAddress(){
-      console.log('arguments:',arguments);
-      if(arguments[2].cellIndex === 3)return
-      this.showAddress(true,arguments[0])
-    },
     cancel() {
       this.centerDialogVisible = false;
       this.getAddressList();
@@ -256,30 +246,78 @@ export default {
   color: #fff;
   border: #fc7200;
 }
-/deep/ .el-button--text {
-  color: #fc7200;
-}
+
 .map {
   width: 20px;
   height: 20px;
   cursor: pointer;
 }
 .address-management {
-  .header {
+  .printer-list {
     display: flex;
-    // justify-content: space-between;
-    align-items: center;
-    margin-bottom: 10px;
-    .num {
-      font-size: 14px;
-      margin-right: 20px;
-      span {
-        color: #fc7200;
+    flex-wrap: wrap;
+    .item {
+      position: relative;
+      display: flex;
+      flex-direction: column;
+      width: 280px;
+      height: 120px;
+      background: #ffffff;
+      border-radius: 8px;
+      margin: 10px 20px 0 0;
+      padding: 35px 20px 0;
+      cursor: pointer;
+      &:hover {
+        box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
+        background: rgba(255, 255, 255, 0.39);
+      }
+      .img {
+        width: 80px;
+        height: 80px;
+      }
+      .name {
+        font-size: 18px;
+        font-weight: 500;
+        line-height: 20px;
+        color: #333333;
+      }
+      .shop-name {
+        font-size: 14px;
+        font-weight: 400;
+        line-height: 20px;
+        color: #999999;
+        margin-top: 16px;
+      }
+      .btns {
+        position: absolute;
+        top: 10px;
+        right: 0;
+        img {
+          width: 20px;
+          height: 20px;
+          margin-right: 10px;
+        }
+      }
+    }
+    .item1 {
+      display: flex;
+      flex-direction: column;
+      justify-content: center;
+      align-items: center;
+      background: #ffffff;
+      width: 320px;
+      height: 155px;
+      box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
+      border-radius: 8px;
+      margin: 10px 20px 0 0;
+      cursor: pointer;
+      .shop-name {
+        font-size: 16px;
+        font-weight: 500;
+        line-height: 22px;
+        color: #333333;
       }
     }
-  }
-  .el-icon-delete {
-    cursor: pointer;
   }
 }
 </style>

+ 296 - 104
src/components/settingComponents/deliverySetting.vue

@@ -1,31 +1,86 @@
 <template>
-  <div class="delivery-content">
-    <div>
-      <!-- <el-button type="primary">保存操作</el-button> -->
+  <div class="delivery-setting">
+    <div class="model">
+      <div class="title">接单设置</div>
+      <div class="list">
+        <div class="item" v-for="(v,i) in list3" :key=i>
+          <div class="left">
+            <div class="left-top">
+              <div class="name">{{v.name}}</div>
+            </div>
+            <div class="left-bot">{{v.tips}}</div>
+          </div>
+          <div class="right">
+            <el-switch @change="change(v)" v-model="v.value" :active-value="1" :inactive-value="0" active-color="#FC7200" inactive-color="#999" />
+          </div>
+        </div>
+      </div>
     </div>
-    <div class="recommend">
-      <div class="title">
-        <!-- <el-button type="primary" @click.stop="toPay">发起支付</el-button> -->
-        <span>推荐/屏蔽运力</span>
-        <span>用户选择非聚合配送发单时,优先选中的运力置顶显示,提高您的下单效率</span>
+    <div class="model">
+      <div class="title">自动发单设置</div>
+      <div class="list">
+        <div class="item" v-for="(v,i) in list" :key=i>
+          <div class="left">
+            <div class="left-top">
+              <div class="name">{{v.name}}</div>
+              <div @click="setTime(v,i)" class="set">{{v.setContent}}</div>
+            </div>
+            <div class="left-bot">{{v.tips}}</div>
+          </div>
+          <div class="right">
+            <div v-if="!i" :class="['time', v.value ? '' : 'time1']">顾客下单{{v.time}}分钟后</div>
+            <div v-else :class="['time', v.value ? '' : 'time1']">期望送达前{{v.time}}分钟</div>
+            <el-switch @change="change(v)" v-model="v.value" :active-value="1" :inactive-value="0" active-color="#FC7200" inactive-color="#999" />
+          </div>
+        </div>
       </div>
-      <div class="delivery-list">
-        <div @click="changeStatus(v.deliveryId)" class="item" v-for="(v,i) in list" :key="i">
-          <img :src="v.pcLogo" class="icon" />
-          <div v-if="shieldDeliveryIds.includes(String(v.deliveryId))" class="mask mantle">
-            {{v.name}}已屏蔽
+    </div>
+    <div class="model">
+      <div class="title">同步设置</div>
+      <div class="list">
+        <div class="item" v-for="(v,i) in list2" :key=i>
+          <div class="left">
+            <div class="left-top">
+              <div class="name">{{v.name}}</div>
+            </div>
+            <div class="left-bot">{{v.tips}}</div>
+          </div>
+          <div class="right">
+            <el-switch @change="change(v)" v-model="v.value" :active-value="1" :inactive-value="0" active-color="#FC7200" inactive-color="#999" />
+          </div>
+        </div>
+      </div>
+    </div>
+    <div class="model">
+      <div class="title">运力设置<span class="tips">(推荐的运力在聚合发单时会置顶展示,屏蔽的运力在发单时将不进行计价)</span></div>
+      <div class="list">
+        <div class="item" v-for="(v,i) in deliveryList" :key=i>
+          <div class="left">
+            <div class="left-top">
+              <div class="name">{{v.name}}</div>
+            </div>
+            <div class="left-bot">{{v.tips}}</div>
           </div>
-          <div v-if="billDeliveryIds.includes(String(v.deliveryId))" class="mask recommend-delivery">
-            {{v.name}}已推荐
+          <div class="right">
+            <div class="con con1" @click="changeDelivery(v,3)" v-if="billDeliveryIds.includes(String(v.deliveryId))">取消推荐</div>
+            <div class="con" @click="changeDelivery(v,2)" v-if="billDeliveryIds.includes(String(v.deliveryId)) || !shieldDeliveryIds.includes(String(v.deliveryId))">屏蔽</div>
+            <div class="con con1" @click="changeDelivery(v,3)" v-if="shieldDeliveryIds.includes(String(v.deliveryId))">取消屏蔽</div>
+            <div class="con" @click="changeDelivery(v,1)" v-if="shieldDeliveryIds.includes(String(v.deliveryId)) || !billDeliveryIds.includes(String(v.deliveryId))">推荐</div>
           </div>
         </div>
       </div>
     </div>
-    <el-dialog title="请选择对当前运力的操作!" :visible.sync="centerDialogVisible" width="600px" center>
+    <el-dialog :title="!curIndex ? '即时单自动发单时间设置' : '预定单自动发单时间设置'" @close="centerDialogVisible=false" :visible.sync="centerDialogVisible" width="400px" center>
+      <el-form label-width="120px">
+        <el-form-item :label="!curIndex ? '顾客下单' : '期望送达前'">
+          <el-input size="small" class="auto-time" v-model="time" clearable>
+            <template slot="append">分钟{{curIndex ? '' : '后'}}</template>
+          </el-input>
+        </el-form-item>
+      </el-form>
       <span slot="footer" class="dialog-footer">
-        <el-button type="success" @click="changeDelivery(1)">推荐运力</el-button>
-        <el-button type="danger" @click="changeDelivery(2)">屏蔽运力</el-button>
-        <el-button type="primary" @click="changeDelivery(3)">重置运力</el-button>
+        <el-button size="medium" @click="centerDialogVisible=false">取 消</el-button>
+        <el-button size='medium' type="primary" @click="confirm">确 定</el-button>
       </span>
     </el-dialog>
   </div>
@@ -38,59 +93,132 @@ import {
   updateConfig,
 } from "../../api/setting.js";
 export default {
+  name: "deliverySetting",
   data() {
     return {
-      form: "",
-      list: [],
-      billDeliveryIds: [], // 推荐运力ID
-      shieldDeliveryIds: [], // 屏蔽运力ID
+      list: [
+        {
+          name: "自动发单",
+          setContent: "设置时长",
+          value: 1,
+          field: "openAutodelivery",
+          tips: "非冲突绑定模式,不支持自动发单",
+          time: 0,
+        },
+        {
+          name: "预约单自动发单",
+          setContent: "设置时长",
+          value: 1,
+          field: "openBookingAutodelivery",
+          tips: "设置的时长为预约单期望送达前多长时间自动呼叫配送",
+          time: 0,
+        },
+      ],
+      list2: [
+        {
+          name: "同步订单商品给骑手",
+          value: 1,
+          field: "syncGoodsDetailToDelivery",
+          tips: "关闭后骑手将看不到商品详情",
+        },
+        {
+          name: "同步打印客户联商品明细",
+          value: 1,
+          field: "customerLinkPrintGoodsDetail",
+          tips: "关闭后打印的客户联小票将看不到商品明细",
+        },
+        {
+          name: "同步打印客户联商品价格",
+          value: 1,
+          field: "customerLinkPrintGoodsPrice",
+          tips: "关闭后打印的客户联小票将看不到商品价格",
+        },
+      ],
+      list3: [
+        {
+          name: "自动接单",
+          value: 1,
+          field: "openAutoorder",
+          tips: "非冲突绑定模式,不支持自动接单",
+        }
+      ],
+      billDeliveryIds: [], // 推荐运力
+      shieldDeliveryIds: [], // 屏蔽运力
+      deliveryList: [],
       centerDialogVisible: false,
+      curIndex: 0,
+      time: 0,
     };
   },
-  created() {
-    this.getDeliveryFloorList();
-    this.getConfig();
-  },
-  mounted() {},
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {},
+  // 方法集合
   methods: {
-    changeStatus(id) {
-      this.id = id;
-      this.centerDialogVisible = true;
-    },
-    changeDelivery(type) {
-      console.log(2222);
+    changeDelivery(v, type) {
+      let id = v.deliveryId;
       // 推荐该运力
       if (type === 1) {
         this.shieldDeliveryIds = this.shieldDeliveryIds.filter((v) => {
-          return v !== String(this.id);
+          return v !== String(id);
         });
-        this.billDeliveryIds.push(String(this.id));
+        this.billDeliveryIds.push(String(id));
         this.billDeliveryIds = [...new Set(this.billDeliveryIds)];
       }
       // 屏蔽该运力
       if (type === 2) {
         this.billDeliveryIds = this.billDeliveryIds.filter((v) => {
-          return v !== String(this.id);
+          return v !== String(id);
         });
-        this.shieldDeliveryIds.push(String(this.id));
+        this.shieldDeliveryIds.push(String(id));
         this.shieldDeliveryIds = [...new Set(this.shieldDeliveryIds)];
       }
       // 恢复为普通运力
       if (type === 3) {
         this.billDeliveryIds = this.billDeliveryIds.filter((v) => {
-          return v !== String(this.id);
+          return v !== String(id);
         });
         this.shieldDeliveryIds = this.shieldDeliveryIds.filter((v) => {
-          return v !== String(this.id);
+          return v !== String(id);
+        });
+      }
+      let data = {
+        billDeliveryIds: String(this.billDeliveryIds),
+        shieldDeliveryIds: String(this.shieldDeliveryIds),
+      };
+      this.updateConfig(data);
+    },
+    confirm() {
+      let data = {};
+      if (!this.curIndex) {
+        data = { autodeliveryOrderTime: this.time * 60 };
+      } else {
+        data = { bookingAutodeliveryOrderTime: this.time * 60 };
+      }
+      this.updateConfig(data);
+    },
+    setTime(v, i) {
+      if (!v.value) {
+        return this.$message({
+          message: "请开启后再设置时间!",
+          type: "warning",
         });
       }
-      this.updateConfig();
+      this.curIndex = i;
+      this.time = v.time;
+      this.centerDialogVisible = true;
+    },
+    change(e) {
+      let data = { [e.field]: e.value };
+      this.updateConfig(data);
     },
-    getDeliveryFloorList() {
+    getDelivery() {
       getDeliveryFloorList().then((res) => {
+        console.log("返回的运力:", res);
         if (res.code === 200) {
           // 电脑端暂时不支持货拉拉
-          this.list = res.data.filter((v) => {
+          this.deliveryList = res.data.filter((v) => {
             return v.type !== 12;
           });
         } else {
@@ -110,10 +238,20 @@ export default {
           this.shieldDeliveryIds = res.data.shieldDeliveryIds
             ? res.data.shieldDeliveryIds.split(",")
             : [];
-          let a = new Set(this.shieldDeliveryIds);
-          let b = new Set(this.billDeliveryIds);
-          let difference = new Set([...a].filter((x) => !b.has(x)));
-          this.shieldDeliveryIds = [...difference];
+          this.list[0].time = res.data.autodeliveryOrderTime / 60;
+          this.list[1].time = res.data.bookingAutodeliveryOrderTime / 60;
+          this.list = this.list.map((v) => {
+            v.value = res.data[v.field];
+            return v;
+          });
+          this.list2 = this.list2.map((v) => {
+            v.value = res.data[v.field];
+            return v;
+          });
+          this.list3 = this.list3.map((v) => {
+            v.value = res.data[v.field];
+            return v;
+          });
         } else {
           this.$message({
             type: "error",
@@ -123,16 +261,9 @@ export default {
         this.centerDialogVisible = false;
       });
     },
-    updateConfig() {
-      let billDeliveryIds = this.billDeliveryIds.toString();
-      let shieldDeliveryIds = this.shieldDeliveryIds.toString();
-      updateConfig({ billDeliveryIds, shieldDeliveryIds }).then((res) => {
-        if (res.code === 200) {
-          this.$message({
-            type: "success",
-            message: "修改成功!",
-          });
-        } else {
+    updateConfig(data) {
+      updateConfig(data).then((res) => {
+        if (res.code !== 200) {
           this.$message({
             type: "error",
             message: res.msg,
@@ -142,65 +273,126 @@ export default {
       });
     },
   },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  created() {
+    this.getDelivery();
+    this.getConfig();
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {},
+  // 生命周期 - 创建之前
+  beforeCreate() {},
+  // 生命周期 - 挂载之前
+  beforeMount() {},
+  // 生命周期 - 更新之前
+  beforeUpdate() {},
+  // 生命周期 - 更新之后
+  updated() {},
+  // 生命周期 - 销毁之前
+  beforeDestroy() {},
+  // 生命周期 - 销毁完成
+  destroyed() {},
+  // 如果页面有keep-alive缓存功能,这个函数会触发
+  activated() {},
 };
 </script>
 
-<style lang="scss" scoped>
-.delivery-content {
-  .recommend {
-    background-color: #fff;
-    margin-top: 10px;
-    .title {
-      font-size: 16px;
-      font-family: PingFang SC;
-      font-weight: 600;
-      color: #333333;
-      height: 55px;
-      line-height: 55px;
-      box-sizing: border-box;
-      padding: 0 18px;
-      border-bottom: 1px solid #eee;
-      span:nth-child(2) {
-        font-size: 14px;
-        font-family: PingFang SC;
-        font-weight: 400;
-        color: #b1b1b1;
-      }
+<style lang="scss" scoped  type="text/css">
+/deep/ .el-button--default:hover {
+  background-color: rgba(252, 114, 0, 0.2);
+  border-color: rgba(252, 114, 0, 0.2);
+  color: #fc7200;
+}
+/deep/ .el-button--primary {
+  background-color: #fc7200;
+  border-color: #fc7200;
+}
+.model {
+  .title {
+    position: relative;
+    font-size: 16px;
+    font-weight: bold;
+    line-height: 22px;
+    color: #333333;
+    padding-left: 10px;
+    margin-top: 24px;
+    .tips {
+      font-size: 14px;
+      font-weight: 400;
+      line-height: 22px;
+      color: #999999;
     }
-    .delivery-list {
+  }
+  .title::before {
+    width: 3px;
+    height: 16px;
+    background: #fc7200;
+    border-radius: 2px;
+    content: "";
+    position: absolute;
+    top: 2px;
+    left: 0;
+  }
+  .list {
+    .item {
       display: flex;
-      flex-wrap: wrap;
-      padding: 30px 18px 0;
-      .item {
-        position: relative;
-        cursor: pointer;
-        margin: 0 30px 30px 0;
-        .mask {
-          position: absolute;
+      justify-content: space-between;
+      align-items: center;
+      background: #ffffff;
+      margin-top: 10px;
+      padding: 16px 20px;
+      .left {
+        display: flex;
+        flex-direction: column;
+        font-size: 14px;
+        font-weight: bold;
+        line-height: 20px;
+        color: #000000;
+        .left-top {
           display: flex;
           align-items: center;
-          justify-content: center;
-          top: 0;
-          left: 0;
-          width: 129px;
-          height: 40px;
-          background: #999;
-          font-size: 14px;
-          border-radius: 25px;
-          opacity: 0.8;
+          .set {
+            font-weight: 400;
+            color: #fc7200;
+            margin-left: 10px;
+            cursor: pointer;
+          }
+        }
+        .left-bot {
+          margin-top: 2px;
+          font-size: 12px;
+          font-weight: 400;
+          line-height: 17px;
+          color: #999999;
         }
-        .mantle {
-          color: #fff;
+      }
+      .right {
+        display: flex;
+        align-items: center;
+        .time {
+          font-size: 12px;
+          font-family: PingFang SC;
+          font-weight: 400;
+          line-height: 17px;
+          color: #333333;
+          margin-right: 20px;
+        }
+        .time1 {
+          color: #999999;
         }
-        .recommend-delivery {
-          color: red;
+        .con {
+          font-size: 14px;
+          font-weight: 400;
+          line-height: 20px;
+          color: #fc7200;
+          padding-left: 20px;
+          cursor: pointer;
         }
-        .icon {
-          width: 129px;
-          height: 40px;
+        .con1 {
+          color: #999999;
         }
       }
     }
   }
 }
-</style>
+</style>

+ 2 - 2
src/components/pictureManagement.vue

@@ -5,7 +5,7 @@
         <div class="name">同步商品图片</div>
         <div class="tips">(同步后显示最新的商品图片)</div>
       </div>
-      <img @click="syncFoodImg" class="img" src="../../static/image/update.png" alt="">
+      <img @click="syncFoodImg" class="img" src="../../../static/image/update.png" alt="">
     </div>
     <div class="set">
       <div class="title">
@@ -19,7 +19,7 @@
 </template>
 
 <script>
-import { getConfig, updateConfig, syncFoodImg } from "../api/setting.js";
+import { getConfig, updateConfig, syncFoodImg } from "../../api/setting.js";
 export default {
   name: "pictureManagement",
   data() {

+ 138 - 0
src/components/settingComponents/print.vue

@@ -0,0 +1,138 @@
+<template>
+  <div class="shopInfo">
+    <el-row class="order_tab">
+      <el-col :span="24">
+        <div class="tabList">
+          <div class="tab_item" @click="changeTabs(i)" :class="{'tab_item_ac':tabNum==i?true:false}" v-for="(item,i) in tabList" :key="i">
+            <span class="item" :class="tabNum==i?'active-item':''" v-if="!item.children">{{item.name}}</span>
+            <el-dropdown v-else @command="chooseCoupon">
+              <span class="el-dropdown-link item" :class="tabNum==i?'active-item':''">
+                {{item.name}}<i class="el-icon-arrow-down el-icon--right"></i>
+              </span>
+              <el-dropdown-menu slot="dropdown">
+                <el-dropdown-item :command="v.command" v-for="(v,index) in item.children" :key="index">{{v.name}}</el-dropdown-item>
+              </el-dropdown-menu>
+            </el-dropdown>
+            <div class="tab_line"></div>
+          </div>
+        </div>
+      </el-col>
+    </el-row>
+    <el-row class="content">
+      <component v-if="renderComponent" :is="activeName"></component>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import printerList from "./print/printerList.vue";
+import a4Printer from "./print/a4Printer.vue";
+import greetingCardPrinter from "./print/greetingCardPrinter.vue";
+import usbPrinter from "../shopCompoents/bindUsbPrint.vue";
+export default {
+  name: "print",
+  components: {
+    printerList,
+    usbPrinter,
+    a4Printer,
+    greetingCardPrinter,
+  },
+  data() {
+    return {
+      activeName: "printerList",
+      tabList: [
+        { name: "云打印", index: 0, activeName: "printerList" },
+        { name: "有线打印", index: 1, activeName: "usbPrinter" },
+        // { name: "A4打印", index: 2, activeName: "a4Printer" },
+        { name: "贺卡打印", index: 3, activeName: "greetingCardPrinter" },
+      ],
+      tabNum: 0,
+      renderComponent: true,
+    };
+  },
+  created() {
+    let index = this.$route.params.tabNum ?? 0;
+    console.log(this.$route);
+    this.changeTabs(index);
+  },
+  methods: {
+    chooseCoupon(e) {
+      this.tabNum = 2;
+      this.activeName = e;
+    },
+    forceRerender() {
+      // 从 DOM 中删除 my-component 组件
+      this.renderComponent = false;
+      this.$nextTick(() => {
+        // 在 DOM 中添加 my-component 组件
+        this.renderComponent = true;
+      });
+    },
+    changeTabs(i) {
+      if (i === this.tabNum) {
+        this.forceRerender();
+        return;
+      }
+      this.tabNum = i;
+      this.activeName = this.tabList[i].activeName;
+    },
+  },
+};
+</script>
+
+<!-- Add "scoped" attribute to limit CSS to this component only -->
+<style scoped lang="scss">
+.shopInfo {
+  .order_tab {
+    width: 100%;
+    height: 74px;
+    background: #fff;
+
+    .tabList {
+      width: 100%;
+      height: 74px;
+      padding-top: 20px;
+      padding-left: 36px;
+      box-sizing: border-box;
+      display: flex;
+
+      .tab_item {
+        min-width: 58px;
+        margin-right: 56px;
+        .item {
+          font-size: 16px;
+          font-weight: 500;
+          color: #b1b1b1;
+          position: relative;
+          text-align: center;
+          cursor: pointer;
+        }
+        .active-item {
+          color: #fc7200;
+        }
+        .tab_line {
+          width: 58px;
+          height: 6px;
+          background: #fff;
+          border-radius: 3px;
+          margin: 15px auto 0;
+        }
+      }
+
+      .tab_item_ac {
+        color: #fc7200;
+
+        .tab_line {
+          background: #fc7200;
+        }
+      }
+    }
+  }
+
+  .content {
+    width: 100%;
+    margin-top: 10px;
+    box-sizing: border-box;
+  }
+}
+</style>

+ 387 - 0
src/components/settingComponents/print/a4Printer.vue

@@ -0,0 +1,387 @@
+<template>
+  <div class="printer-list">
+    <div class="model">
+      <div class="title">
+        <div class="name">A4打印</div>
+      </div>
+      <div class="setting-model">
+        <div class="list">
+          <div class="item" v-for="(v,i) in list" :key=i>
+            <div class="left">
+              <div class="left-top">
+                <div class="name">{{v.name}}</div>
+              </div>
+              <div class="left-bot">{{v.tips}}</div>
+            </div>
+            <div class="right">
+              <el-switch @change="change(v)" v-model="v.value" :active-value="1" :inactive-value="0" active-color="#FC7200" inactive-color="#999" />
+            </div>
+          </div>
+        </div>
+      </div>
+      <div class="printer-list">
+        <div class="item" v-for="(v,i) in printerList" :key="i">
+          <img class="img" :src="require(`../../../../static/image/printer-online-${v.onlineStatus}.png`)" alt="">
+          <div class="name">{{v.name}}</div>
+          <div class="shop-name">{{v.shopName}}</div>
+          <div class="btns">
+            <img @click.stop="printTest(v)" src="../../../../static/image/print-icon.png" alt="">
+            <img @click.stop="addPrinter(v)" src="../../../../static/image/edit-icon.png" alt="">
+            <img @click.stop="deletePrinter(v)" src="../../../../static/image/delete-icon.png" alt="">
+          </div>
+        </div>
+        <div class="item" @click.stop="addPrinter('')">
+          <img class="img" src="../../../../static/image/icon-add.png" alt="">
+          <div class="name">添加打印云盒</div>
+          <div class="shop-name"> </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import printerAdd from "./printerAdd";
+import {
+  getShopList,
+  shopDeviceList,
+  deviceDetail,
+  deviceList,
+  deviceAdd,
+  deviceDelete,
+  deviceStatus,
+  printTest,
+  shopListNew,
+} from "../../../api/shop";
+export default {
+  name: "a4Printer",
+  components: {
+    printerAdd,
+  },
+  data() {
+    return {
+      list: [
+        {
+          name: "开启电脑打印",
+          value: 1,
+          field: "openAutoorder",
+          tips: "开启后订单打印将使用电脑打印机,如需自动打印,请开启下方云盒打印",
+        },
+        {
+          name: "使用云盒打印",
+          value: 1,
+          field: "openAutoorder",
+          tips: "使用智能打印云盒,实现A4带图自动打印",
+        },
+        {
+          name: "开通自动打印",
+          value: 1,
+          field: "openAutoorder",
+          tips: "开通后将使用云盒模式自动打印订单",
+        }
+      ],
+    };
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {},
+  // 方法集合
+  methods: {
+    printTest(v) {
+      printTest({ deviceSn: v.deviceSn }).then((res) => {
+        if (res.code === 200) {
+          this.$message({
+            type: "success",
+            message: "操作成功!",
+          });
+        } else {
+          this.$message({
+            type: "error",
+            message: res.msg,
+          });
+        }
+      });
+    },
+    deletePrinter(v) {
+      this.$confirm("此操作将删除打印机, 是否继续?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+        center: true,
+      })
+        .then(() => {
+          deviceDelete({ id: v.id }).then((res) => {
+            if (res.code === 200) {
+              this.$message({
+                type: "error",
+                message: "删除成功!",
+              });
+              this.refreshData();
+            } else {
+              this.$message({
+                type: "error",
+                message: res.msg,
+              });
+            }
+          });
+        })
+        .catch(() => {
+          this.$message({
+            type: "info",
+            message: "已取消删除",
+          });
+        });
+    },
+    refreshData() {
+      this.getPrinterNum();
+      this.getPrinterList();
+    },
+    addPrinter(e) {
+      console.log(e);
+      if (!e) {
+        this.$refs.printerAdd.init();
+      } else {
+        this.$refs.printerAdd.init(JSON.parse(JSON.stringify(e)));
+      }
+    },
+    getPrinterList() {
+      shopDeviceList({ deviceType: 2 }).then((res) => {
+        if (res.code === 200) {
+          this.printerList = res.data;
+        } else {
+          this.$message({
+            type: "error",
+            message: res.msg,
+          });
+        }
+      });
+    },
+    getPrinterNum() {
+      deviceStatus().then((res) => {
+        if (res.code === 200) {
+          this.pinter = res.data;
+        } else {
+          this.$message({
+            type: "error",
+            message: res.msg,
+          });
+        }
+      });
+    },
+    getDeviceList() {
+      deviceList({ type: 2 }).then((res) => {
+        if (res.code === 200) {
+          this.deviceList = res.data;
+        } else {
+          this.$message({
+            type: "error",
+            message: res.msg,
+          });
+        }
+      });
+    },
+    getShopList() {
+      shopListNew().then((res) => {
+        if (res.code === 200) {
+          this.shopList = res.data;
+        } else {
+          this.$message({
+            type: "error",
+            message: res.msg,
+          });
+        }
+      });
+    },
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  created() {
+    this.getPrinterNum();
+    this.getPrinterList();
+    this.getDeviceList();
+    this.getShopList();
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {},
+  // 生命周期 - 创建之前
+  beforeCreate() {},
+  // 生命周期 - 挂载之前
+  beforeMount() {},
+  // 生命周期 - 更新之前
+  beforeUpdate() {},
+  // 生命周期 - 更新之后
+  updated() {},
+  // 生命周期 - 销毁之前
+  beforeDestroy() {},
+  // 生命周期 - 销毁完成
+  destroyed() {},
+  // 如果页面有keep-alive缓存功能,这个函数会触发
+  activated() {},
+};
+</script>
+
+<style lang="scss" scoped  type="text/css">
+.model {
+  .title {
+    position: relative;
+    display: flex;
+    align-items: center;
+    font-size: 16px;
+    font-weight: bold;
+    line-height: 22px;
+    color: #333333;
+    padding-left: 10px;
+    margin-top: 24px;
+  }
+  .title::before {
+    width: 3px;
+    height: 16px;
+    background: rgba(252, 114, 0, 0.39);
+    border-radius: 2px;
+    content: "";
+    position: absolute;
+    top: 2px;
+    left: 0;
+  }
+  /deep/ .el-button--default:hover {
+    background-color: rgba(252, 114, 0, 0.2);
+    border-color: rgba(252, 114, 0, 0.2);
+    color: #fc7200;
+  }
+  /deep/ .el-button--primary {
+    background-color: #fc7200;
+    border-color: #fc7200;
+  }
+  .setting-model {
+    .title {
+      position: relative;
+      font-size: 16px;
+      font-weight: bold;
+      line-height: 22px;
+      color: #333333;
+      padding-left: 10px;
+      margin-top: 24px;
+      .tips {
+        font-size: 14px;
+        font-weight: 400;
+        line-height: 22px;
+        color: #999999;
+      }
+    }
+    .title::before {
+      width: 3px;
+      height: 16px;
+      background: #fc7200;
+      border-radius: 2px;
+      content: "";
+      position: absolute;
+      top: 2px;
+      left: 0;
+    }
+    .list {
+      .item {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        background: #ffffff;
+        margin-top: 10px;
+        padding: 16px 20px;
+        .left {
+          display: flex;
+          flex-direction: column;
+          font-size: 14px;
+          font-weight: bold;
+          line-height: 20px;
+          color: #000000;
+          .left-top {
+            display: flex;
+            align-items: center;
+            .set {
+              font-weight: 400;
+              color: #fc7200;
+              margin-left: 10px;
+              cursor: pointer;
+            }
+          }
+          .left-bot {
+            margin-top: 2px;
+            font-size: 12px;
+            font-weight: 400;
+            line-height: 17px;
+            color: #999999;
+          }
+        }
+        .right {
+          display: flex;
+          align-items: center;
+          .time {
+            font-size: 12px;
+            font-family: PingFang SC;
+            font-weight: 400;
+            line-height: 17px;
+            color: #333333;
+            margin-right: 20px;
+          }
+          .time1 {
+            color: #999999;
+          }
+          .con {
+            font-size: 14px;
+            font-weight: 400;
+            line-height: 20px;
+            color: #fc7200;
+            padding-left: 20px;
+            cursor: pointer;
+          }
+          .con1 {
+            color: #999999;
+          }
+        }
+      }
+    }
+  }
+  .printer-list {
+    display: flex;
+    flex-wrap: wrap;
+    .item {
+      position: relative;
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 320px;
+      height: 182px;
+      background: #ffffff;
+      border-radius: 8px;
+      margin: 10px 20px 0 0;
+      cursor: pointer;
+      .img {
+        width: 80px;
+        height: 80px;
+      }
+      .name {
+        font-size: 14px;
+        font-weight: 500;
+        line-height: 20px;
+        color: #333333;
+      }
+      .shop-name {
+        font-size: 12px;
+        font-weight: 400;
+        line-height: 20px;
+        color: #999999;
+      }
+      .btns {
+        position: absolute;
+        top: 10px;
+        right: 0;
+        img {
+          width: 20px;
+          height: 20px;
+          margin-right: 10px;
+        }
+      }
+    }
+  }
+}
+</style>

File diff ditekan karena terlalu besar
+ 1086 - 0
src/components/settingComponents/print/greetingCardPrinter.vue


+ 46 - 23
src/components/shopCompoents/printerAdd.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="shopAdd">
     <!-- 打印机新增、编辑 -->
-    <el-dialog width="40%" :title="title" destroy-on-close center :visible.sync="showVisible">
+    <el-dialog width="600px" :title="title" :destroy-on-close="true" center :visible.sync="showVisible">
       <el-form :model="form" ref="form" label-width="120px">
         <el-form-item label="选择打印机" prop="deviceType">
           <div class="category_box">
@@ -10,41 +10,46 @@
             </div>
           </div>
         </el-form-item>
+        <el-form-item label="关联门店">
+          <el-select v-model="form.shopId" placeholder="请选择关联门店">
+            <el-option v-for="v in shopList" :key="v.id" :label="v.name" :value="v.id"></el-option>
+          </el-select>
+        </el-form-item>
         <el-form-item label="打印机名称" prop="name">
-          <el-input v-model="form.name" placeholder="给这台打印机取个名字吧" autocomplete="off" style="width: 100%">
+          <el-input clearable v-model="form.name" placeholder="给这台打印机取个名字吧" autocomplete="off" style="width: 100%">
           </el-input>
         </el-form-item>
         <el-form-item label="打印机编号" prop="deviceSn">
-          <el-input v-model="form.deviceSn" placeholder="查看打印机底部标签" autocomplete="off" style="width: 100%">
+          <el-input clearable v-model="form.deviceSn" placeholder="查看打印机底部标签" autocomplete="off" style="width: 100%">
           </el-input>
         </el-form-item>
-        <el-form-item label="打印机KEY" prop="deviceSecret">
-          <el-input v-model="form.deviceSecret" placeholder="查看打印机底部标签" autocomplete="off" style="width: 100%">
+        <el-form-item label="打印机KEY" prop="deviceSecret" v-if="form.deviceType!==25">
+          <el-input clearable v-model="form.deviceSecret" placeholder="查看打印机底部标签" autocomplete="off" style="width: 100%">
           </el-input>
         </el-form-item>
-        <el-form-item label="自动打印接单" prop="deviceSecret">
+        <el-form-item label="接单自动打印" prop="deviceSecret">
           <el-switch v-model="form.openOrderPrint" :active-value="1" :inactive-value="0" active-color="#FC7200" inactive-color="#999" />
         </el-form-item>
-        <el-form-item label="自动打印取消单" prop="deviceSecret">
+        <el-form-item label="取消单自动打印" prop="deviceSecret">
           <el-switch v-model="form.openOrderCancelPrint" :active-value="1" :inactive-value="0" active-color="#FC7200" inactive-color="#999" />
         </el-form-item>
         <el-form-item label="打印份数">
           <div class="printer-num">
-            <img @click="reduce(1)" src="../../../static/image/icon_reduce.png" class="reduce" alt="" srcset="" />
+            <img @click="reduce(1)" src="../../../../static/image/icon_reduce.png" class="reduce" alt="" srcset="" />
             <div class="num">{{ form.printCustomerCount }} 份</div>
-            <img @click="add(1)" src="../../../static/image/icon_add.png" class="add" alt="" srcset="" />
+            <img @click="add(1)" src="../../../../static/image/icon_add.png" class="add" alt="" srcset="" />
             <div class="name">客户联</div>
           </div>
           <div class="printer-num">
-            <img @click="reduce(2)" src="../../../static/image/icon_reduce.png" class="reduce" alt="" srcset="" />
+            <img @click="reduce(2)" src="../../../../static/image/icon_reduce.png" class="reduce" alt="" srcset="" />
             <div class="num">{{ form.printMerchantCount }} 份</div>
-            <img @click="add(2)" src="../../../static/image/icon_add.png" class="add" alt="" srcset="" />
+            <img @click="add(2)" src="../../../../static/image/icon_add.png" class="add" alt="" srcset="" />
             <div class="name">商家联</div>
           </div>
           <div class="printer-num">
-            <img @click="reduce(3)" src="../../../static/image/icon_reduce.png" class="reduce" alt="" srcset="" />
+            <img @click="reduce(3)" src="../../../../static/image/icon_reduce.png" class="reduce" alt="" srcset="" />
             <div class="num">{{ form.printKitchenCount }} 份</div>
-            <img @click="add(3)" src="../../../static/image/icon_add.png" class="add" alt="" srcset="" />
+            <img @click="add(3)" src="../../../../static/image/icon_add.png" class="add" alt="" srcset="" />
             <div class="name">厨房联</div>
           </div>
         </el-form-item>
@@ -57,7 +62,7 @@
 </template>
 
 <script>
-import { deviceAdd } from "../../api/shop.js";
+import { deviceAdd } from "../../../api/shop.js";
 export default {
   props: {
     devices: {
@@ -66,12 +71,24 @@ export default {
         return [];
       },
     },
+    shopList: {
+      type: Array,
+      default: function () {
+        return [];
+      },
+    },
   },
   data() {
     return {
       title: "添加打印机",
       showVisible: false,
-      form: {},
+      form: {
+        openOrderPrint: 1,
+        openOrderCancelPrint: 1,
+        printCustomerCount: 1,
+        printMerchantCount: 1,
+        printKitchenCount: 1,
+      },
       revieweds: [],
       loading: false,
       isEdit: false,
@@ -84,9 +101,10 @@ export default {
         return;
       }
       this.$set(this.form, "deviceType", v.type);
+      this.$set(this.form, "name", v.name);
       this.form.deviceId = v.id;
     },
-    init(e, shopId) {
+    init(e) {
       if (e) {
         this.isEdit = true;
         this.title = "编辑打印机";
@@ -95,14 +113,16 @@ export default {
         this.isEdit = false;
         this.title = "添加打印机";
         this.form = {
+          openOrderPrint: 1,
+          openOrderCancelPrint: 1,
+          printCustomerCount: 1,
+          printMerchantCount: 1,
+          printKitchenCount: 1,
+          deviceType: "",
           name: "",
-          deviceSn: "",
-          deviceSecret: "",
           deviceId: "",
-          printCustomerCount: 0,
-          printMerchantCount: 0,
-          printKitchenCount: 0,
-          shopId,
+          shopId: "",
+          deviceSn: "",
         };
       }
       this.showVisible = true;
@@ -126,7 +146,10 @@ export default {
           message: "请填写打印机编号!",
         });
       }
-      if (!this.form.deviceSecret.trim()) {
+      if (
+        this.form.deviceType !== 25 &&
+        (!this.form.deviceSecret || !this.form.deviceSecret.trim())
+      ) {
         return this.$message({
           type: "error",
           message: "请填写打印机Key!",

+ 302 - 0
src/components/settingComponents/print/printerList.vue

@@ -0,0 +1,302 @@
+<template>
+  <div class="printer-list">
+    <div class="model">
+      <div class="title">
+        <div class="name">云打印</div>
+        <div class="status-list">
+          <div class="status">
+            <div class="bg1"></div>
+            <div class="con">在线{{pinter.onlineNum}}</div>
+          </div>
+          <div class="status">
+            <div class="bg1 bg2"></div>
+            <div class="con">离线{{pinter.offlineNum}}</div>
+          </div>
+          <div class="status">
+            <div class="bg1 bg3"></div>
+            <div class="con">异常{{pinter.abnormalNum}}</div>
+          </div>
+        </div>
+      </div>
+      <div class="printer-list">
+        <div class="item" v-for="(v,i) in printerList" :key="i">
+          <img class="img" :src="require(`../../../../static/image/printer-online-${v.onlineStatus}.png`)" alt="">
+          <div class="name">{{v.name}}</div>
+          <div class="shop-name">{{v.shopName}}</div>
+          <div class="btns">
+            <img @click.stop="printTest(v)" src="../../../../static/image/print-icon.png" alt="">
+            <img @click.stop="addPrinter(v)" src="../../../../static/image/edit-icon.png" alt="">
+            <img @click.stop="deletePrinter(v)" src="../../../../static/image/delete-icon.png" alt="">
+          </div>
+        </div>
+        <div class="item" @click.stop="addPrinter('')">
+          <img class="img" src="../../../../static/image/icon-add.png" alt="">
+          <div class="name">添加打印机</div>
+          <div class="shop-name"> </div>
+        </div>
+      </div>
+    </div>
+    <printer-add :shopList="shopList" @shopDeviceList="refreshData" ref="printerAdd" :devices="deviceList"></printer-add>
+  </div>
+</template>
+
+<script>
+import printerAdd from "./printerAdd";
+import {
+  getShopList,
+  shopDeviceList,
+  deviceDetail,
+  deviceList,
+  deviceAdd,
+  deviceDelete,
+  deviceStatus,
+  printTest,
+  shopListNew,
+} from "../../../api/shop";
+export default {
+  name: "printerList",
+  components: {
+    printerAdd,
+  },
+  data() {
+    return {
+      pinter: {},
+      printerList: [],
+      deviceList: [],
+      shopList: [],
+    };
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {},
+  // 方法集合
+  methods: {
+    printTest(v) {
+      printTest({ deviceSn: v.deviceSn }).then((res) => {
+        if (res.code === 200) {
+          this.$message({
+            type: "success",
+            message: "操作成功!",
+          });
+        } else {
+          this.$message({
+            type: "error",
+            message: res.msg,
+          });
+        }
+      });
+    },
+    deletePrinter(v) {
+      this.$confirm("此操作将删除打印机, 是否继续?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+        center: true,
+      })
+        .then(() => {
+          deviceDelete({ id: v.id }).then((res) => {
+            if (res.code === 200) {
+              this.$message({
+                type: "error",
+                message: "删除成功!",
+              });
+              this.refreshData();
+            } else {
+              this.$message({
+                type: "error",
+                message: res.msg,
+              });
+            }
+          });
+        })
+        .catch(() => {
+          this.$message({
+            type: "info",
+            message: "已取消删除",
+          });
+        });
+    },
+    refreshData() {
+      this.getPrinterNum();
+      this.getPrinterList();
+    },
+    addPrinter(e) {
+      console.log(e);
+      if (!e) {
+        this.$refs.printerAdd.init();
+      } else {
+        this.$refs.printerAdd.init(JSON.parse(JSON.stringify(e)));
+      }
+    },
+    getPrinterList() {
+      shopDeviceList({ deviceType: 2 }).then((res) => {
+        if (res.code === 200) {
+          this.printerList = res.data;
+        } else {
+          this.$message({
+            type: "error",
+            message: res.msg,
+          });
+        }
+      });
+    },
+    getPrinterNum() {
+      deviceStatus().then((res) => {
+        if (res.code === 200) {
+          this.pinter = res.data;
+        } else {
+          this.$message({
+            type: "error",
+            message: res.msg,
+          });
+        }
+      });
+    },
+    getDeviceList() {
+      deviceList({ type: 2 }).then((res) => {
+        if (res.code === 200) {
+          this.deviceList = res.data;
+        } else {
+          this.$message({
+            type: "error",
+            message: res.msg,
+          });
+        }
+      });
+    },
+    getShopList() {
+      shopListNew().then((res) => {
+        if (res.code === 200) {
+          this.shopList = res.data;
+        } else {
+          this.$message({
+            type: "error",
+            message: res.msg,
+          });
+        }
+      });
+    },
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  created() {
+    this.getPrinterNum();
+    this.getPrinterList();
+    this.getDeviceList();
+    this.getShopList();
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {},
+  // 生命周期 - 创建之前
+  beforeCreate() {},
+  // 生命周期 - 挂载之前
+  beforeMount() {},
+  // 生命周期 - 更新之前
+  beforeUpdate() {},
+  // 生命周期 - 更新之后
+  updated() {},
+  // 生命周期 - 销毁之前
+  beforeDestroy() {},
+  // 生命周期 - 销毁完成
+  destroyed() {},
+  // 如果页面有keep-alive缓存功能,这个函数会触发
+  activated() {},
+};
+</script>
+
+<style lang="scss" scoped  type="text/css">
+.model {
+  .title {
+    position: relative;
+    display: flex;
+    align-items: center;
+    font-size: 16px;
+    font-weight: bold;
+    line-height: 22px;
+    color: #333333;
+    padding-left: 10px;
+    margin-top: 24px;
+    .status-list {
+      display: flex;
+      align-items: center;
+      font-size: 14px;
+      font-weight: 400;
+      line-height: 22px;
+      color: #999999;
+      .status {
+        display: flex;
+        align-items: center;
+        margin-left: 30px;
+        .con {
+          margin-left: 5px;
+        }
+        .bg1 {
+          width: 40px;
+          height: 10px;
+          border-radius: 2px;
+          background: linear-gradient(180deg, #64c47c 0%, #1aaa3d 100%);
+        }
+        .bg2 {
+          background: rgba(204, 204, 204, 0.39);
+        }
+        .bg3 {
+          background: linear-gradient(180deg, #ff8a8a 0%, #e60000 100%);
+        }
+      }
+    }
+  }
+  .title::before {
+    width: 3px;
+    height: 16px;
+    background: rgba(252, 114, 0, 0.39);
+    border-radius: 2px;
+    content: "";
+    position: absolute;
+    top: 2px;
+    left: 0;
+  }
+  .printer-list {
+    display: flex;
+    flex-wrap: wrap;
+    .item {
+      position: relative;
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 320px;
+      height: 182px;
+      background: #ffffff;
+      border-radius: 8px;
+      margin: 10px 20px 0 0;
+      cursor: pointer;
+      .img {
+        width: 80px;
+        height: 80px;
+      }
+      .name {
+        font-size: 14px;
+        font-weight: 500;
+        line-height: 20px;
+        color: #333333;
+      }
+      .shop-name {
+        font-size: 12px;
+        font-weight: 400;
+        line-height: 20px;
+        color: #999999;
+      }
+      .btns {
+        position: absolute;
+        top: 10px;
+        right: 0;
+        img {
+          width: 20px;
+          height: 20px;
+          margin-right: 10px;
+        }
+      }
+    }
+  }
+}
+</style>

+ 39 - 0
src/components/settingComponents/system.vue

@@ -0,0 +1,39 @@
+<template>
+  <div>这是系统设置</div>
+</template>
+
+<script>
+export default {
+  name: "system",
+  data() {
+    return {};
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {},
+  // 方法集合
+  methods: {},
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  created() {},
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {},
+  // 生命周期 - 创建之前
+  beforeCreate() {},
+  // 生命周期 - 挂载之前
+  beforeMount() {},
+  // 生命周期 - 更新之前
+  beforeUpdate() {},
+  // 生命周期 - 更新之后
+  updated() {},
+  // 生命周期 - 销毁之前
+  beforeDestroy() {},
+  // 生命周期 - 销毁完成
+  destroyed() {},
+  // 如果页面有keep-alive缓存功能,这个函数会触发
+  activated() {},
+};
+</script>
+
+<style lang="scss" scoped  type="text/css">
+</style>

+ 99 - 267
src/components/settingComponents/voiceSetting.vue

@@ -1,129 +1,64 @@
 <template>
   <div class="voice">
-    <template v-if="memberType !== 1">
-      <div class="top-set">
-        <div class="t-left">
-          自动接单
-        </div>
-        <div class="t-right">
-          <el-switch @change="updateConfig" v-model="openAutoorder" :active-value="1" :inactive-value="0" active-color="#FC7200" inactive-color="#999" />
-        </div>
-      </div>
-      <div class="top-set">
-        <div class="t-left">
-          自动配送(暂不支持预约单)
-          <span @click="openSetTime">[时长设置]</span>
-        </div>
-        <div class="t-right">
-          <span>默认下单{{autodeliveryOrderTime}}分钟后</span>
-          <el-switch @change="autodelivery" v-model="openAutodelivery" :active-value="1" :inactive-value="0" active-color="#FC7200" inactive-color="#999" />
-        </div>
-      </div>
-      <div class="top-set">
-        <div class="t-left">
-          自动打印
-          <span style="color: #999;">(开启后将为您自动打印小票)</span>
-        </div>
-        <div class="t-right">
-          <el-switch @change="updateConfig" v-model="openPrintSwitch" :active-value="1" :inactive-value="0" active-color="#FC7200" inactive-color="#999" />
-        </div>
-      </div>
-    </template>
-    <div class="voice-content">
-      <div class="top-set" style="border-bottom: 1px solid #eee;">
-        <div class="t-left">
-          语音播报
-        </div>
-        <div class="t-right">
-          <span>一键开启</span>
-          <el-switch @change="changeMessageStatus" v-model="msasterSwitch" :active-value="1" :inactive-value="0"  active-color="#FC7200" inactive-color="#999" />
+    <div class="model">
+      <div class="title">通知设置</div>
+      <div class="list">
+        <div class="item">
+          <div class="left">
+            <div class="left-top">
+              <div class="name">语音开启</div>
+            </div>
+          </div>
+          <div class="right">
+            <el-switch @change="changeMessageStatus" v-model="open" :active-value="1" :inactive-value="0" active-color="#FC7200" inactive-color="#999" />
+          </div>
         </div>
       </div>
-      <div class="voice-list">
-        <el-row>
-          <el-col :span="8" v-for="(item, index) in voiceList" :key="index">
-            <div class="item">
-              <div class="left">
-                <img @click="play(index)" src="../../../static/image/voice-icon.png" class="voice-icon" />
-                <span>{{ item.name }}</span>
-              </div>
-              <div class="right">
-                <el-switch @change="updateSavePushMessageStatus" v-model="item.msasterSwitch" :active-value="1" :inactive-value="0" active-color="#FC7200" inactive-color="#999" />
-              </div>
+    </div>
+    <div class="model">
+      <div class="title">播报类型选择</div>
+      <div class="list">
+        <div class="item" v-for="(v,i) in voiceList" :key=i>
+          <div class="left">
+            <div class="left-top">
+              <img @click="play(i)" src="../../../static/image/voice-icon.png" class="voice-icon" />
+              <div class="name">{{v.name}}</div>
             </div>
-          </el-col>
-        </el-row>
+          </div>
+          <div class="right">
+            <el-switch @change="updateSavePushMessageStatus" v-model="v.open" :active-value="1" :inactive-value="0" active-color="#FC7200" inactive-color="#999" />
+          </div>
+        </div>
       </div>
     </div>
-    <!-- // 选择自动配送运力 -->
-    <el-dialog title="自动配送设置" @close="getConfig" :visible.sync="centerDialogVisible" width="800px" center>
-      <el-form label-width="120px">
-        <el-form-item label="自动接单时间">
-          <el-input size="small" class="auto-time" v-model="autodeliveryOrderTime" clearable>
-            <template slot="append">分钟</template>
-          </el-input>
-        </el-form-item>
-        <!-- <el-form-item label="自动配送运力">
-          <el-checkbox-group v-model="autodeliveryIds">
-            <el-checkbox :label="String(v.deliveryId)" name="type" v-for="(v,i) in deliveryList" :key="i">{{v.name}}</el-checkbox>
-          </el-checkbox-group>
-        </el-form-item> -->
-      </el-form>
-      <span slot="footer" class="dialog-footer">
-        <el-button size="medium" @click="getConfig">取 消</el-button>
-        <el-button size='medium' type="primary" @click="confirm">确 定</el-button>
-      </span>
-    </el-dialog>
   </div>
 </template>
 
 <script>
 import {
-  getConfig,
-  updateConfig,
   queryPushMessageStatus,
   updateSavePushMessageStatus,
 } from "../../api/setting.js";
-// import { floorListDelivery } from "../../api/shop.js";
 export default {
+  name: "voiceSetting",
   data() {
     return {
       voiceList: [],
-      openAutodelivery: 0,
-      openAutoorder: 0,
-      openPrintSwitch: 0,
-      autodeliveryOrderTime: 0,
-      msasterSwitch: 1,
-      centerDialogVisible: false,
-      // autodeliveryIds: [],
-      deliveryList: [], // 运力列表
-      deliveryIdList: [],
-      memberType: this.$store.state.userInfo.memberType,
+      open: 1,
     };
   },
-  watch:{
-    "$store.state.userInfo": {
-      handler(newVal, oldVal) {
-        this.memberType = newVal.memberType;
-      },
-      deep: true,
-    },
-  },
-  created() {
-    this.getConfig();
-    this.queryPushMessageStatus();
-    // this.floorListDelivery();
-  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {},
+  // 方法集合
   methods: {
-    openSetTime(){
-      if(this.openAutodelivery){
-        this.centerDialogVisible = true
-      }else{
-        this.$message({
-          type:'info',
-          message: '请先开启自动配送再设置时长!'
-        })
-      }
+    changeMessageStatus() {
+      this.voiceList = this.voiceList.map((v) => {
+        v.open = this.open;
+        return v;
+      });
+      this.updateSavePushMessageStatus();
     },
     play(index) {
       let src = "https://pc.liebaoai.cn/audio/alone.mp3";
@@ -162,57 +97,6 @@ export default {
       let mp3 = new Audio(src);
       mp3.play(); //播放 mp3这个音频对象
     },
-    confirm() {
-      // if (!this.autodeliveryIds.length) {
-      //   return this.$message({
-      //     type: "error",
-      //     message: "开启自动配送必须选择至少一个运力平台!",
-      //   });
-      // }
-      this.centerDialogVisible = true;
-      this.updateConfig();
-    },
-    // floorListDelivery() {
-    //   floorListDelivery().then((res) => {
-    //     if (res.code === 200) {
-    //       this.deliveryList = res.data;
-    //       this.deliveryIdList = this.deliveryList.map((v) => {
-    //         return String(v.deliveryId);
-    //       });
-    //     } else {
-    //       this.$message({
-    //         type: "error",
-    //         message: res.msg,
-    //       });
-    //     }
-    //   });
-    // },
-    changeMessageStatus() {
-      this.voiceList = this.voiceList.map((v) => {
-        v.msasterSwitch = this.msasterSwitch;
-        return v;
-      });
-      this.updateSavePushMessageStatus();
-    },
-    getConfig() {
-      this.centerDialogVisible = false;
-      getConfig().then((res) => {
-        if (res.code === 200) {
-          this.autodeliveryOrderTime = res.data.autodeliveryOrderTime / 60;
-          this.openAutodelivery = res.data.openAutodelivery;
-          this.openAutoorder = res.data.openAutoorder;
-          this.openPrintSwitch = res.data.openPrintSwitch;
-          // this.autodeliveryIds = res.data.autodeliveryIds
-          //   ? res.data.autodeliveryIds.split(",")
-          //   : [];
-        } else {
-          this.$message({
-            type: "error",
-            message: res.msg,
-          });
-        }
-      });
-    },
     queryPushMessageStatus() {
       queryPushMessageStatus().then((res) => {
         if (res.code === 200) {
@@ -243,136 +127,84 @@ export default {
         }
       );
     },
-    autodelivery() {
-      if (this.openAutodelivery === 1) {
-        this.centerDialogVisible = true;
-        // this.autodeliveryIds = this.deliveryIdList
-      } else {
-        // this.autodeliveryIds = "";
-        this.autodeliveryOrderTime = 5;
-        this.updateConfig();
-      }
-    },
-    updateConfig() {
-      let params = {
-        autodeliveryOrderTime: this.autodeliveryOrderTime * 60,
-        // autodeliveryIds: this.autodeliveryIds.toString(),
-        openAutodelivery: this.openAutodelivery,
-        openAutoorder: this.openAutoorder,
-        openPrintSwitch: this.openPrintSwitch,
-      };
-      updateConfig(params).then((res) => {
-        if (res.code === 200) {
-          this.$message({
-            type: "success",
-            message: "修改成功!",
-          });
-          this.getConfig();
-        } else {
-          this.$message({
-            type: "error",
-            message: res.msg,
-          });
-        }
-      });
-    },
   },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  created() {
+    this.queryPushMessageStatus();
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {},
+  // 生命周期 - 创建之前
+  beforeCreate() {},
+  // 生命周期 - 挂载之前
+  beforeMount() {},
+  // 生命周期 - 更新之前
+  beforeUpdate() {},
+  // 生命周期 - 更新之后
+  updated() {},
+  // 生命周期 - 销毁之前
+  beforeDestroy() {},
+  // 生命周期 - 销毁完成
+  destroyed() {},
+  // 如果页面有keep-alive缓存功能,这个函数会触发
+  activated() {},
 };
 </script>
 
-<style lang="scss" scoped>
-.voice {
-  /deep/ .el-checkbox__input.is-checked .el-checkbox__inner,
-  /deep/ .el-checkbox__input.is-indeterminate .el-checkbox__inner {
-    background-color: #fc7200;
-    border-color: #fc7200;
-  }
-  /deep/ .el-checkbox__input.is-checked + .el-checkbox__label {
-    color: #fc7200;
-  }
-  /deep/ .el-button--primary {
-    color: #fff;
-    background-color: #fc7200;
-    border-color: #fc7200;
-  }
-  .top-set {
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
-    padding: 20px;
-    background-color: #fff;
-    .t-left {
-      font-size: 16px;
-      font-family: PingFang SC;
-      font-weight: 600;
-      color: #333333;
-      span {
-        cursor: pointer;
-        font-size: 14px;
-        font-family: PingFang SC;
-        font-weight: 400;
-        color: #175199;
-      }
-    }
-    .t-right {
+<style lang="scss" scoped  type="text/css">
+.model {
+  .title {
+    position: relative;
+    font-size: 16px;
+    font-weight: bold;
+    line-height: 22px;
+    color: #333333;
+    padding-left: 10px;
+    margin-top: 24px;
+    .tips {
       font-size: 14px;
-      font-family: PingFang SC;
       font-weight: 400;
-      color: #b1b1b1;
+      line-height: 22px;
+      color: #999999;
     }
   }
-  .voice-content {
-    margin-top: 10px;
-    .voice-list {
-      background-color: #fff;
-      .item {
+  .title::before {
+    width: 3px;
+    height: 16px;
+    background: rgba(252, 114, 0, 0.39);
+    border-radius: 2px;
+    content: "";
+    position: absolute;
+    top: 2px;
+    left: 0;
+  }
+  .list {
+    .item {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      background: #ffffff;
+      margin-top: 10px;
+      padding: 16px 20px;
+      .left {
         display: flex;
-        justify-content: space-between;
-        align-items: center;
-        padding: 17px 22px 19px 18px;
-        .left {
+        flex-direction: column;
+        font-size: 14px;
+        font-weight: bold;
+        line-height: 20px;
+        color: #000000;
+        .left-top {
           display: flex;
           align-items: center;
           .voice-icon {
             width: 15px;
             height: 12px;
-            margin-right: 4px;
-            margin-top: 2px;
+            margin-right: 10px;
             cursor: pointer;
           }
-          span {
-            font-size: 14px;
-            font-family: PingFang SC;
-            font-weight: 400;
-            color: #333333;
-          }
         }
       }
     }
   }
-  .delivery-list {
-    display: flex;
-    flex-wrap: wrap;
-    margin-top: 20px;
-    .delivery {
-      margin: 0 20px 20px 0;
-      width: 100px;
-      height: 30px;
-      line-height: 30px;
-      text-align: center;
-      border-radius: 25px;
-      border: 1px solid #999;
-      color: #999999;
-      cursor: pointer;
-    }
-    .active {
-      border: 1px solid #fc7200;
-      color: #fff;
-      background: #fc7200;
-    }
-  }
-  .auto-time {
-    width: 150px;
-  }
 }
-</style>
+</style>

+ 146 - 0
src/components/settingComponents/waimai.vue

@@ -0,0 +1,146 @@
+<template>
+  <div class="shopInfo">
+    <el-row class="order_tab">
+      <el-col :span="24">
+        <div class="tabList">
+          <div class="tab_item" @click="changeTabs(i)" :class="{'tab_item_ac':tabNum==i?true:false}" v-for="(item,i) in tabList" :key="i">
+            <span class="item" :class="tabNum==i?'active-item':''" v-if="!item.children">{{item.name}}</span>
+            <el-dropdown v-else @command="chooseCoupon">
+              <span class="el-dropdown-link item" :class="tabNum==i?'active-item':''">
+                {{item.name}}<i class="el-icon-arrow-down el-icon--right"></i>
+              </span>
+              <el-dropdown-menu slot="dropdown">
+                <el-dropdown-item :command="v.command" v-for="(v,index) in item.children" :key="index">{{v.name}}</el-dropdown-item>
+              </el-dropdown-menu>
+            </el-dropdown>
+            <div class="tab_line"></div>
+          </div>
+        </div>
+      </el-col>
+    </el-row>
+    <el-row class="content">
+      <component v-if="renderComponent" :is="activeName"></component>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import printerList from "./print/printerList.vue";
+import a4Printer from "./print/a4Printer.vue";
+import greetingCardPrinter from "./print/greetingCardPrinter.vue";
+import usbPrinter from "../shopCompoents/bindUsbPrint.vue";
+import pictureManagement from "./pictureManagement.vue";
+import addressManagement from "./addressManagement.vue";
+import deliverySetting from "./deliverySetting.vue";
+import voiceSetting from "./voiceSetting.vue";
+export default {
+  name: "waimai",
+  components: {
+    printerList,
+    usbPrinter,
+    a4Printer,
+    greetingCardPrinter,
+    pictureManagement,
+    addressManagement,
+    deliverySetting,
+    voiceSetting,
+  },
+  data() {
+    return {
+      activeName: "deliverySetting",
+      tabList: [
+        { name: "配送设置", index: 0, activeName: "deliverySetting" },
+        { name: "语音设置", index: 1, activeName: "voiceSetting" },
+        { name: "商品管理", index: 2, activeName: "pictureManagement" },
+        { name: "常用地址", index: 3, activeName: "addressManagement" },
+      ],
+      tabNum: 0,
+      renderComponent: true,
+    };
+  },
+  created() {
+    let index = this.$route.params.tabNum ?? 0;
+    console.log(this.$route);
+    this.changeTabs(index);
+  },
+  methods: {
+    chooseCoupon(e) {
+      this.tabNum = 2;
+      this.activeName = e;
+    },
+    forceRerender() {
+      // 从 DOM 中删除 my-component 组件
+      this.renderComponent = false;
+      this.$nextTick(() => {
+        // 在 DOM 中添加 my-component 组件
+        this.renderComponent = true;
+      });
+    },
+    changeTabs(i) {
+      if (i === this.tabNum) {
+        this.forceRerender();
+        return;
+      }
+      this.tabNum = i;
+      this.activeName = this.tabList[i].activeName;
+    },
+  },
+};
+</script>
+
+<!-- Add "scoped" attribute to limit CSS to this component only -->
+<style scoped lang="scss">
+.shopInfo {
+  .order_tab {
+    width: 100%;
+    height: 74px;
+    background: #fff;
+
+    .tabList {
+      width: 100%;
+      height: 74px;
+      padding-top: 20px;
+      padding-left: 36px;
+      box-sizing: border-box;
+      display: flex;
+
+      .tab_item {
+        min-width: 58px;
+        margin-right: 56px;
+        .item {
+          font-size: 16px;
+          font-weight: 500;
+          color: #b1b1b1;
+          position: relative;
+          text-align: center;
+          cursor: pointer;
+        }
+        .active-item {
+          color: #fc7200;
+        }
+        .tab_line {
+          width: 58px;
+          height: 6px;
+          background: #fff;
+          border-radius: 3px;
+          margin: 15px auto 0;
+        }
+      }
+
+      .tab_item_ac {
+        color: #fc7200;
+
+        .tab_line {
+          background: #fc7200;
+        }
+      }
+    }
+  }
+
+  .content {
+    width: 100%;
+    margin-top: 10px;
+    box-sizing: border-box;
+  }
+}
+</style>

+ 209 - 23
src/components/shopCompoents/bindDelivery.vue

@@ -28,18 +28,20 @@
             </div>
           </div>
           <div v-if="type === 5 && [2,3].includes(v.bindStatus)" :class="['status',v.bindStatus === 2 ? '' : 'bt-refuse']">{{v.bindStatus === 2 ? '审核中' : '审核失败'}}</div>
-          <div class="but" v-if="[1,9].includes(type)">
-            <div @click="bind(v)" v-if="!v.dadaBindType" class="but-con">绑定</div>
-          </div>
-          <div class="but" v-else-if="[5].includes(type)">
-            <div @click="bind(v)" v-if="v.bindStatus === 3 || !v.bindStatus" class="but-con">绑定</div>
-          </div>
-          <div class="but" v-else>
-            <div @click="bind(v)" v-if="!v.bindStatus" class="but-con">绑定</div>
-          </div>
-          <div class="but" @click="release(v)" v-if="v.bindStatus === 1">
-            <div class="but-con unbind">解绑</div>
-          </div>
+          <template v-if="memberType === 2">
+            <div class="but" v-if="[1,9].includes(type)">
+              <div @click="bind(v)" v-if="!v.dadaBindType" class="but-con">绑定</div>
+            </div>
+            <div class="but" v-else-if="[5].includes(type)">
+              <div @click="bind(v)" v-if="v.bindStatus === 3 || !v.bindStatus" class="but-con">绑定</div>
+            </div>
+            <div class="but" v-else>
+              <div @click="bind(v)" v-if="!v.bindStatus" class="but-con">绑定</div>
+            </div>
+            <div class="but" @click="release(v)" v-if="v.bindStatus === 1">
+              <div class="but-con unbind">解绑</div>
+            </div>
+          </template>
         </div>
       </div>
     </div>
@@ -65,7 +67,7 @@
     <el-dialog :title="title" :visible.sync="centerDialogVisible" width="40%" center>
       <el-form v-if="title === 'UU跑腿绑定'" :model="UUData" ref="UUData" label-width="80px" class="demo-ruleForm">
         <el-form-item label="城市" prop="cityName">
-          <el-input v-model="UUData.cityName" placeholder="请输入当前城市名称"></el-input>
+          <el-cascader style="width: 100%;" :show-all-levels="false" v-model="cityName" :options="areaData"></el-cascader>
         </el-form-item>
         <el-form-item label="手机号" prop="mobile">
           <el-input v-model="UUData.mobile" placeholder="请输入用户手机号"></el-input>
@@ -109,6 +111,55 @@
         </el-form-item>
       </el-form>
     </el-dialog>
+    <!-- 曹操送绑定 -->
+    <el-dialog title="曹操送绑定" :visible.sync="centerDialogVisible4" width="40%" center>
+      <el-form ref="form" :model="params" label-width="100px">
+        <el-form-item label="手机号">
+          <el-input v-model="ccsData.mobile" maxlength="11" placeholder="请输入手机号"></el-input>
+        </el-form-item>
+        <el-form-item label="密码">
+          <el-input v-model="ccsData.secret" placeholder="请输入密码"></el-input>
+        </el-form-item>
+        <el-form-item>
+          <el-button size="small" type="primary" @click="bindCCS">绑定</el-button>
+        </el-form-item>
+      </el-form>
+    </el-dialog>
+    <!-- 绑定裹小递 -->
+    <el-dialog title="裹小递绑定" :visible.sync="centerDialogVisible5" width="40%" center>
+      <el-form :model="gxdData" ref="gxdData" label-width="80px" class="demo-ruleForm">
+        <el-form-item label="手机号" prop="mobile">
+          <el-input v-model="gxdData.mobile" placeholder="请输入用户手机号"></el-input>
+        </el-form-item>
+        <el-form-item label="验证码" prop="validateCode">
+          <div class="code">
+            <el-input v-model="gxdData.validateCode" placeholder="请输入验证码"></el-input>
+            <div class="get-code" v-if="!showCode" @click.stop="getGxdCode">
+              获取短信验证码
+            </div>
+            <div class="get-code" v-else>{{ count }}秒</div>
+          </div>
+        </el-form-item>
+        <el-form-item>
+          <el-button size="small" type="primary" @click="bindGXD">确 定</el-button>
+        </el-form-item>
+      </el-form>
+    </el-dialog>
+    <!-- 快跑者绑定 -->
+    <el-dialog title="快跑者绑定" :visible.sync="centerDialogVisible6" width="40%" center>
+      <div class="tips">请联系您的配送团队获取团队密钥和登录的手机号</div>
+      <el-form ref="kpzData" :model="kpzData" label-width="100px">
+        <el-form-item label="手机号">
+          <el-input v-model="kpzData.mobile" maxlength="11" placeholder="请输入手机号"></el-input>
+        </el-form-item>
+        <el-form-item label="密钥">
+          <el-input v-model="kpzData.teamToken" placeholder="请输入密码"></el-input>
+        </el-form-item>
+        <el-form-item>
+          <el-button size="small" type="primary" @click="bindKPZ">绑定</el-button>
+        </el-form-item>
+      </el-form>
+    </el-dialog>
   </div>
 </template>
      
@@ -126,8 +177,14 @@ import {
   unBindDeliveryNew,
   getBindDeliveryShopList,
   unBindAptNew,
+  bindCCS,
+  bindKPZ,
+  gxdCode,
+  bindGXD,
 } from "../../api/shop";
+import areaData from "../../common/areadata.js";
 export default {
+  name: "bindDelivery",
   data() {
     return {
       deliveryList: [],
@@ -135,12 +192,30 @@ export default {
       fullscreenLoading: false,
       centerDialogVisible: false,
       centerDialogVisible2: false,
+      centerDialogVisible3: false,
+      centerDialogVisible4: false,
+      centerDialogVisible5: false,
+      centerDialogVisible6: false,
       loading: false,
       UUData: {
         cityName: "",
         mobile: "",
         validateCode: "",
       },
+      ccsData: {
+        mobile: "",
+        secret: "",
+      },
+      kpzData: {
+        mobile: "",
+        teamToken: "",
+      },
+      gxdData: {
+        mobile: "",
+        validateCode: "",
+        codeUuid: "",
+      },
+      cityName: [],
       title: "UU跑腿绑定",
       count: 60,
       showCode: false,
@@ -156,9 +231,9 @@ export default {
         merchantNo: "",
         mobile: "",
       },
-      centerDialogVisible3: false,
       sfId: "",
       sfId2: "",
+      areaData: [],
     };
   },
   watch: {
@@ -198,6 +273,14 @@ export default {
     },
   },
   created() {
+    this.areaData = areaData.map(({ name, code, children }) => ({
+      value: code,
+      label: name,
+      children: children.map(({ name, code }) => ({
+        value: code,
+        label: name,
+      })),
+    }));
     if (this.memberType !== 1) {
       this.getDeliveryList();
     }
@@ -214,6 +297,82 @@ export default {
   // 12->货拉拉
   // 13-> 美图跑腿
   methods: {
+    getGxdCode() {
+      if (!/^1[23456789]\d{9}$/.test(this.gxdData.mobile)) {
+        return this.$message.warning("请输入正确的手机号");
+      }
+      gxdCode({ mobile: this.gxdData.mobile }).then((res) => {
+        if (res.code === 200) {
+          this.gxdData.codeUuid = res.data.codeUuid;
+          this.showCode = true;
+          this.$message.success("验证码发送成功");
+          this.timer = setInterval(() => {
+            this.count--;
+            if (this.count <= 1) {
+              this.showCode = false;
+              this.count = 60;
+              clearInterval(this.timer);
+            }
+          }, 1000);
+        } else {
+          this.$message.error(res.msg);
+        }
+      });
+    },
+    bindGXD() {
+      if (!/^1[23456789]\d{9}$/.test(this.gxdData.mobile)) {
+        return this.$message.warning("请输入正确的手机号");
+      }
+      if (!this.gxdData.validateCode.trim()) {
+        return this.$message.warning("请输入验证码");
+      }
+      if (!this.gxdData.codeUuid.trim()) {
+        return this.$message.warning("codeUuid无效,请稍后重新获取验证码");
+      }
+      bindGXD(this.gxdData).then((res) => {
+        if (res.code === 200) {
+          this.$message.success("绑定成功!");
+          this.centerDialogVisible5 = false;
+          this.getDeliveryList();
+        } else {
+          this.$message.error(res.msg);
+        }
+      });
+    },
+    bindCCS() {
+      if (!/^1[23456789]\d{9}$/.test(this.ccsData.mobile)) {
+        return this.$message.warning("请输入正确的手机号");
+      }
+      if (!this.ccsData.secret.trim()) {
+        return this.$message.warning("请输入密码");
+      }
+      bindCCS(this.ccsData).then((res) => {
+        if (res.code === 200) {
+          this.$message.success("绑定成功!");
+          this.centerDialogVisible4 = false;
+          this.getDeliveryList();
+        } else {
+          this.$message.error(res.msg);
+        }
+      });
+    },
+    bindKPZ() {
+      if (!/^1[23456789]\d{9}$/.test(this.kpzData.mobile)) {
+        return this.$message.warning("请输入正确的手机号");
+      }
+      if (!this.kpzData.teamToken.trim()) {
+        return this.$message.warning("请输入密码");
+      }
+      bindKPZ(this.kpzData).then((res) => {
+        if (res.code === 200) {
+          this.$message.success("绑定成功!");
+          this.centerDialogVisible6 = false;
+          this.getDeliveryList();
+        } else {
+          this.$message.error(res.msg);
+        }
+      });
+    },
     // 顺丰绑定确定
     confirmSF() {
       if (!this.sfId.trim()) {
@@ -286,6 +445,21 @@ export default {
         this.centerDialogVisible = true;
         return;
       }
+      // 曹操送
+      if (this.type === 19) {
+        this.centerDialogVisible4 = true;
+        return;
+      }
+      // 裹小递
+      if (this.type === 18) {
+        this.centerDialogVisible5 = true;
+        return;
+      }
+      // 快跑者
+      if (this.type === 21) {
+        this.centerDialogVisible6 = true;
+        return;
+      }
       this.$confirm("即将进行绑定操作, 是否继续?", "提示", {
         confirmButtonText: "确定",
         cancelButtonText: "取消",
@@ -313,7 +487,7 @@ export default {
     changeTab(i) {
       this.curIndex = i;
       if ([1, 2, 5, 9, 13].includes(this.type)) {
-        this.sfId = ''
+        this.sfId = "";
         this.getBindDeliveryShopList();
       } else {
         let shop = this.deliveryList[i];
@@ -421,6 +595,13 @@ export default {
       });
     },
     bindUU() {
+      this.UUData.cityName = this.areaData
+        .find((v) => {
+          return v.value === this.cityName[0];
+        })
+        .children.find((v) => {
+          return v.value === this.cityName[1];
+        }).label;
       if (!this.UUData.cityName.trim()) {
         return this.$message({
           message: "城市不能为空",
@@ -591,9 +772,6 @@ export default {
 }
 .store-list::-webkit-scrollbar-track {
   background-color: #eee;
-  /*border-radius: 5px;
-    -webkit-border-radius: 5px;
-    -moz-border-radius: 5px;*/
 }
 .store-list::-webkit-scrollbar-thumb {
   background-color: #999;
@@ -610,21 +788,24 @@ export default {
     flex-direction: column;
     background: #fefefe;
     height: 100%;
-    padding: 0 10px;
 
     .active {
       background: #ffffff;
       color: #fc7200;
       font-weight: bold;
       box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.12);
-      border-radius: 40px 2px 4px 40px;
     }
     .list {
       display: flex;
       align-items: center;
-      margin: 10px;
       cursor: pointer;
-      padding: 0 10px 0 10px;
+      padding: 10px 20px;
+      &:hover {
+        background: #ffffff;
+        color: #fc7200;
+        font-weight: bold;
+        box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.12);
+      }
       img {
         width: 30px;
         height: 30px;
@@ -649,10 +830,14 @@ export default {
       width: 305px;
       height: 170px;
       background: #ffffff;
-      box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.1);
       border-radius: 8px;
       margin: 0 20px 20px 0;
+      cursor: pointer;
       overflow: hidden;
+      &:hover {
+        background: rgba(255, 255, 255, 0.39);
+        box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.1);
+      }
       .status {
         position: absolute;
         top: 60px;
@@ -839,5 +1024,6 @@ export default {
 .tips {
   color: red;
   margin-bottom: 15px;
+  text-align: center;
 }
 </style>

+ 0 - 404
src/components/shopCompoents/bindPrinter.vue

@@ -1,404 +0,0 @@
-<template>
-  <div class="bind-printer" v-loading="loading" element-loading-text="数据加载中">
-    <div class="store-list">
-      <div class="store-list-item" @click="curIdx = index" :class=" index == curIdx ? 'active' : '' " v-for="(item, index) in shopList" :key="index">{{ item.name }}</div>
-    </div>
-    <div class="header" v-if="shopList.length">
-      <div class="left">
-        <div class="line">
-          <div class="b_line"></div>
-          <div class="triangle"></div>
-        </div>
-        <div class="label">云打印机管理</div>
-      </div>
-      <div class="right">
-        <el-button class="btn" @click.stop="addPrinter(1)">添加打印机</el-button>
-      </div>
-    </div>
-    <template v-if="printerList.length">
-      <div class="take-out-list" v-for="(v,i) in printerList" :key="i">
-        <div class="item">
-          <div class="item-top">
-            <div class="name">{{v.name}}</div>
-          </div>
-          <div class="item-bottom">
-            <div class="left">
-              <div class="l-l">
-                <img :src="v.img" class="l-l-img" />
-              </div>
-              <div class="take-out-name">
-                <div class="take-out-name-bot">
-                  <span :class="['status'+v.onlineStatus,'status']"> 打印机{{v.onlineStatus === 1 ? '在线' : v.onlineStatus === 2 ? '异常' : '离线'}}</span>
-                </div>
-                <div>打印机名称:{{v.deviceName}}</div>
-                <div>打印机编号:{{v.deviceSn}}</div>
-                <div class="take-out-name-bot">打印机KEY:{{v.deviceSecret}}</div>
-                <div class="print-num">
-                  <div>客户联:X{{v.printCustomerCount}}</div>
-                  <div>商家联:X{{v.printMerchantCount}}</div>
-                  <div>厨房联:X{{v.printKitchenCount}}</div>
-                </div>
-              </div>
-            </div>
-            <div class="right">
-              <el-button @click="addPrinter(2,v)" size="small">编&nbsp;辑</el-button>
-              <el-button type="danger" @click="deletePrinter(v)" size="small">删&nbsp;除</el-button>
-            </div>
-          </div>
-        </div>
-      </div>
-    </template>
-    <el-empty v-if="!shopList.length && !loading" description="暂无绑定打印机!"></el-empty>
-    <!-- <div class="empty-img" v-else>
-      <img src="../../../static/image/printer.png" />
-    </div> -->
-    <printer-add @shopDeviceList="shopDeviceList(curIdx)" ref="printerAdd" :devices="deviceList"></printer-add>
-  </div>
-</template>
-
-<script>
-import printerAdd from "./printerAdd";
-import {
-  getShopList,
-  shopDeviceList,
-  deviceDetail,
-  deviceList,
-  deviceAdd,
-  deviceDelete,
-  deviceStatus,
-} from "../../api/shop";
-export default {
-  components: {
-    printerAdd,
-  },
-  data() {
-    return {
-      shopList: [],
-      curIdx: -1,
-      loading: false,
-      printerList: [],
-      showVisible: false,
-      title: "添加打印机",
-      deviceList: [],
-      memberType: this.$store.state.userInfo.memberType,
-    };
-  },
-  watch: {
-    curIdx(newVal, oldVal) {
-      this.shopDeviceList(newVal);
-    },
-    "$store.state.userInfo": {
-      handler(newVal, oldVal) {
-        this.memberType = newVal.memberType;
-      },
-      deep: true,
-    },
-  },
-  created() {
-    if (this.memberType !== 1) {
-      this.getShopList();
-      this.getDeviceList();
-    }
-  },
-  methods: {
-    deletePrinter(v) {
-      this.$confirm("此操作将删除打印机, 是否继续?", "提示", {
-        confirmButtonText: "确定",
-        cancelButtonText: "取消",
-        type: "warning",
-      })
-        .then(() => {
-          deviceDelete({ id: v.id }).then((res) => {
-            if (res.code === 200) {
-              this.$message({
-                type: "error",
-                message: "删除成功!",
-              });
-              this.shopDeviceList(this.curIdx);
-            } else {
-              this.$message({
-                type: "error",
-                message: res.msg,
-              });
-            }
-          });
-        })
-        .catch(() => {
-          this.$message({
-            type: "info",
-            message: "已取消删除",
-          });
-        });
-    },
-    getDeviceList() {
-      deviceList({ type: 2 }).then((res) => {
-        if (res.code === 200) {
-          this.deviceList = res.data;
-        } else {
-          this.$message({
-            type: "error",
-            message: res.msg,
-          });
-        }
-      });
-    },
-    getShopList() {
-      this.loading = true;
-      getShopList().then((res) => {
-        if (res.code === 200) {
-          this.shopList = res.data;
-          this.curIdx = 0;
-        } else {
-          this.$message({
-            type: "error",
-            message: res.msg,
-          });
-        }
-        this.loading = false;
-      });
-    },
-    addPrinter(val, e) {
-      if (val === 1) {
-        let shopId = this.shopList[this.curIdx].id;
-        this.$refs.printerAdd.init("", shopId);
-      } else {
-        this.$refs.printerAdd.init(JSON.parse(JSON.stringify(e)));
-      }
-    },
-    shopDeviceList(index) {
-      shopDeviceList({ deviceType: 2, shopId: this.shopList[index].id }).then(
-        (res) => {
-          if (res.code === 200) {
-            this.printerList = res.data;
-          } else {
-            this.$message({
-              type: "error",
-              message: res.msg,
-            });
-          }
-        }
-      );
-    },
-  },
-};
-</script>
-
-<style lang="scss" scoped>
-.bind-printer {
-  min-height: 200px;
-  .store-list {
-    display: flex;
-    flex-wrap: nowrap;
-    width: 100%;
-    white-space: nowrap;
-    overflow-x: auto;
-    padding-bottom: 10px;
-    &-item {
-      padding: 8px 27px;
-      background-color: #fff;
-      font-size: 14px;
-      font-family: PingFang SC;
-      font-weight: 400;
-      color: #b1b1b1;
-      box-sizing: border-box;
-      border: 1px solid #eee;
-      border-radius: 17px;
-      cursor: pointer;
-      margin-right: 10px;
-      &.active {
-        color: #fc7200;
-      }
-    }
-  }
-  .store-list::-webkit-scrollbar {
-    height: 6px;
-  }
-  .store-list::-webkit-scrollbar-track {
-    background-color: #eee;
-    /*border-radius: 5px;
-    -webkit-border-radius: 5px;
-    -moz-border-radius: 5px;*/
-  }
-  .store-list::-webkit-scrollbar-thumb {
-    background-color: #999;
-    border-radius: 6px;
-    -webkit-border-radius: 6px;
-    -moz-border-radius: 6px;
-  }
-  .take-out-list {
-    margin-bottom: 10px;
-    .item {
-      background-color: #fff;
-      .item-top {
-        display: flex;
-        justify-content: space-between;
-        box-sizing: border-box;
-        padding: 20px 18px;
-        align-items: center;
-        border-bottom: 1px solid #eee;
-        .name {
-          font-size: 16px;
-          font-family: PingFang SC;
-          font-weight: bold;
-          color: #333333;
-        }
-        .top-right {
-          display: flex;
-          align-items: center;
-          span {
-            font-size: 14px;
-            font-family: PingFang SC;
-            font-weight: 400;
-            color: #b1b1b1;
-            margin-right: 12px;
-          }
-        }
-      }
-      .item-bottom {
-        display: flex;
-        justify-content: space-between;
-        box-sizing: border-box;
-        padding: 10px 18px;
-        align-items: center;
-        .left {
-          display: flex;
-          align-items: center;
-          .l-l {
-            width: 155px;
-            height: 80px;
-            font-size: 0;
-            .l-l-img {
-              width: 100%;
-              height: 100%;
-            }
-          }
-          .take-out-name {
-            font-size: 13px;
-            font-family: PingFang SC;
-            font-weight: 400;
-            color: #333333;
-            line-height: 26px;
-            margin-left: 30px;
-            .take-out-name-bot {
-              // margin-bottom: 10px;
-              .status {
-                display: flex;
-                align-items: center;
-                &:before {
-                  content: "";
-                  display: block;
-                  width: 8px;
-                  height: 8px;
-                  border-radius: 50%;
-                  margin-right: 5px;
-                }
-              }
-              .status0 {
-                color: #b1b1b1;
-                &:before {
-                  background: #b1b1b1;
-                }
-              }
-              .status2 {
-                color: #f74141;
-                &:before {
-                  background: #f74141;
-                }
-              }
-              .status1 {
-                color: #18b71c;
-                &:before {
-                  background: #18b71c;
-                }
-              }
-            }
-            .print-num {
-              display: flex;
-              div {
-                margin-right: 20px;
-              }
-            }
-          }
-        }
-        .right {
-          .right-btn {
-            background-color: #fc7200;
-            border: none;
-          }
-        }
-      }
-    }
-  }
-  .category_box {
-    display: flex;
-    flex-wrap: wrap;
-    width: 100%;
-    margin-top: -10px;
-
-    .item {
-      display: flex;
-      align-items: center;
-      justify-content: center;
-      width: 92px;
-      height: 38px;
-      margin: 10px 10px 0 0;
-      background: #f4f4f4;
-      border-radius: 2px;
-      cursor: pointer;
-
-      &.active {
-        color: #ffffff;
-        background: #fc7200;
-      }
-    }
-  }
-  .header {
-    display: flex;
-    align-items: center;
-    justify-content: space-between;
-    margin: 10px;
-    .left {
-      display: flex;
-      align-items: center;
-
-      .line {
-        position: relative;
-        width: 4px;
-        height: 15px;
-        background: #fc7200;
-        border-radius: 4px;
-        overflow: hidden;
-        margin-right: 10px;
-
-        .b_line {
-          width: 100px;
-          height: 6px;
-          background: #462bf7;
-        }
-
-        .triangle {
-          width: 0;
-          height: 0;
-          border-top: 100px solid #462bf7;
-          border-left: 100px solid transparent;
-        }
-      }
-
-      .label {
-        font-size: 16px;
-        font-weight: 500;
-        color: #0d1e40;
-      }
-    }
-  }
-  .btn {
-    background: #fc7200;
-    border-color: #fc7200;
-    color: #fff;
-    &.black {
-      background: #0d1e40;
-      border-color: #0d1e40;
-    }
-  }
-}
-</style>

+ 21 - 6
src/components/shopCompoents/bindTakeOut.vue

@@ -28,7 +28,11 @@
             <div class="but-con unbind">解绑</div>
           </div>
         </div>
-        <div class="shop-bind" @click="goBind">
+        <div class="shop-bind" v-if="waimaiList.length&&[6,7,8].includes(waimaiList[curIndex].type)">
+          <img src="../../../static/image/icon-customer.png" alt="" srcset="">
+          <div class="name">联系客服绑定</div>
+        </div>
+        <div class="shop-bind" @click="goBind" v-else>
           <img src="../../../static/image/icon-add.png" alt="" srcset="">
           <div class="name">绑定{{waimaiList[curIndex] && waimaiList[curIndex].name}}</div>
         </div>
@@ -105,6 +109,7 @@ import {
   bindChangeShop,
 } from "../../api/shop";
 export default {
+  name: "bindTakeOut",
   data() {
     return {
       curIndex: 0,
@@ -384,21 +389,24 @@ export default {
       flex-direction: column;
       background: #fefefe;
       height: 100%;
-      padding: 0 10px;
 
       .active {
         background: #ffffff;
         color: #fc7200;
         font-weight: bold;
         box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.12);
-        border-radius: 40px 2px 4px 40px;
       }
       .list {
         display: flex;
         align-items: center;
-        margin: 10px;
         cursor: pointer;
-        padding: 0 10px 0 10px;
+        padding: 10px 20px;
+        &:hover {
+          background: #ffffff;
+          color: #fc7200;
+          font-weight: bold;
+          box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.12);
+        }
         img {
           width: 30px;
           height: 30px;
@@ -443,10 +451,14 @@ export default {
         width: 305px;
         height: 170px;
         background: #ffffff;
-        box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.1);
         border-radius: 8px;
         margin: 0 20px 20px 0;
         overflow: hidden;
+        cursor: pointer;
+        &:hover {
+          box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.1);
+          background: rgba(255, 255, 255, 0.39);
+        }
         .status {
           position: absolute;
           top: 60px;
@@ -473,6 +485,9 @@ export default {
             font-weight: 500;
             line-height: 25px;
             color: #333333;
+            white-space: nowrap;
+            text-overflow: ellipsis;
+            overflow: hidden;
           }
           img {
             width: 30px;

+ 3 - 3
src/components/shopCompoents/bindUsbPrint.vue

@@ -19,7 +19,7 @@
       <el-empty style="width:100%;" v-if="!printerList.length" description="无法获取系统打印机列表,请先安装下载中心USB打印相关插件!"></el-empty>
     </div>
     <!-- 打印机新增、编辑 -->
-    <el-dialog width="40%" :title="title" destroy-on-close center :visible.sync="showVisible">
+    <el-dialog width="600px" :title="title" destroy-on-close center :visible.sync="showVisible">
       <el-form :model="form" ref="form" label-width="130px">
         <el-form-item label="打印机系统名称" prop="deviceName">
           <span>{{form.deviceName}}</span>
@@ -28,10 +28,10 @@
           <el-input v-model="form.name" placeholder="给这台打印机取个名字吧" autocomplete="off" style="width: 100%">
           </el-input>
         </el-form-item>
-        <el-form-item label="自动打印接单" prop="deviceSecret">
+        <el-form-item label="接单自动打印" prop="deviceSecret">
           <el-switch v-model="form.openOrderPrint" :active-value="1" :inactive-value="0" active-color="#FC7200" inactive-color="#999" />
         </el-form-item>
-        <el-form-item label="自动打印取消单" prop="deviceSecret">
+        <el-form-item label="取消单自动打印" prop="deviceSecret">
           <el-switch v-model="form.openOrderCancelPrint" :active-value="1" :inactive-value="0" active-color="#FC7200" inactive-color="#999" />
         </el-form-item>
         <el-form-item label="打印份数">

+ 132 - 103
src/components/shopCompoents/shopList.vue

@@ -1,38 +1,33 @@
 <template>
   <div class="shopList" v-loading="loading" element-loading-text="数据加载中">
-    <div class="header" v-if="shopList.length">
-      <div class="left">
-        <div class="line">
-          <div class="b_line"></div>
-          <div class="triangle"></div>
+    <div class="shop-list">
+      <div class="item" v-for="(v,i) in shopList" :key="i" @click.stop="addShop(2, v)">
+        <div class="shop-top">
+          <div class="code">门店编号:{{v.code}}</div>
+          <div class="edit" @click.stop="addShop(2, v)">编辑</div>
+        </div>
+        <div class="cell">
+          <img class="img" src="../../../static/image/shop-name.png" alt="">
+          <div class="con">{{v.name}}</div>
+        </div>
+        <div class="cell">
+          <img class="img" src="../../../static/image/shop-address.png" alt="">
+          <div class="con1">{{v.poiAddress}}{{v.address}}</div>
+        </div>
+        <div class="cell">
+          <img class="img" src="../../../static/image/shop-contact.png" alt="">
+          <div class="con1">{{v.contactName}} {{v.mobile}}</div>
+        </div>
+        <div class="delivery">
+          <div class="name">配送运力:</div>
+          <img class="img" :src="d.logo" v-for="(d,idx) in v.deliveries" :key="idx" alt="">
         </div>
-        <div class="label">门店管理</div>
       </div>
-      <div class="right">
-        <el-button class="btn" v-if="$store.state.userInfo.memberType === 2" @click.stop="addShop(1)">新增门店</el-button>
+      <div class="item1" @click.stop="addShop(1)">
+        <img class="img" src="../../../static/image/icon-add.png" alt="">
+        <div class="shop-name">添加门店</div>
       </div>
     </div>
-    <el-table v-if="shopList.length" :data="shopList" stripe header-row-class-name="table_h" style="width: 100%; margin-top: 10px">
-      <el-table-column prop="code" label="门店编号" width="170"></el-table-column>
-      <el-table-column prop="name" label="门店名称" width="172" align="center"></el-table-column>
-      <el-table-column prop="address" label="门店地址" width="321" align="center"></el-table-column>
-      <el-table-column prop="contactName" label="联系人" width="164" align="center"></el-table-column>
-      <el-table-column prop="mobile" label="联系电话" width="176" align="center"></el-table-column>
-      <el-table-column label="已获运力" align="center" width="450">
-        <template slot-scope="scope">
-          <div class="imgs">
-            <img class="img" :src="item.logo" v-for="(item, i) in scope.row.deliveries" :key="i" alt="">
-          </div>
-        </template>
-      </el-table-column>
-      <el-table-column fixed="right" label="操作" width="100" align="center">
-        <template slot-scope="scope">
-          <el-button class="btn" size="mini" @click.stop="addShop(2, scope.row)">修改</el-button>
-          <!-- <el-button type="danger" size="mini" @click.stop="deleteItem(scope.row)">删除</el-button> -->
-        </template>
-      </el-table-column>
-    </el-table>
-    <el-empty v-if="!shopList.length && !loading" description="暂无门店数据!"></el-empty>
     <shop-add @getData="getData" ref="shopAdd" :products="productList"></shop-add>
   </div>
 </template>
@@ -41,6 +36,7 @@
 import shopAdd from "./shopAdd";
 import { getShopList, getProductList, shopDelete } from "../../api/shop";
 export default {
+  name: "shopList",
   components: {
     shopAdd,
   },
@@ -52,7 +48,7 @@ export default {
       memberType: this.$store.state.userInfo.memberType,
     };
   },
-  watch:{
+  watch: {
     "$store.state.userInfo": {
       handler(newVal, oldVal) {
         this.memberType = newVal.memberType;
@@ -81,7 +77,16 @@ export default {
       this.loading = true;
       getShopList().then((res) => {
         if (res.code === 200) {
-          this.shopList = res.data;
+          this.shopList = res.data.map((v) => {
+            if (
+              v.poiAddress === "null" ||
+              v.poiAddress === "undefined" ||
+              !v.poiAddress
+            ) {
+              v.poiAddress = "";
+            }
+            return v;
+          });
         } else {
           this.$message({
             type: "error",
@@ -135,87 +140,111 @@ export default {
 
 <style lang="scss">
 .shopList {
-  width: 100%;
-  background: #ffffff;
-  min-height: calc(100vh - 184px);
-  padding: 20px;
-  box-sizing: border-box;
-
-  .header {
+  .shop-list {
     display: flex;
-    align-items: center;
-    justify-content: space-between;
-
-    .left {
+    flex-wrap: wrap;
+    .item {
+      position: relative;
       display: flex;
-      align-items: center;
-
-      .line {
-        position: relative;
-        width: 4px;
-        height: 15px;
-        background: #fc7200;
-        border-radius: 4px;
-        overflow: hidden;
-        margin-right: 10px;
-
-        .b_line {
-          width: 100px;
-          height: 6px;
-          background: #462bf7;
+      flex-direction: column;
+      width: 290px;
+      height: 150px;
+      background: #ffffff;
+      margin: 10px 20px 0 0;
+      padding: 16px;
+      border-radius: 8px;
+      overflow: hidden;
+      cursor: pointer;
+      &:hover {
+        background: rgba(255, 255, 255, 0.39);
+        box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
+      }
+      .shop-top {
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        padding-bottom: 8px;
+        border-bottom: 1px solid #ebebeb;
+        .code {
+          font-size: 14px;
+          font-weight: 400;
+          line-height: 20px;
+          color: #999999;
         }
-
-        .triangle {
-          width: 0;
-          height: 0;
-          border-top: 100px solid #462bf7;
-          border-left: 100px solid transparent;
+        .edit {
+          font-size: 14px;
+          font-weight: 500;
+          line-height: 20px;
+          color: #fc7200;
         }
       }
-
-      .label {
+      .cell {
+        display: flex;
+        align-items: center;
+        margin-top: 8px;
+        .img {
+          width: 12px;
+          height: 12px;
+          margin-right: 5px;
+        }
+        .con {
+          font-size: 16px;
+          font-weight: bold;
+          line-height: 20px;
+          color: #333333;
+          text-overflow: ellipsis;
+          white-space: nowrap;
+          overflow: hidden;
+        }
+        .con1 {
+          font-size: 14px;
+          font-weight: 400;
+          line-height: 20px;
+          color: #333333;
+          text-overflow: ellipsis;
+          white-space: nowrap;
+          overflow: hidden;
+        }
+      }
+      .delivery {
+        display: flex;
+        align-items: center;
+        border-top: 1px solid #ebebeb;
+        margin-top: 8px;
+        padding-top: 8px;
+        .name {
+          flex-shrink: 0;
+          font-size: 14px;
+          font-weight: 400;
+          line-height: 20px;
+          color: #333333;
+        }
+        .img {
+          width: 16px;
+          height: 16px;
+          margin-left: 10px;
+        }
+      }
+    }
+    .item1 {
+      display: flex;
+      flex-direction: column;
+      justify-content: center;
+      align-items: center;
+      background: #ffffff;
+      width: 322px;
+      height: 182px;
+      box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
+      border-radius: 8px;
+      margin: 10px 20px 0 0;
+      cursor: pointer;
+      .shop-name {
         font-size: 16px;
         font-weight: 500;
-        color: #0d1e40;
+        line-height: 22px;
+        color: #333333;
       }
     }
   }
-
-  .btn {
-    background: #fc7200;
-    border-color: #fc7200;
-    color: #fff;
-
-    &.black {
-      background: #0d1e40;
-      border-color: #0d1e40;
-    }
-  }
-
-  .el-table th.el-table__cell {
-    height: 38px;
-    background: #fafafa;
-    padding: 0;
-    font-size: 12px;
-    color: #666666;
-  }
-
-  .el-table .el-table__cell {
-    font-size: 14px;
-    color: #222222;
-  }
-
-  .imgs {
-    display: flex;
-    align-items: center;
-    padding-left: 36px;
-
-    .img {
-      width: 20px;
-      height: 20px;
-      border-radius: 50%;
-      margin-right: 10px;
-    }
-  }
 }
 </style>

+ 0 - 221
src/components/shopInfo.vue

@@ -1,221 +0,0 @@
-<template>
-  <div class="shopInfo">
-    <el-row class="order_tab">
-      <el-col :span="24">
-        <div class="tabList">
-          <div class="tab_item" @click="changeTabs(i)" :class="{'tab_item_ac':tabNum==i?true:false}" v-for="(item,i) in tabList" :key="i">
-            <span class="item" v-if="!item.children">{{item.name}}</span>
-            <el-dropdown v-else @command="choosePrint">
-              <span class="el-dropdown-link item">
-                {{item.name}}<i class="el-icon-arrow-down el-icon--right"></i>
-              </span>
-              <el-dropdown-menu slot="dropdown">
-                <el-dropdown-item :command="v.command" v-for="(v,index) in item.children" :key="index">{{v.name}}</el-dropdown-item>
-              </el-dropdown-menu>
-            </el-dropdown>
-            <div class="tab_line"></div>
-          </div>
-        </div>
-      </el-col>
-    </el-row>
-
-    <el-row class="content">
-      <el-col style="height: 100%;" :span="24">
-        <component v-if="renderComponent" :is="activeName"></component>
-      </el-col>
-    </el-row>
-    <merchant-add ref="merchantAdd" :products="productList"></merchant-add>
-  </div>
-</template>
-
-<script>
-import merchantAdd from "./merchantAdd.vue";
-import shopList from "./shopCompoents/shopList";
-import storeList from "./shopCompoents/bindTakeOut.vue";
-import deliveryList from "./shopCompoents/bindDelivery.vue";
-import printerList from "./shopCompoents/bindPrinter.vue";
-import usbPrinter from "./shopCompoents/bindUsbPrint.vue";
-import bus from "../common/bus.js";
-import { getProductList } from "../api/shop.js";
-export default {
-  name: "HelloWorld",
-  components: {
-    merchantAdd,
-    shopList,
-    storeList,
-    deliveryList,
-    printerList,
-    usbPrinter,
-  },
-
-  data() {
-    return {
-      activeName: "shopList",
-      tabList: [
-        { name: "门店列表", activeName: "shopList" },
-        { name: "绑定外卖平台", activeName: "storeList" },
-        { name: "绑定配送平台", activeName: "deliveryList" },
-        {
-          name: "绑定打印机",
-          activeName: "printerList",
-          children: [
-            { name: "云打印机", command: "printerList" },
-            { name: "USB打印机", command: "usbPrinter" },
-          ],
-        },
-      ],
-      tabNum: 0,
-      renderComponent: true,
-      productList: [],
-      memberType: this.$store.state.userInfo.memberType,
-    };
-  },
-  watch: {
-    "$store.state.userInfo": {
-      handler(newVal, oldVal) {
-        this.memberType = newVal.memberType;
-      },
-      deep: true,
-    },
-  },
-  created() {
-    this.getProductList();
-    bus.$on("goPrinter", () => {
-      this.changeTabs(3);
-    });
-    let i = this.$route.params.tabNum;
-    if (i) {
-      this.changeTabs(Number(i));
-    }
-  },
-  beforeRouteEnter(to, from, next) {
-    next((vm) => {
-      if (from.name) {
-        vm.$nextTick(() => {
-          vm.changeTabs(0);
-        });
-      }
-    });
-  },
-  mounted() {},
-  methods: {
-    choosePrint(e) {
-      console.log("object", e);
-      if (this.memberType === 1) {
-        this.$confirm("您当前还不是商户,请先申请成为商户!", "提示", {
-          confirmButtonText: "成为商户",
-          cancelButtonText: "取消",
-          type: "warning",
-          center: true,
-        })
-          .then(() => {
-            this.$refs.merchantAdd.init(0);
-          })
-          .catch(() => {});
-      }
-      if (this.tabNum === 3) {
-        this.activeName = e;
-        this.forceRerender();
-        return;
-      }
-      this.tabNum = 3;
-      this.activeName = e;
-    },
-    forceRerender() {
-      // 从 DOM 中删除 my-component 组件
-      this.renderComponent = false;
-      this.$nextTick(() => {
-        // 在 DOM 中添加 my-component 组件
-        this.renderComponent = true;
-      });
-    },
-    changeTabs(i) {
-      if (this.memberType === 1) {
-        this.$confirm("您当前还不是商户,请先申请成为商户!", "提示", {
-          confirmButtonText: "成为商户",
-          cancelButtonText: "取消",
-          type: "warning",
-          center: true,
-        })
-          .then(() => {
-            this.$refs.merchantAdd.init(0);
-          })
-          .catch(() => {});
-      }
-      if (i === this.tabNum) {
-        this.forceRerender();
-        return;
-      }
-      this.tabNum = i;
-      this.activeName = this.tabList[i].activeName;
-    },
-    getProductList() {
-      getProductList().then((res) => {
-        if (res.code === 200) {
-          this.productList = res.data;
-        } else {
-          this.$message({
-            type: "error",
-            message: res.msg,
-          });
-        }
-      });
-    },
-  },
-};
-</script>
-
-<!-- Add "scoped" attribute to limit CSS to this component only -->
-<style scoped lang="scss">
-.shopInfo {
-  height: 100%;
-  .order_tab {
-    width: 100%;
-    height: 74px;
-    background: #fff;
-
-    .tabList {
-      width: 100%;
-      height: 74px;
-      padding-top: 20px;
-      padding-left: 36px;
-      box-sizing: border-box;
-      display: flex;
-
-      .tab_item {
-        min-width: 58px;
-        margin-right: 56px;
-        .item {
-          font-size: 16px;
-          font-weight: 500;
-          color: #b1b1b1;
-          position: relative;
-          text-align: center;
-          cursor: pointer;
-        }
-        .tab_line {
-          width: 58px;
-          height: 6px;
-          background: #fff;
-          border-radius: 3px;
-          margin: 15px auto 0;
-        }
-      }
-
-      .tab_item_ac {
-        color: #fc7200;
-
-        .tab_line {
-          background: #fc7200;
-        }
-      }
-    }
-  }
-
-  .content {
-    width: 100%;
-    height: calc(100% - 84px);
-    margin-top: 10px;
-  }
-}
-</style>

+ 2 - 0
src/main.js

@@ -10,6 +10,7 @@ import axios from 'axios'
 import AmapVue from '@amap/amap-vue';
 import { get, post, postJson } from './api/http'
 import Tool from './api/tool'
+import './assets/font/font.css'
 
 Vue.prototype.$axios = axios    //全局注册,使用方法为:this.$axios
 Vue.prototype.$tool = Tool;
@@ -17,6 +18,7 @@ Vue.config.productionTip = false
 Vue.prototype.$get = get;
 Vue.prototype.$post = post;
 Vue.prototype.$postJson = postJson;
+Vue.prototype.$bus = new Vue();
 
 AmapVue.config.key = '5ae8644771ef9abf9cfb3ea23b1df6ca';
 Vue.use(AmapVue);

+ 76 - 34
src/router/index.js

@@ -32,60 +32,102 @@ const router = new Router({
           component: () => import('../components/orderSearch.vue')
         },
         {
-          path: '/setUp/set',
-          name: 'set',
-          title: '外卖设置',
-          component: () => import('../components/set.vue')
+          path: '/manualCreate',
+          name: 'manualCreate',
+          title: '手动发单',
+          component: () => import('../components/manualCreate.vue')
         },
         {
-          path: '/setUp/addressManagement',
-          name: 'addressManagement',
-          title: '常用地址',
-          component: () => import('../components/addressManagement.vue')
+          path: '/shop/shopList',
+          name: 'shopList',
+          title: '我的店铺',
+          component: () => import('../components/shopCompoents/shopList.vue')
         },
         {
-          path: '/setUp/pictureManagement',
-          name: 'pictureManagement',
-          title: '图片管理',
-          component: () => import('../components/pictureManagement.vue')
+          path: '/platformAccount/index',
+          name: 'platformAccount',
+          title: '账号管理',
+          component: () => import('../components/platformAccount/index')
         },
         {
-          path: '/shopInfo/shopInfos',
-          name: 'shopInfos',
-          title: '门店管理',
-          component: () => import('../components/shopInfo.vue')
+          path: '/account/wallet',
+          name: 'wallet',
+          title: '我的钱包',
+          component: () => import('../components/accountCompoents/wallet.vue')
         },
         {
-          path: '/shopInfo/shopAccount',
-          name: 'shopAccount',
-          title: '我的账户',
-          component: () => import('../components/shopAccount.vue')
+          path: '/account/walletDetail',
+          name: 'walletDetail',
+          title: '收支明细',
+          component: () => import('../components/accountCompoents/shopAccount.vue')
         },
         {
-          path: '/manualCreate',
-          name: 'manualCreate',
-          title: '手动发单',
-          component: () => import('../components/manualCreate.vue')
+          path: '/account/coupon',
+          name: 'coupon',
+          title: '优惠券',
+          component: () => import('../components/accountCompoents/coupon.vue')
+        },
+
+        {
+          path: '/platform/bindTakeOut',
+          name: 'bindTakeOut',
+          title: '绑定外卖平台',
+          component: () => import('../components/shopCompoents/bindTakeOut.vue')
+        },
+        {
+          path: '/platform/bindDelivery',
+          name: 'bindDelivery',
+          title: '绑定配送平台',
+          component: () => import('../components/shopCompoents/bindDelivery.vue')
+        },
+        {
+          path: '/set/waimai',
+          name: 'waimai',
+          title: '外卖设置',
+          component: () => import('../components/settingComponents/waimai.vue')
         },
         {
-          path: '/help',
-          name: 'help',
-          title: '帮助中心',
-          component: () => import('../components/help.vue')
+          path: '/set/print',
+          name: 'print',
+          title: '打印设置',
+          component: () => import('../components/settingComponents/print.vue')
         },
         {
-          path: '/download',
+          path: '/set/system',
+          name: 'system',
+          title: '系统设置',
+          component: () => import('../components/settingComponents/system.vue')
+        },
+        {
+          path: '/help/commonProblem',
+          name: 'commonProblem',
+          title: '常见问题',
+          component: () => import('../components/help/help.vue')
+        },
+        {
+          path: '/help/customerService',
+          name: 'customerService',
+          title: '客服中心',
+          component: () => import('../components/help/customerService.vue')
+        },
+        {
+          path: '/help/download',
           name: 'download',
           title: '下载中心',
-          component: () => import('../components/downloadCenter.vue')
+          component: () => import('../components/help/downloadCenter.vue')
         },
         {
-          path: '/about',
+          path: '/help/feedback',
+          name: 'feedback',
+          title: '意见反馈',
+          component: () => import('../components/help/feedback.vue')
+        },
+        {
+          path: '/help/about',
           name: 'about',
           title: '关于我们',
-          component: () => import('../components/about.vue')
+          component: () => import('../components/help/about.vue')
         },
-
       ]
     },
     {
@@ -111,7 +153,7 @@ router.beforeEach((to, from, next) => {
     next()
   } else {
     const token = localStorage.getItem('token') || null;
-    console.log('这是一个token:',token);
+    // console.log('这是一个token:',token);
     if (token) {
       next()
     } else if (to.path !== '/resetPassword') {

+ 40 - 22
src/views/home.vue

@@ -2,12 +2,16 @@
   <el-container>
     <sidebar></sidebar>
     <el-container>
-      <el-header style="text-align: right;height: 80px;line-height: 80px;">
+      <el-header>
         <span @click="showMerchant" v-if="$store.state.userInfo.memberType === 1" class="header-button">成为商户</span>
-        <span @click="$router.push({
-          path: '/shopInfo/shopAccount'
-        })" class="header-button">充值中心</span>
-        <span @click="goPrinter" class="header-button">打印设置</span>
+        <div class="account" @click="goAccount">
+          <img src="../../static/image/head-account2.png" alt="">
+          <div class="num">¥{{$store.state.userInfo.amount}}</div>
+        </div>
+        <div class="print" @click="goPrinter">
+          <img src="../../static/image/head-print2.png" alt="">
+          <div class="num con">打印设置</div>
+        </div>
         <el-dropdown trigger="click">
           <span class="el-dropdown-link">
             <span style="cursor: pointer;">{{ userInfo.nickname }}</span>
@@ -65,6 +69,11 @@ export default {
   },
 
   methods: {
+    goAccount() {
+      this.$router.push({
+        name: "wallet",
+      });
+    },
     showMerchant() {
       this.$refs.merchantAdd.init(0);
     },
@@ -82,14 +91,8 @@ export default {
     },
     goPrinter() {
       this.$router.push({
-        path: "/shopInfo/shopInfos",
-        params: {
-          tabNum: 3,
-        },
+        name: "print",
       });
-      if (this.$route.name === "shopInfos") {
-        bus.$emit("goPrinter");
-      }
     },
     loginOut() {
       this.$confirm("此操作将退出当前登录用户, 是否继续?", "提示", {
@@ -110,10 +113,13 @@ export default {
 </script>
 
 <style lang="scss" scoped="scoped">
-.el-header {
+/deep/.el-header {
+  display: flex;
+  align-items: center;
+  justify-content: flex-end;
   position: relative;
   width: 100%;
-  height: 80px;
+  height: 80px !important;
 }
 
 .el-main {
@@ -122,7 +128,6 @@ export default {
   right: 0;
   top: 80px;
   bottom: 0;
-  // overflow-y: hidden;
   background-color: #f1f2f5;
   padding: 10px;
   min-width: 550px;
@@ -137,15 +142,28 @@ export default {
   margin-right: 40px;
 }
 
-.header-button {
-  font-size: 16px;
-  font-family: PingFang SC;
-  font-weight: 400;
-  color: #777777;
+.account,
+.print {
+  display: flex;
+  align-items: center;
+  margin-right: 20px;
   cursor: pointer;
-  margin-right: 40px;
+  img {
+    width: 20px;
+    height: 20px;
+    margin-right: 5px;
+  }
+  .num {
+    line-height: 25px;
+    font-size: 16px;
+    font-weight: 500;
+    color: #fc7200;
+  }
+  .con {
+    font-size: 15px;
+    color: #333333;
+  }
 }
-
 .home-content {
   display: flex;
 

+ 8 - 5
src/views/login.vue

@@ -52,7 +52,7 @@
 </template>
 
 <script>
-import { mapState, mapMutations, mapGetters } from "vuex";
+import { mapState, mapMutations, mapGetters, mapActions } from "vuex";
 import { getPhoneCode, loginPassword, loginVerification } from "../api/user.js";
 export default {
   data() {
@@ -74,14 +74,15 @@ export default {
     this.timer = null;
   },
   computed: {
-    ...mapState(["userInfo"]),
-    ...mapGetters(["userInfo"]),
+    // ...mapState(["userInfo"]),
+    // ...mapGetters(["userInfo"]),
   },
   created() {
     console.log("vuex", this.userInfo);
   },
   methods: {
     ...mapMutations(["SET_USERINFO"]),
+    ...mapActions(["getUserInfo"]),
     seachEnterFun(e) {
       var keyCode = window.event ? e.keyCode : e.which;
       if (keyCode == 13) {
@@ -99,6 +100,7 @@ export default {
         if (res.code == 200) {
           localStorage.setItem("token", res.data.token);
           this.SET_USERINFO(res.data.member);
+          this.getUserInfo();
           this.$router.push("/");
         } else {
           return this.$message({
@@ -120,6 +122,7 @@ export default {
           this.errCount = 0;
           localStorage.setItem("token", res.data.token);
           this.SET_USERINFO(res.data.member);
+          this.getUserInfo();
           this.$store.dispatch("getUsbPrint");
           this.$router.push("/");
         } else {
@@ -161,8 +164,8 @@ export default {
       }
       if (!this.checked) {
         return this.$message({
-          message: "请先勾选同意后再充值!",
-          type: "info",
+          message: "请先勾选同意后再登录!",
+          type: "error",
         });
       }
       if (this.activeIndex == 1) {

TEMPAT SAMPAH
static/audio/test.mp3


TEMPAT SAMPAH
static/image/account-icon.png


TEMPAT SAMPAH
static/image/delete-icon.png


TEMPAT SAMPAH
static/image/edit-icon.png


TEMPAT SAMPAH
static/image/empty-img.png


TEMPAT SAMPAH
static/image/head-account2.png


TEMPAT SAMPAH
static/image/head-print2.png


TEMPAT SAMPAH
static/image/help-icon.png


TEMPAT SAMPAH
static/image/icon-add.png


TEMPAT SAMPAH
static/image/icon-big.png


TEMPAT SAMPAH
static/image/icon-center.png


TEMPAT SAMPAH
static/image/icon-customer.png


TEMPAT SAMPAH
static/image/icon-left.png


TEMPAT SAMPAH
static/image/icon-print.png


TEMPAT SAMPAH
static/image/icon-reset.png


TEMPAT SAMPAH
static/image/icon-right.png


TEMPAT SAMPAH
static/image/icon-small.png


TEMPAT SAMPAH
static/image/icon_choose.png


TEMPAT SAMPAH
static/image/invalid-coupon.png


TEMPAT SAMPAH
static/image/order-icon.png


TEMPAT SAMPAH
static/image/platform-icon.png


TEMPAT SAMPAH
static/image/print-icon.png


TEMPAT SAMPAH
static/image/printer-online-0.png


TEMPAT SAMPAH
static/image/printer-online-1.png


TEMPAT SAMPAH
static/image/printer-online-2.png


TEMPAT SAMPAH
static/image/recharge.png


TEMPAT SAMPAH
static/image/recharge_coupon.png


TEMPAT SAMPAH
static/image/setting-icon.png


TEMPAT SAMPAH
static/image/shop-address.png


TEMPAT SAMPAH
static/image/shop-contact.png


TEMPAT SAMPAH
static/image/shop-icon.png


TEMPAT SAMPAH
static/image/shop-name.png


TEMPAT SAMPAH
static/image/show-map-icon.png


TEMPAT SAMPAH
static/image/wallet1.png


TEMPAT SAMPAH
static/image/wallet2.png


TEMPAT SAMPAH
static/image/组 2396.png