瀏覽代碼

feat:“同步2025.05.14“

soobin 3 月之前
父節點
當前提交
1631833525

二進制
src/assets/device/operIcon/jam.png


二進制
src/assets/device/operIcon/tax.png


+ 19 - 2
src/assets/language/en.json

@@ -768,7 +768,7 @@
     "dataOverview": "Dashboard",
     "orderData": "Orders",
     "totalIncome": "Revenue",
-    "productNum": "Sales",
+    "productNum": "Volume",
     "numberOfOrders": "Orders",
     "salesAmount": "Sales",
     "commonTools": "Tools",
@@ -1002,6 +1002,7 @@
     "equipmentName": "Machine Name",
     "tradeName": "Product",
     "dividingDomesticService": "Commission",
+    "tax": "Taxes & Fees",
     "business": "Merchant",
     "orderNo": "Order No",
     "commodity": "Item",
@@ -1732,6 +1733,20 @@
     "M21": "MQTT",
     "M22": "Terminals"
   },
+  "tax": {
+    "taxFee": "Tax Levy",
+    "taxFeeDesc": "Taxes will be automatically collected per transaction when enabled",
+    "taxRate": "Tax Rate",
+    "ratePlaceholder": "Enter tax rate percentage (0.00-100.00)",
+    "rateRequired": "Tax rate is required",
+    "rateInvalid": "Enter valid value with up to 2 decimal places",
+    "update": "Apply Now"
+  },
+  "jam": {
+    "forward": "Forward Extraction",
+    "reverse": "Reverse Extraction",
+    "stop": "Emergency Stop"
+  },
   "remote": {
     "C1": "Restart Machine",
     "C2": "Sleep Toggle",
@@ -1760,6 +1775,8 @@
     "C25": "Mixing Mode (Ice Cream)",
     "C26": "Freshness Mode (Ice Cream)",
     "C27": "Defrost Mode (Ice Cream)",
-    "C28": "Edit Payment Method"
+    "C28": "Edit Payment Method",
+    "C29": "Tax Administration",
+    "C30": "Jam Extraction"
   }
 }

+ 18 - 1
src/assets/language/es.json

@@ -1002,6 +1002,7 @@
         "equipmentName": "Equipo",
         "tradeName": "Producto",
         "dividingDomesticService": "Comisión",
+        "tax": "Impuestos",
         "business": "Comercio",
         "orderNo": "N° pedido",
         "commodity": "Artículo",
@@ -1731,6 +1732,20 @@
         "M21": "MQTT",
         "M22": "Terminales"
     },
+    "tax": {
+        "taxFee": "Recaudación Tributaria",
+        "taxFeeDesc": "Recaudación automática por transacción",
+        "taxRate": "Tipo Impositivo",
+        "ratePlaceholder": "Introduzca porcentaje (0,00-100,00)",
+        "rateRequired": "Campo obligatorio",
+        "rateInvalid": "Valor entre 0-100 con 2 decimales",
+        "update": "Actualizar ahora"
+    },
+    "jam": {
+        "forward": "Extracción Directa",
+        "reverse": "Extracción Inversa",
+        "stop": "Paro de Emergencia"
+    },
     "remote": {
         "C1": "Reiniciar máquina",
         "C2": "Alternar suspensión",
@@ -1759,6 +1774,8 @@
         "C25": "Mezcla (Helado)",
         "C26": "Conservación (Helado)",
         "C27": "Descongelación (Helado)",
-        "C28": "Cambiar pago"
+        "C28": "Cambiar pago",
+        "C29": "Gestión Tributaria",
+        "C30": "Extracción de Mermelada"
     }
 }

+ 18 - 1
src/assets/language/fr.json

@@ -1002,6 +1002,7 @@
         "equipmentName": "Appareil",
         "tradeName": "Produit",
         "dividingDomesticService": "Commission",
+        "tax": "Taxes",
         "business": "Marchand",
         "orderNo": "N° commande",
         "commodity": "Article",
@@ -1762,6 +1763,20 @@
         "M21": "MQTT",
         "M22": "Terminaux"
     },
+    "tax": {
+        "taxFee": "Prélèvement Fiscal",
+        "taxFeeDesc": "Collecte automatique des taxes par transaction",
+        "taxRate": "Taux d'Imposition",
+        "ratePlaceholder": "Saisir le taux en % (00,00 à 100,00)",
+        "rateRequired": "Le taux est obligatoire",
+        "rateInvalid": "Valeur entre 0 et 100 (2 décimales max)",
+        "update": "Mettre à jour"
+    },
+    "jam": {
+        "forward": "Extraction Avant",
+        "reverse": "Extraction Arrière",
+        "stop": "Arrêt d'Urgence"
+    },
     "remote": {
         "C1": "Redémarrer machine",
         "C2": "Mode veille",
@@ -1790,6 +1805,8 @@
         "C25": "Mélange (Glace)",
         "C26": "Conservation (Glace)",
         "C27": "Décongélation (Glace)",
-        "C28": "Modifier paiement"
+        "C28": "Modifier paiement",
+        "C29": "Gestion Fiscale",
+        "C30": "Extraction de Confiture"
     }
 }

+ 18 - 1
src/assets/language/ja.json

@@ -991,6 +991,7 @@
         "equipmentName": "機器名",
         "tradeName": "商品名",
         "dividingDomesticService": "コミッション分配",
+        "tax": "税金",
         "business": "ビジネス",
         "orderNo": "注文番号",
         "commodity": "商品",
@@ -1723,6 +1724,20 @@
         "M21": "MQTT",
         "M22": "端末"
     },
+    "tax": {
+        "taxFee": "課税徴収",
+        "taxFeeDesc": "有効時、取引ごとに自動課税されます",
+        "taxRate": "税率",
+        "ratePlaceholder": "税率パーセンテージを入力(0.00~100.00)",
+        "rateRequired": "税率の入力必須",
+        "rateInvalid": "0-100の数値を入力(小数点第2位まで)",
+        "update": "即時適用"
+    },
+    "jam": {
+        "forward": "順方向抽出",
+        "reverse": "逆方向抽出",
+        "stop": "緊急停止"
+    },
     "remote": {
         "C1": "マシン再起動",
         "C2": "スリープ切替",
@@ -1751,6 +1766,8 @@
         "C25": "攪拌モード(アイスクリーム)",
         "C26": "鮮度保持(アイスクリーム)",
         "C27": "解凍モード(アイスクリーム)",
-        "C28": "支払い方法変更"
+        "C28": "支払い方法変更",
+        "C29": "税務管理",
+        "C30": "ジャム抽出"
     }
 }

+ 18 - 1
src/assets/language/pt.json

@@ -1002,6 +1002,7 @@
         "equipmentName": "Equipamento",
         "tradeName": "Produto",
         "dividingDomesticService": "Comissão",
+        "tax": "Tributos e Taxas",
         "business": "Comerciante",
         "orderNo": "Nº do Pedido",
         "commodity": "Item",
@@ -1731,6 +1732,20 @@
         "M21": "MQTT",
         "M22": "Terminais"
     },
+    "tax": {
+        "taxFee": "Cobrança Fiscal",
+        "taxFeeDesc": "Coleta automática de impostos por transação",
+        "taxRate": "Alíquota",
+        "ratePlaceholder": "Insira a porcentagem (0,00-100,00)",
+        "rateRequired": "Campo obrigatório",
+        "rateInvalid": "Valor entre 0-100 com 2 decimais",
+        "update": "Atualizar agora"
+    },
+    "jam": {
+        "forward": "Extração Direta",
+        "reverse": "Extração Reversa",
+        "stop": "Parada de Emergência"
+    },
     "remote": {
         "C1": "Reiniciar máquina",
         "C2": "Alternar sono",
@@ -1759,6 +1774,8 @@
         "C25": "Mistura (Sorvete)",
         "C26": "Conservação (Sorvete)",
         "C27": "Descongelamento (Sorvete)",
-        "C28": "Alterar pagamento"
+        "C28": "Alterar pagamento",
+        "C29": "Gestão Tributária",
+        "C30": "Extração de Geleia"
     }
 }

+ 18 - 1
src/assets/language/ru.json

@@ -1002,6 +1002,7 @@
         "equipmentName": "Устройство",
         "tradeName": "Товар",
         "dividingDomesticService": "Комиссия",
+        "tax": "Налоги и сборы",
         "business": "Мерчант",
         "orderNo": "№ заказа",
         "commodity": "Товар",
@@ -1762,6 +1763,20 @@
         "M21": "MQTT",
         "M22": "Терминалы"
     },
+    "tax": {
+        "taxFee": "Налоговое взимание",
+        "taxFeeDesc": "Автоматическое удержание налогов при активации",
+        "taxRate": "Налоговая ставка",
+        "ratePlaceholder": "Введите процентную ставку (0,00-100,00)",
+        "rateRequired": "Укажите налоговую ставку",
+        "rateInvalid": "Допустимое значение: 0-100 с 2 знаками после запятой",
+        "update": "Применить сейчас"
+    },
+    "jam": {
+        "forward": "Прямая прокачка",
+        "reverse": "Обратная прокачка",
+        "stop": "Аварийная остановка"
+    },
     "remote": {
         "C1": "Перезагрузка машины",
         "C2": "Переключение сна",
@@ -1790,6 +1805,8 @@
         "C25": "Перемешивание (Мороженое)",
         "C26": "Сохранение свежести (Мороженое)",
         "C27": "Разморозка (Мороженое)",
-        "C28": "Изменить оплату"
+        "C28": "Изменить оплату",
+        "C29": "Управление налогообложением",
+        "C30": "Экстракция джема"
     }
 }

+ 18 - 1
src/assets/language/uk.json

@@ -1002,6 +1002,7 @@
         "equipmentName": "Пристрій",
         "tradeName": "Товар",
         "dividingDomesticService": "Розподіл комісій",
+        "tax": "Податки та збори",
         "business": "Продавець",
         "orderNo": "Номер замовлення",
         "commodity": "Товар",
@@ -1732,6 +1733,20 @@
         "M21": "MQTT",
         "M22": "Керування терміналами"
     },
+    "tax": {
+        "taxFee": "Податкове стягнення",
+        "taxFeeDesc": "Автоматичне утримання податків",
+        "taxRate": "Податкова ставка",
+        "ratePlaceholder": "Введіть відсоток (0,00-100,00)",
+        "rateRequired": "Обов'язкове поле",
+        "rateInvalid": "Допустиме значення: 0-100 з 2 десятковими",
+        "update": "Застосувати"
+    },
+    "jam": {
+        "forward": "Пряме витягнення",
+        "reverse": "Зворотне витягнення",
+        "stop": "Аварійне зупинення"
+    },
     "remote": {
         "C1": "Перезавантажити пристрій",
         "C2": "Режим сну",
@@ -1760,6 +1775,8 @@
         "C25": "Змішування (морозиво)",
         "C26": "Збереження свіжості (морозиво)",
         "C27": "Розморозка (морозиво)",
-        "C28": "Змінити оплату"
+        "C28": "Змінити оплату",
+        "C29": "Управління оподаткуванням",
+        "C30": "Витяг джему"
     }
 }

+ 18 - 1
src/assets/language/zh.json

@@ -1002,6 +1002,7 @@
     "equipmentName": "设备名称",
     "tradeName": "商品名称",
     "dividingDomesticService": "分佣",
+    "tax": "税费",
     "business": "商家",
     "orderNo": "订单编号",
     "commodity": "商品",
@@ -1732,6 +1733,20 @@
     "M21": "MQTT",
     "M22": "终端管理"
   },
+  "tax": {
+    "taxFee": "税费征收",
+    "taxFeeDesc": "启用后将对每笔交易收取税费",
+    "taxRate": "税率",
+    "ratePlaceholder": "请输入税率百分比",
+    "rateRequired": "税率不能为空",
+    "rateInvalid": "请输入0-100之间的有效数值(最多两位小数)",
+    "update": "立即更新"
+  },
+  "jam": {
+    "forward": "正抽",
+    "reverse": "反抽",
+    "stop": "停止"
+  },
   "remote": {
     "C1": "重启设备",
     "C2": "睡眠开关",
@@ -1760,6 +1775,8 @@
     "C25": "搅拌模式(冰淇淋)",
     "C26": "保鲜模式(冰淇淋)",
     "C27": "解冻模式(冰淇淋)",
-    "C28": "修改支付方式"
+    "C28": "修改支付方式",
+    "C29": "税收管理",
+    "C30": "果酱抽取"
   }
 }

+ 1 - 0
src/common/js/utils.js

@@ -58,6 +58,7 @@ export const remoteMenus = {
   "C26": t("remote.C26"),
   "C27": t("remote.C27"),
   "C28": t("remote.C28"),
+  "C29": t("remote.C29")
 }
 
 // 判断值是否是数字 true:数值型的,false:非数值型

+ 2 - 3
src/components/commom/kDialog/index.vue

@@ -1,5 +1,4 @@
 <template>
-  <!-- 通知弹窗 -->
   <div class="k-dialog">
     <van-dialog close-on-click-overlay v-model:show="dialogShow" :title="dialogTitle" :show-confirm-button="false"
       :show-cancel-button="false">
@@ -29,7 +28,6 @@
  *
  */
 import { ref } from "vue";
-import { styleUrl } from "../../../common/js/utils";
 export default {
   props: {
     // 弹窗标题
@@ -88,7 +86,6 @@ export default {
       ctx.emit("confirmclk", "右侧按钮222");
     };
 
-    styleUrl('kDialog');
     return {
       dialogShow,
       openDialog,
@@ -101,6 +98,8 @@ export default {
 </script>
 
 <style lang="less" scoped>
+@import "@/common/style/common.less";
+// @import "./index.less";
 .k-dialog {
   --primary-color: #2c87c8;
   --text-color-light: #ffffff;

+ 6 - 19
src/components/dateSelectList/index.vue

@@ -152,9 +152,9 @@ export default {
             dateUtil.formateDate(endTime, "yyyy-MM-dd") + " 23:59:59";
         } else {
           // 按月统计
-          params.chartType = "month";
-          startTime = new Date(monthDate.value[0] + '-' + monthDate.value[1] + '-01');
-          endTime = new Date(monthDate.value[0], monthDate.value[1], 0);
+          params.chartType = "year";
+          startTime = calendarDate[0];
+          endTime = calendarDate[1];
           params.startDate =
             dateUtil.formateDate(startTime, "yyyy-MM-dd") + " 00:00:00";
           params.endDate =
@@ -171,7 +171,6 @@ export default {
       { text: t('dateSelectList.monthType'), value: "2" },
     ];
     const timeTypeConfirm = ({ selectedOptions }) => {
-      console.log('selectedOptions[0].text', selectedOptions[0].value);
       // 按日统计
       chartType.value = selectedOptions[0].value;
       if (selectedOptions[0].value == '1') {
@@ -192,8 +191,9 @@ export default {
     const monthDateShow = ref(false);
     const monthDate = ref([currentYear, currentMonth]);
     const monthDateType = ['year', 'month'];
-    const monthDateConfirm = () => {
+    const monthDateConfirm = (data) => {
       monthDateShow.value = false;
+      calendarDate = data;
       outputDate();
     }
     const monthDateCancel = () => { monthDateShow.value = false; }
@@ -234,8 +234,7 @@ export default {
   .time-tabs {
     display: flex;
     background: #fff;
-    border-radius: 4px;
-    border: 1px solid var(--border-color);
+    border-radius: 8px;
     box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
     overflow: hidden;
 
@@ -251,7 +250,6 @@ export default {
       white-space: nowrap;
       cursor: pointer;
       transition: all 0.2s ease;
-      border-right: 1px solid var(--border-color);
 
       &:last-child {
         border-right: none;
@@ -266,17 +264,6 @@ export default {
         color: #fff;
         font-weight: 500;
 
-        &::after {
-          content: "";
-          position: absolute;
-          bottom: -5px;
-          left: 50%;
-          transform: translateX(-50%);
-          border-left: 6px solid transparent;
-          border-right: 6px solid transparent;
-          border-top: 6px solid var(--bg-active);
-        }
-
         .dropdown-indicator {
           border-top-color: #fff;
         }

+ 14 - 0
src/router/index.js

@@ -511,6 +511,20 @@ const router = createRouter({
       component: () => import("@/views/device/payment/index"),
       meta: { index: 1 },
     },
+    // 税收管理
+    {
+      path: "/tax",
+      name: "tax",
+      component: () => import("@/views/device/tax/index"),
+      meta: { index: 1 },
+    },
+    // 果酱抽取
+    {
+      path: "/jam",
+      name: "jam",
+      component: () => import("@/views/device/jam/index"),
+      meta: { index: 1 },
+    },
     // 提现列表
     {
       path: "/withdrawList",

+ 25 - 0
src/service/device/index.js

@@ -102,6 +102,11 @@ export function doSugar(params) {
   return axios.post(`/SZWL-SERVER/tSugarDo/doSugar`, params);
 }
 
+// 远程制作
+export function remoteProduction(params) {
+  return axios.post(`/SZWL-SERVER/tSugarDo/remoteProduction`, params);
+}
+
 // 查询做糖状态
 export function selectSugarStatus(params) {
   return axios.get(
@@ -239,6 +244,11 @@ export function updateProductsShow(params) {
   return axios.post(`/SZWL-SERVER/tProduct/updateProductsShow`, params);
 }
 
+// 新屏蔽/显示商品
+export function newUpdateProductsShow(params) {
+  return axios.post(`/SZWL-SERVER/tProduct/newUpdateProductsShow`, params)
+}
+
 // 远程修改机器密码
 export function updateDevicePassword(params) {
   return axios.post(`/SZWL-SERVER/tEquipment/updatePassword`, params);
@@ -340,3 +350,18 @@ export function getAlaramClockByDevice(params) {
 export function updateAlaramClockStatus(params) {
   return axios.post(`/SZWL-SERVER/tAlarmClock/updataStatus`, params);
 }
+
+// 修改税费开关状态
+export function updateTaxStatus(params) {
+  return axios.post(`/SZWL-SERVER/tEquipment/updateTaxSwitch`, params);
+}
+
+// 修改税率
+export function updateTaxRate(params) {
+  return axios.post(`/SZWL-SERVER/tEquipment/updateTaxRate`, params);
+}
+
+// 果酱抽取
+export function smokeJam(params) {
+  return axios.post(`/SZWL-SERVER/tEquipment/smokeJam`, params)
+}

+ 39 - 2
src/service/purse/index.js

@@ -1,5 +1,5 @@
 import axios from "../../utils/axios";
-import { stringToUrl } from '@/common/js/utils';
+import { stringToUrl } from "@/common/js/utils";
 
 // MQTT发送消息
 export function sendMqttMessage(params) {
@@ -23,7 +23,9 @@ export function withdrawRecord(params) {
 
 // 导出提现记录
 export function exportWithdrawRecord(params) {
-  return axios.post(`/SZWL-SERVER/purse/exportWithdrawRecord`, params, { responseType: 'blob' });
+  return axios.post(`/SZWL-SERVER/purse/exportWithdrawRecord`, params, {
+    responseType: "blob",
+  });
 }
 
 // 查询提现状态
@@ -34,4 +36,39 @@ export function withdrawStatus(params) {
 // 证照识别
 export function idCardRecognition(params) {
   return axios.post(`/SZWL-SERVER/purse/ocrImage`, params);
+}
+
+// 获取商户信息
+export function getJoinPayMch(params) {
+  return axios.post(
+    `/SZWL-SERVER/tJoinpayMch/getOne?${stringToUrl(params)}`,
+    params
+  );
+}
+
+// 汇聚入网
+export function createMch(params) {
+  return axios.post(`/SZWL-SERVER/tJoinpayMch/createMch`, params);
+}
+
+// 上传图片审核
+export function uploadPhotos(params) {
+  return axios.post(`/SZWL-SERVER/tJoinpayMch/uploadPhotos`, params);
+}
+
+// 更新图片审核情况
+export function updateApproveStatus(params) {
+  return axios.post(`/SZWL-SERVER/tJoinpayMch/updateApproveStatus`, params);
+}
+
+// 签约
+export function altMchSign(params) {
+  return axios.get(
+    `/SZWL-SERVER/tJoinpayMch/altMchSign?${stringToUrl(params)}`
+  );
+}
+
+// 查询证照
+export function getPhotos(params) {
+  return axios.get(`/SZWL-SERVER/purse/userLicense?${stringToUrl(params)}`);
 }

文件差異過大導致無法顯示
+ 0 - 1385
src/styles/orderCenter/index.less


+ 0 - 349
src/styles/robotRanking/index.less

@@ -1,349 +0,0 @@
-body * {
-    box-sizing: border-box;
-    flex-shrink: 0;
-}
-
-body {
-    font-family: PingFangSC-Regular, Roboto, Helvetica Neue, Helvetica, Tahoma,
-        Arial, PingFang SC-Light, Microsoft YaHei;
-}
-
-button {
-    margin: 0;
-    padding: 0;
-    border: 1px solid transparent;
-    outline: none;
-    background-color: transparent;
-}
-
-button:active {
-    opacity: 0.6;
-}
-
-.flex-col {
-    display: flex;
-    flex-direction: column;
-}
-
-.flex-row {
-    display: flex;
-    flex-direction: row;
-}
-
-.justify-start {
-    display: flex;
-    justify-content: flex-start;
-}
-
-.justify-center {
-    display: flex;
-    justify-content: center;
-}
-
-.justify-end {
-    display: flex;
-    justify-content: flex-end;
-}
-
-.justify-evenly {
-    display: flex;
-    justify-content: space-evenly;
-}
-
-.justify-around {
-    display: flex;
-    justify-content: space-around;
-}
-
-.justify-between {
-    display: flex;
-    justify-content: space-between;
-}
-
-.align-start {
-    display: flex;
-    align-items: flex-start;
-}
-
-.align-center {
-    display: flex;
-    align-items: center;
-}
-
-.align-end {
-    display: flex;
-    align-items: flex-end;
-}
-
-.group5 {
-    width: 15%;
-    height: 16px;
-    margin-right: 50px;
-
-    .icon2 {
-        width: 18px;
-        height: 18px;
-        margin-right: 5px;
-    }
-
-    .TextGroup2 {
-        height: 16px;
-        width: 22px;
-
-        .txt3 {
-            width: 22px;
-            height: 16px;
-            overflow-wrap: break-word;
-            color: rgba(64, 77, 116, 1);
-            font-size: 14px;
-            font-family: PingFangSC-Semibold;
-            text-align: center;
-            white-space: nowrap;
-            line-height: 16px;
-            display: block;
-        }
-    }
-}
-
-.robotRanking {
-    background-color: #fff;
-    width: 100%;
-    // height: calc(100vh - 100px);
-    
-    
-    .box1 {
-        height: 100%;
-        width: 100%;
-        height: calc(100% - 50px);
-        padding-bottom: 10px;
-        overflow: auto;
-        overflow-x: hidden;
-
-
-        .van-tabs__line {
-            background-color: #2c87c8 !important;
-        }
-
-        .van-tab--active .van-tab__text--ellipsis {
-            color: #2c87c8;
-        }
-
-        .box2 {
-            height: 64px;
-            background: url(https://lanhu.oss-cn-beijing.aliyuncs.com/SketchPnged210ff8540d1e20d828b0758e650612a9ea018b41f720bede87fea0f933d8d8) 100% no-repeat;
-            width: 100%;
-
-            .layer1 {
-                width: 364px;
-                height: 20px;
-                margin: 1px 0 0 7px;
-
-                .group1 {
-                    width: 34px;
-                    height: 6px;
-                    background: url(https://lanhu.oss-cn-beijing.aliyuncs.com/SketchPnga64b2ae35561e96115c75cc6dfc235eedb108ecf95df957be1ef364417a9806e) 100% no-repeat;
-                    margin-top: 7px;
-                }
-
-                .word1 {
-                    width: 38px;
-                    height: 17px;
-                    overflow-wrap: break-word;
-                    color: rgba(81, 84, 106, 1);
-                    font-size: 12px;
-                    font-family: PingFangSC-Semibold;
-                    text-align: right;
-                    white-space: nowrap;
-                    line-height: 17px;
-                    margin-left: 21px;
-                    display: block;
-                }
-
-                .group2 {
-                    width: 30px;
-                    height: 17px;
-                    overflow-wrap: break-word;
-                    font-size: 0;
-                    font-family: PingFangSC-Semibold;
-                    text-align: right;
-                    white-space: nowrap;
-                    line-height: 17px;
-                    margin: 3px 0 0 73px;
-
-                    .info1 {
-                        width: 30px;
-                        height: 17px;
-                        overflow-wrap: break-word;
-                        color: rgba(81, 84, 106, 1);
-                        font-size: 12px;
-                        font-family: PingFangSC-Semibold;
-                        text-align: left;
-                        white-space: nowrap;
-                        line-height: 17px;
-                    }
-
-                    .word2 {
-                        width: 30px;
-                        height: 17px;
-                        overflow-wrap: break-word;
-                        color: rgba(81, 84, 106, 1);
-                        font-size: 12px;
-                        font-family: PingFangSC-Medium;
-                        text-align: left;
-                        white-space: nowrap;
-                        line-height: 17px;
-                    }
-                }
-
-                .group3 {
-                    width: 26px;
-                    height: 10px;
-                    background: url(https://lanhu.oss-cn-beijing.aliyuncs.com/SketchPng2e68dee6e62554db0f6ac40572f41b7be9cc24d35fc06b24c556fed2b7b18626) 100% no-repeat;
-                    margin: 5px 0 0 142px;
-                }
-            }
-
-            .layer2 {
-                width: 218px;
-                height: 22px;
-                margin: 9px 0 12px 10px;
-
-                .label1 {
-                    width: 10px;
-                    height: 18px;
-                    margin-top: 4px;
-                }
-
-                .txt1 {
-                    width: 80px;
-                    height: 22px;
-                    overflow-wrap: break-word;
-                    color: rgba(64, 77, 116, 1);
-                    font-size: 16px;
-                    font-family: PingFangSC-Medium;
-                    text-align: center;
-                    white-space: nowrap;
-                    line-height: 22px;
-                    display: block;
-                }
-            }
-        }
-
-        .box3 {
-            background-color: rgba(255, 255, 255, 1);
-            height: 100%;
-            margin-top: 1px;
-            width: 100%;
-
-            .main1 {
-                width: 100%;
-                height: 100%;
-
-                .groove {
-                    height: 10px;
-                    width: 100%;
-                    background-color: #f5f5f5;
-                }
-
-                .mod1 {
-
-                    .section1 {
-                        margin: 15px 15px;
-
-                        .ImageText1 {
-                            height: 16px;
-                            margin-top: 1px;
-                            width: 55%;
-
-                            .group4 {
-                                width: 40%;
-                                height: 16px;
-
-                                .layer3 {
-                                    width: 16px;
-                                    height: 16px;
-                                    margin-right: 5px;
-                                    background: url("../../assets/home/titleIcon.png") top center no-repeat;
-                                    background-size: 100%;
-                                }
-
-                                .word3 {
-                                    width: auto;
-                                    height: 14px;
-                                    overflow-wrap: break-word;
-                                    color: rgba(64, 77, 116, 1);
-                                    font-size: 15px;
-                                    font-family: PingFangSC-Semibold;
-                                    text-align: left;
-                                    white-space: nowrap;
-                                    line-height: 15px;
-                                    display: block;
-                                }
-                            }
-                        }
-
-                        .main5 {
-                            width: auto;
-                            cursor: pointer;
-
-                            .label2 {
-                                width: 20px;
-                                height: 20px;
-                                margin-right: 5px;
-                            }
-                        }
-                    }
-                }
-
-                .robotLabelName {
-                    width: 25%;
-                }
-
-                .mod3 {
-                    background-color: rgba(255, 255, 255, 1);
-                    z-index: 24;
-                    height: 350px;
-                    width: 100%;
-                    position: relative;
-                }
-
-                .mod5 {
-                    background-color: rgba(255, 255, 255, 1);
-                    z-index: 84;
-                    height: 350px;
-                    width: 100%;
-                    position: relative;
-                }
-
-                .mod9 {
-                    background-color: rgba(255, 255, 255, 1);
-                    z-index: 156;
-                    height: 350px;
-                    width: 100%;
-                    position: relative;
-                }
-
-                .mod11 {
-                    background-color: rgba(255, 255, 255, 1);
-                    z-index: 217;
-                    height: 350px;
-                    width: 100%;
-                    position: relative;
-                }
-            }
-        }
-
-    }
-
-    .van-field__label {
-        width: auto;
-    }
-
-    .van-field__control {
-        width: 70%;
-    }
-
-    .van-field__body {
-        width: 100%;
-    }
-}

+ 0 - 264
src/styles/user/index.less

@@ -1,264 +0,0 @@
-.userPage {
-    width: 100%;
-    background: url(../../assets/user/bg.png) top center no-repeat;
-    background-size: 100%;
-    // height: calc(100vh - 50px);
-    // padding-bottom: 50px;
-
-
-    .van-nav-bar {
-        background: transparent;
-    }
-
-    .userPageBox {
-        height: 100%;
-        width: 100%;
-        height: calc(100% - 50px);
-        overflow: auto;
-        overflow-x: hidden;
-    }
-
-    .userBaseBox {
-        width: 100%;
-    }
-
-    .baseRow {
-        margin: 10px 10px;
-
-        .group2 {
-            background-color: #5a9cc8;
-            border-radius: 2px;
-            width: 4px;
-            height: 16px;
-        }
-
-        .baseText {
-            width: 150px;
-            overflow-wrap: break-word;
-            color: rgba(64, 77, 116, 1);
-            font-size: 13px;
-            font-family: PingFangSC-Medium;
-            text-align: left;
-            white-space: nowrap;
-            line-height: 13px;
-            display: block;
-            margin-left: 8px;
-        }
-    }
-
-    .userMessage {
-        text-align: center;
-        width: 80%;
-        margin: 0 auto;
-        margin-top: 30px;
-        line-height: 1.7;
-
-        .userText {
-            font-size: 14px;
-            font-family: PingFangSC-Medium;
-            margin: 0;
-        }
-
-        .userLine {
-            width: 1px;
-            height: 3.5em;
-            font-size: 14px;
-            background: #e7eaf7;
-        }
-    }
-
-    .userInfoBox {
-        // margin-top: 25px;
-        padding: 0px 10px 15px;
-
-        .userInfo {
-            // width: 87%;
-            margin: 0 3px;
-            justify-content: flex-start;
-            margin-top: 15px;
-            position: relative;
-            font-size: 12px;
-
-            .filedInpPad {
-                .van-cell {
-                    padding: 0 !important;
-                }
-            }
-
-            .editIcon {
-                position: absolute;
-                right: 0;
-                font-size: 18px;
-                color: #2c87c8;
-            }
-
-            .userInfoLeft {
-                // width: 76px;
-                padding-right: 10px;
-            }
-
-            .relationClass {
-
-                .van-field__control {
-                    width: 60%;
-                    height: 38px;
-                    line-height: 38px;
-                    padding: 6px;
-                    border-radius: 2px;
-                    background: #fff;
-                    border: 1px solid #dddde8;
-                }
-
-                .van-field__button {
-                    background-color: #2c87c8;
-                    color: #fff;
-                    padding: 0 1em;
-                    margin-left: 15px;
-                    border-radius: 1em;
-                }
-            }
-        }
-    }
-
-    .van-cell {
-        background: none;
-    }
-
-    .lineBox {
-        width: 100%;
-        height: 10px;
-        background-color: #f6f7fc;
-    }
-
-    .commonOperBox {
-        width: 100%;
-        background: #fff;
-
-        .operListBox {
-
-            .taskListRow {
-                width: 100%;
-                height: 50px;
-                flex-wrap: wrap;
-                margin: 5px 10px;
-
-                .taskIcon {
-                    width: 10%;
-                    height: 100%;
-                    position: relative;
-
-                    &.taskMessageIcon::after {
-                        content: "";
-                        position: absolute;
-                        background: #fff url("../../assets/user/taskMessageIcon.png") top center no-repeat;
-                        background-size: 100%;
-                        width: 0.55rem;
-                        height: 0.6rem;
-                        right: 0.2rem;
-                        top: 0.45rem;
-                    }
-
-                    &.joinPayMchIcon::after {
-                        content: "";
-                        position: absolute;
-                        background: #fff url("../../assets/user/joinPayMchIcon.png") top center no-repeat;
-                        background-size: 100%;
-                        width: 0.6rem;
-                        height: 0.6rem;
-                        right: 0.2rem;
-                        top: 0.4rem;
-                    }
-
-                    &.shandeMchIcon::after {
-                        content: "";
-                        position: absolute;
-                        background: #fff url("../../assets/user/shandeMchIcon.png") top center no-repeat;
-                        background-size: 100%;
-                        width: 0.65rem;
-                        height: 0.65rem;
-                        right: 0.2rem;
-                        top: 0.4rem;
-                    }
-
-                    &.bindWechatIcon::after {
-                        content: "";
-                        position: absolute;
-                        background: #fff url("../../assets/user/bindWechatIcon.png") top center no-repeat;
-                        background-size: 100%;
-                        width: 0.6rem;
-                        height: 0.6rem;
-                        right: 0.2rem;
-                        top: 0.4rem;
-                    }
-
-                    &.changePasswordIcon::after {
-                        content: "";
-                        position: absolute;
-                        background: #fff url("../../assets/user/changePasswordIcon.png") top center no-repeat;
-                        background-size: 100%;
-                        width: 0.6rem;
-                        height: 0.6rem;
-                        right: 0.25rem;
-                        top: 0.4rem;
-                    }
-
-                    &.selfPayIcon::after {
-                        content: "";
-                        position: absolute;
-                        background: #fff url("../../assets/user/self.png") top center no-repeat;
-                        background-size: 100%;
-                        width: 0.6rem;
-                        height: 0.6rem;
-                        right: 0.2rem;
-                        top: 0.4rem;
-                    }
-
-                    &.feedbackIcon::after {
-                        content: "";
-                        position: absolute;
-                        background: #fff url("../../assets/user/feedback.png") top center no-repeat;
-                        background-size: 100%;
-                        width: 0.6rem;
-                        height: 0.6rem;
-                        right: 0.2rem;
-                        top: 0.4rem;
-                    }
-
-                    &.loginOutIcon::after {
-                        content: "";
-                        position: absolute;
-                        background: #fff url("../../assets/user/loginOut.png") top center no-repeat;
-                        background-size: 100%;
-                        width: 0.55rem;
-                        height: 0.55rem;
-                        right: 0.2rem;
-                        top: 0.4rem;
-                    }
-                }
-
-                .taskRight {
-                    width: 87%;
-                    height: 100%;
-                    position: relative;
-                    border-bottom: 1px solid #e7eaf7;
-
-                    &::after {
-                        content: "";
-                        position: absolute;
-                        width: 6px;
-                        height: 12px;
-                        background: url('../../assets/right.png') top center no-repeat;
-                        background-size: 100%;
-                        right: 0.55rem;
-                        top: 0.5rem;
-                    }
-
-                    .taskTitle {
-                        line-height: 53px;
-                        font-size: 14px;
-                    }
-                }
-            }
-        }
-    }
-}

文件差異過大導致無法顯示
+ 1844 - 1066
src/views/bindBankCard/index.vue


文件差異過大導致無法顯示
+ 482 - 128
src/views/device/deviceOper.vue


+ 408 - 268
src/views/device/deviceSet.vue

@@ -1,233 +1,250 @@
 <template>
-  <!-- 设备信息修改 -->
-  <div class="deviceSetPage flex-col">
-    <s-header :name="$t('device.deviceInformation')" :noback="false"></s-header>
-    <van-form @submit="updateDeviceFun">
-      <div class="bd1 flex-col">
-        <div class="bd3 flex-col">
-          <div class="mod1 flex-col">
-            <span class="word2">{{ $t("device.essentialInformation") }}</span>
-            <img class="pic1" referrerpolicy="no-referrer" src="../../assets/line.png" />
-          </div>
-          <div class="mod2 flex-col"></div>
+  <div class="device-settings">
+    <s-header :name="$t('device.deviceInformation')" :noback="false" />
+
+    <van-form @submit="updateDeviceFun" class="device-settings-form">
+      <!-- 基础信息卡片 -->
+      <div class="settings-card">
+        <div class="card-header">
+          <span class="header-icon"></span>
+          <h3 class="card-title">{{ $t("device.essentialInformation") }}</h3>
         </div>
-        <van-field readonly v-model="deviceDetal.clientId" :label="`${$t('device.equipmentCode')}`" placeholder="" />
-        <div class="cust_vantBorder">
-          <van-field required clearable v-model="deviceDetal.name" name="name"
-            :label="`${$t('device.equipmentNameLabel')}`" :placeholder="$t('device.equipmentNamePlaceholder')" :rules="[
+
+        <van-field
+          readonly
+          v-model="deviceDetal.clientId"
+          :label="$t('device.equipmentCode')"
+          class="form-item"
+        />
+
+        <div class="form-group">
+          <van-field
+            required
+            clearable
+            v-model="deviceDetal.name"
+            name="name"
+            :label="$t('device.equipmentNameLabel')"
+            :placeholder="$t('device.equipmentNamePlaceholder')"
+            :rules="[
               {
                 required: true,
                 message: $t('device.equipmentNamePlaceholder'),
               },
-            ]" />
-          <van-field clearable v-model="deviceDetal.selfName" :label="`${$t('device.equipmentRemarksLabel')}`"
-            :placeholder="$t('device.equipmentRemarksPlaceholder')" />
-          <div></div>
-        </div>
-        <van-field readonly v-model="deviceDetal.adminUserName" :label="`${$t('device.affiliatedMerchant')}`" />
-        <!-- 地区 -->
-        <!-- <div v-if="areaShow" class="bd7 l-flex-between">
-          <div class="l-flex-RC">
-            <div class="cust_vantBorder">
-              <div class="filedInpPad">
-                <van-field colon @click-input="fieldValueInpClk" readonly clearable v-model="fieldValue"
-                  :label="`${$t('device.affiliatedArea')}`" :placeholder="$t('user.regionPlace')">
-                  <template #right-icon>
-                    <div class="l-flex-RC">
-                      <van-icon v-if="fieldValue" @click="
-                        fieldValue = '';
-                      deviceDetal.areaId = '';
-                      " class="o-mr-6" name="clear" />
-                      <van-icon @click="fieldValueInpClk" name="arrow-down" />
-                    </div>
-                  </template>
-                  <template #extra>
-                    <van-icon @click="areaShow = !areaShow" size="20" name="edit" />
-                  </template>
-                </van-field>
-              </div>
-            </div>
-          </div>
+            ]"
+            class="form-item"
+          />
+          <van-field
+            clearable
+            v-model="deviceDetal.selfName"
+            :label="$t('device.equipmentRemarksLabel')"
+            :placeholder="$t('device.equipmentRemarksPlaceholder')"
+            class="form-item"
+          />
         </div>
-        <div v-else class="bd7 l-flex-between">
-          <van-field colon readonly v-model="fieldValue" :label="`${$t('device.affiliatedArea')}`" placeholder="">
-            <template #extra>
-              <van-icon @click="areaShow = !areaShow" size="20" name="edit" />
-            </template>
-          </van-field>
-        </div> -->
-        <van-field readonly v-model="equimentType" :label="`${$t('device.machineType')}`" placeholder="" />
-        <!-- mg280才有到期时间 -->
-        <template v-if="deviceDetal?.equimentType?.indexOf('mg280') !== -1">
-          <van-field readonly v-model="deviceDetal.lastUseDate" :label="`${$t('device.expirationTime')}`"
-            placeholder="" />
-        </template>
-        <div class="bd9 l-f">
-          <van-field readonly :label="`${$t('device.equipmentLabel')}`" placeholder="">
-            <template #input>
-              <div class="box2 l-flex-RC l-flex-w" v-if="tagsList.arr.length > 0">
-                <div class="word8 o-mr-6 o-p-6 c-radius-2 o-mb-10" v-for="(item, index) in tagsList.arr" :key="index">
-                  {{ item.name }}
-                </div>
-              </div>
-            </template>
-            <template #extra>
-              <div @click="toTagSet" class="ImageText1 flex-col">
-                <div class="box3 flex-row justify-between">
-                  <div class="bd10 flex-col"></div>
-                  <div class="TextGroup1 flex-col">
-                    <span class="word9">{{ $t("device.edit") }}</span>
-                  </div>
-                </div>
-              </div>
-            </template>
-          </van-field>
-        </div>
-        <div class="custom-line"></div>
-        <div v-if="isAdmind" class="bd9 l-f">
-          <van-field readonly :label="`${$t('device.adRule')}`" placeholder="">
-            <template #input>
-              <div class="box2 l-flex-RC l-flex-w" v-if="adRuleList.length > 0">
-                <div class="word8 o-mr-6 o-p-6 c-radius-2 o-mb-5" v-for="(item, index) in adRuleList" :key="index">
-                  {{ item.name }}
-                </div>
-              </div>
-            </template>
-            <template #extra>
-              <div @click="toEditAdRule" class="ImageText1 flex-col">
-                <div class="box3 flex-row justify-between">
-                  <div class="bd10 flex-col"></div>
-                  <div class="TextGroup1 flex-col">
-                    <span class="word9">{{ $t("device.edit") }}</span>
-                  </div>
-                </div>
-              </div>
-            </template>
-          </van-field>
-          <div class="custom-line"></div>
-        </div>
-        <!-- 优惠券 -->
-        <!-- <van-field readonly :label="`${$t('device.coupon')}`" placeholder=""
-          v-if="user.type < 2 && user.ifForeign === '0'">
+      </div>
+
+      <!-- 设备状态卡片 -->
+      <div class="settings-card">
+        <van-field
+          readonly
+          v-model="deviceDetal.adminUserName"
+          :label="$t('device.affiliatedMerchant')"
+          class="form-item"
+        />
+        <van-field
+          readonly
+          v-model="deviceDetal.equimentType"
+          :label="$t('device.machineType')"
+          class="form-item"
+        />
+        <!-- 版本号 -->
+        <van-field
+          readonly
+          v-model="deviceDetal.apkVersion"
+          :label="`${$t('device.versionNo')}`"
+          class="form-item"
+        />
+        <van-field
+          readonly
+          :label="$t('device.equipmentLabel')"
+          class="tag-field"
+        >
           <template #input>
-            <div class="l-flex-RC">
-              <span>{{ couponStatusNameComp }}</span>
-              <van-switch class="o-ml-5" @change="couponStatusChg" v-model="deviceDetal.couponStatus" size="23px"
-                active-value="1" inactive-value="0" />
+            <div class="tag-container" v-if="tagsList.arr.length > 0">
+              <van-tag
+                v-for="(item, index) in tagsList.arr"
+                :key="index"
+                class="tag-item"
+              >
+                {{ item.name }}
+              </van-tag>
             </div>
           </template>
-        </van-field> -->
-        <div class="cust_vantBorder">
-          <van-field required clearable v-model="deviceDetal.contactName" name="contactName"
-            :label="`${$t('device.nameOfOperatorLabel')}`" :placeholder="$t('device.nameOfOperatorPlaceholder')" :rules="[
-              {
-                required: true,
-                message: $t('device.nameOfOperatorPlaceholder'),
-              },
-            ]" />
-          <van-field required clearable v-model="deviceDetal.contactPhone" name="contactPhone"
-            :label="`${$t('device.operatorTelephoneLabel')}`" :placeholder="$t('device.operatorTelephonePlaceholder')"
-            :rules="[
-              {
-                required: true,
-                message: $t('device.operatorTelephonePlaceholder'),
-              },
-            ]" />
+          <template #extra>
+            <van-button icon="edit" class="edit-btn" @click="toTagSet" />
+          </template>
+        </van-field>
+      </div>
 
-          <!-- <van-field clearable v-model="deviceDetal.timeRuleId" :label="`${$t('device.advertisingRulesLabel')}:`"
-            :placeholder="$t('device.advertisingRulesPlaceholder')" /> -->
-        </div>
-        <div class="custom-line"></div>
-        <div class="cust_vantBorder">
-          <van-field clearable label-width="32%" v-model="deviceDetal.messageReceiver1"
-            :label="`${$t('device.messageReceiver1')}`" :placeholder="$t('device.equipmentmessageReceiverPlaceholder')" />
-          <van-field clearable label-width="32%" v-model="deviceDetal.messageReceiver2"
-            :label="`${$t('device.messageReceiver2')}`" :placeholder="$t('device.equipmentmessageReceiverPlaceholder')" />
-          <van-field clearable label-width="32%" v-model="deviceDetal.messageReceiver3"
-            :label="`${$t('device.messageReceiver3')}`" :placeholder="$t('device.equipmentmessageReceiverPlaceholder')" />
-        </div>
-        <div class="custom-line"></div>
-        <!-- <div class="cust_vantBorder">
-        </div>
-        <div class="cust_vantBorder">
-        </div> -->
-        <!-- 支付方式 -->
-        <!-- <van-field v-if="user.ifForeign == '0'" colon readonly label-width="18%" :label="`${$t('device.paymentMethod')}`"
-          placeholder="">
+      <!-- 标签管理卡片 -->
+      <div class="settings-card">
+        <van-field
+          required
+          clearable
+          class="form-item"
+          v-model="deviceDetal.contactName"
+          name="contactName"
+          :label="`${$t('device.nameOfOperatorLabel')}`"
+          :placeholder="$t('device.nameOfOperatorPlaceholder')"
+          :rules="[
+            {
+              required: true,
+              message: $t('device.nameOfOperatorPlaceholder'),
+            },
+          ]"
+        />
+        <van-field
+          required
+          clearable
+          class="form-item"
+          v-model="deviceDetal.contactPhone"
+          name="contactPhone"
+          :label="`${$t('device.operatorTelephoneLabel')}`"
+          :placeholder="$t('device.operatorTelephonePlaceholder')"
+          :rules="[
+            {
+              required: true,
+              message: $t('device.operatorTelephonePlaceholder'),
+            },
+          ]"
+        />
+        <van-field
+          clearable
+          class="form-item"
+          v-model="deviceDetal.messageReceiver1"
+          :label="`${$t('device.messageReceiver1')}`"
+          :placeholder="$t('device.equipmentmessageReceiverPlaceholder')"
+        />
+        <van-field
+          clearable
+          class="form-item"
+          v-model="deviceDetal.messageReceiver2"
+          :label="`${$t('device.messageReceiver2')}`"
+          :placeholder="$t('device.equipmentmessageReceiverPlaceholder')"
+        />
+        <van-field
+          clearable
+          class="form-item"
+          v-model="deviceDetal.messageReceiver3"
+          :label="`${$t('device.messageReceiver3')}`"
+          :placeholder="$t('device.equipmentmessageReceiverPlaceholder')"
+        />
+      </div>
+
+      <!-- 操作卡片 -->
+      <div class="settings-card" v-if="isAdmind">
+        <van-field readonly :label="$t('device.adRule')" class="tag-field">
           <template #input>
-            <div class="van-cell__value van-field__value radioBox">
-              <van-radio-group v-model="deviceDetal.payType" direction="horizontal">
-                <van-radio name="0" icon-size="18px">{{
-                  $t("device.onlinePayment")
-                }}</van-radio>
-                <van-radio name="1" icon-size="18px">{{
-                  $t("device.offlinePayment")
-                }}</van-radio>
-                <van-radio name="2" icon-size="18px">{{
-                  $t("device.onlineAndOfflinePayment")
-                }}</van-radio>
-              </van-radio-group>
+            <div class="tag-container" v-if="adRuleList.length > 0">
+              <van-tag
+                v-for="(item, index) in adRuleList"
+                :key="index"
+                class="tag-item"
+              >
+                {{ item.name }}
+              </van-tag>
             </div>
           </template>
-        </van-field> -->
-        <!-- 新支付方式,暂时没用屏蔽掉,后续再添加 -->
-        <!-- <van-field v-model="paymentValue" is-link readonly :label="`${$t('device.paymentMethod')}`" placeholder="选择支付方式"
-          @click="showPayment = true" />
-        <van-popup v-model:show="showPayment" round position="bottom">
-          <van-picker :columns="paymentColumns" @cancel="showPayment = false" @confirm="onConfirm" />
-        </van-popup> -->
-        <!-- 通信通道 -->
-        <template v-if="isAdmind">
-          <van-field readonly :label="`${$t('device.communiChannel')}`" placeholder="">
-            <template #input>
-              <div class="van-cell__value van-field__value radioBox">
-                <van-radio-group v-model="deviceDetal.channel" direction="horizontal">
-                  <van-radio name="1" icon-size="16px">{{
-                    $t("device.tweets")
-                  }}</van-radio>
-                  <van-radio name="2" icon-size="16px">{{
-                    $t("device.mq")
-                  }}</van-radio>
-                </van-radio-group>
-              </div>
-            </template>
-          </van-field>
-        </template>
-        <!-- 花型种类 -->
-        <template v-if="isAdmind && machineType === '0'">
-          <van-field v-model="deviceDetal.flowers" is-link readonly :label="$t('device.flowerType')" placeholder="选择花型种类"
-            @click="showFlowerPicker = true" />
-        </template>
-        <!-- 版本号 -->
-        <van-field readonly v-model="deviceDetal.apkVersion" :label="`${$t('device.versionNo')}`" placeholder="" />
-        <!-- url -->
-        <div v-if="isAdmind">
-          <van-field center clearable class="input1" v-model="deviceDetal.url" :label="$t('device.url')"
-            :placeholder="$t('device.urlPlace')">
-            <template #button>
-              <van-button class="updateBtn" @click="updateUrlClk" type="primary">&nbsp;&nbsp;{{ $t("device.update")
-              }}&nbsp;&nbsp;</van-button>
-            </template>
-          </van-field>
-        </div>
-        <div class="l-flex-center o-mtb-30">
-          <van-button round type="primary" class="info7" native-type="submit">{{
-            $t("device.submitAndPushDeviceUpdates") }}</van-button>
-        </div>
+          <template #extra>
+            <van-button icon="edit" class="edit-btn" @click="toEditAdRule" />
+          </template>
+        </van-field>
+
+        <van-field
+          v-if="machineType === '0' || machineType === '1'"
+          v-model="deviceDetal.flowers"
+          is-link
+          readonly
+          :label="machineType === '1' ? '口味种类' : $t('device.flowerType')"
+          :placeholder="machineType === '1' ? '选择口味种类' : '选择花型种类'"
+          @click="clickFlowerPicker"
+          class="form-item"
+        />
+
+        <van-field
+          readonly
+          :label="$t('device.communiChannel')"
+          class="form-item"
+        >
+          <template #input>
+            <van-radio-group
+              v-model="deviceDetal.channel"
+              direction="horizontal"
+            >
+              <van-radio name="1" checked-color="#2c87c8" icon-size="16px">{{
+                $t("device.tweets")
+              }}</van-radio>
+              <van-radio name="2" checked-color="#2c87c8" icon-size="16px">{{
+                $t("device.mq")
+              }}</van-radio>
+            </van-radio-group>
+          </template>
+        </van-field>
+
+        <van-field
+          v-model="deviceDetal.url"
+          center
+          clearable
+          class="form-item"
+          :label="$t('device.url')"
+          :placeholder="$t('device.urlPlace')"
+        >
+          <template #button>
+            <van-button size="small" color="#2c87c8" @click="updateUrlClk">{{
+              $t("device.update")
+            }}</van-button>
+          </template>
+        </van-field>
+      </div>
+
+      <!-- 操作按钮 -->
+      <div class="action-container">
+        <van-button
+          round
+          color="#2c87c8"
+          native-type="submit"
+          class="submit-btn"
+        >
+          {{ $t("device.submitAndPushDeviceUpdates") }}
+        </van-button>
       </div>
     </van-form>
     <!-- 地区弹窗 -->
-    <kCascader @getareaname="getAreaName" :selectId="deviceDetal.areaId" @areapopfinish="areaPopFinish"
-      ref="kCascaderRef"></kCascader>
+    <kCascader
+      @getareaname="getAreaName"
+      :selectId="deviceDetal.areaId"
+      @areapopfinish="areaPopFinish"
+      ref="kCascaderRef"
+    >
+    </kCascader>
     <!-- 更新弹窗 -->
-    <kDialog :dialogTitle="$t('user.logOutTips')" :cancelBtnTxt="$t('user.cancelLog')"
-      :confirmBtnTxt="$t('user.confirmLog')" ref="kDialogRef" :dialogContent="$t('device.sureUpdate')"
-      @confirmclk="confirmClk">
+    <kDialog
+      :dialogTitle="$t('user.logOutTips')"
+      :cancelBtnTxt="$t('user.cancelLog')"
+      :confirmBtnTxt="$t('user.confirmLog')"
+      ref="kDialogRef"
+      :dialogContent="$t('device.sureUpdate')"
+      @confirmclk="confirmClk"
+    >
     </kDialog>
     <!-- 花型种类 -->
     <van-popup v-model:show="showFlowerPicker" round position="bottom">
-      <van-picker v-model="selectedFlower" :columns="flowerColumns" @cancel="showFlowerPicker = false"
-        @confirm="onFlowerConfirm" />
+      <van-picker
+        v-model="selectedFlower"
+        :columns="flowerColumns"
+        @cancel="showFlowerPicker = false"
+        @confirm="onFlowerConfirm"
+      />
     </van-popup>
   </div>
 </template>
@@ -254,27 +271,13 @@ import {
   Api_getDiscCodeStatus,
   getGoodsNumber,
 } from "@/service/device/index";
-import { showFailToast, showSuccessToast, showToast } from "vant";
+import { showFailToast, showSuccessToast, showToast, closeToast } from "vant";
 import { useI18n } from "vue-i18n";
 import dateUtil from "@/utils/dateUtil";
-import { styleUrl } from "../../common/js/utils";
 
 export default {
   name: "deviceSet",
   components: { sHeader, kCascader, kDialog },
-  // // 路由守卫
-  // beforeRouteEnter(to, from, next) {
-  //   console.log("to", to);
-  //   console.log("from", from);
-  //   // 不能获取组件实例
-  //   // 因为当守卫执行前,组件实例还没被创建
-  //   if (from.name === "editTag") {
-  //     let tagList = sessionStorage.getItem("tagList") || "[]";
-  //     this.tagsList.arr = JSON.parse(tagList);
-  //     sessionStorage.removeItem("tagList");
-  //   }
-  //   next();
-  // },
   setup() {
     // 广告规则列表
     const adRuleList = ref([]);
@@ -301,14 +304,13 @@ export default {
       messageReceiver2: "",
       messageReceiver3: "",
     });
-    const equimentType = ref('');
     let tagsList = reactive({
       arr: [],
     });
     onBeforeRouteLeave((to, from, next) => {
       if (isUpdate.value) {
-        console.log("to.meta.keepAlive", to.meta.keepAlive);
-        to.meta.keepAlive = false;
+        // console.log("to.meta.keepAlive>>>", to.meta.keepAlive);
+        // to.meta.keepAlive = false;
       }
       next();
     });
@@ -322,34 +324,32 @@ export default {
     // 是否管理员
     const isAdmind = ref(false);
     // 设备类型
-    const machineType = ref('0');
+    const machineType = ref("0");
 
     const paymentColumns = [
       {
         text: t("device.onlinePayment"),
-        value: 0
+        value: 0,
       },
       {
         text: t("device.offlinePayment"),
-        value: 1
+        value: 1,
       },
       {
         text: t("device.onlineAndOfflinePayment"),
-        value: 2
-      }
+        value: 2,
+      },
     ];
-    const paymentValue = ref('');
+    const paymentValue = ref("");
     const showPayment = ref(false);
     const onConfirm = ({ selectedOptions }) => {
       paymentValue.value = selectedOptions[0].text;
       deviceDetal.value.payType = selectedOptions[0].value;
-      console.log(deviceDetal.value.payType);
       showPayment.value = false;
     };
     // 初始化页面获取列表
     onMounted(async () => {
       // 加载样式
-      styleUrl('deviceSet');
       // 从标签设置回来
       // let tagList = sessionStorage.getItem("tagList") || "[]";
       // tagsList.arr = JSON.parse(tagList);
@@ -365,7 +365,6 @@ export default {
     const getLabelDetail = () => {
       Api_getGetEquipmentToLabel({ equipmentId: route.query.deviceId }).then(
         (res) => {
-          // console.log("res", res);
           if (res.data.code === "00000") {
             tagsList.arr = res.data.data;
             // 储存数据到vuex
@@ -400,20 +399,11 @@ export default {
             getDetail(data.data.timeRuleId);
           }
         }
-        if (data.data.machineType === '1') {
-          machineType.value = '1';
-        } else if (data.data.machineType === '2') {
-          machineType.value = '1';
-        }
-        if (machineType.value == '0') {
+        machineType.value = data.data.machineType;
+        if (machineType.value == "0" || machineType.value == "1") {
           selectedFlower.value = [deviceDetal.value.flowers];
           getFlowerNumber(machineType.value);
         }
-        if (data.data.equimentType === 'MG320') {
-          equimentType.value = 'SC320';
-        } else if (data.data.equimentType === 'MG330') {
-          equimentType.value = 'SC330';
-        }
       } else {
         showFailToast(data.message);
       }
@@ -437,7 +427,7 @@ export default {
           areaId: item.areaId,
           contactName: item.contactName,
           contactPhone: item.contactPhone,
-          flowers: user.type <= 1 ? item.flowers : '',
+          flowers: user.type <= 1 ? item.flowers : "",
           operationalName: item.operationalName,
           operationalPhone: item.operationalPhone,
           timeRuleId: item.timeRuleId,
@@ -445,10 +435,10 @@ export default {
           messageReceiver1: item.messageReceiver1,
           messageReceiver2: item.messageReceiver2,
           messageReceiver3: item.messageReceiver3,
-          payType: item.payType
+          payType: item.payType,
         };
       })[0];
-      console.log(params);
+      // console.log(params);
       if (params.name.length > 25) {
         showToast(t("device.nameLength"));
         return;
@@ -464,7 +454,7 @@ export default {
         // 设备名称重复
         showToast(t("device.existsFailed"));
       } else {
-        showFailToast(t("device.editFailed"))
+        showFailToast(t("device.editFailed"));
       }
     };
 
@@ -478,17 +468,21 @@ export default {
     const getFlowerNumber = async (machineType) => {
       const { data } = await getGoodsNumber({ machineType: machineType });
       if (data.code === "00000") {
-        data.data.forEach(item => {
-          flowerColumns.push({ text: item, value: item + "" })
+        data.data.forEach((item) => {
+          flowerColumns.push({ text: item, value: item + "" });
         });
       }
-    }
+    };
     //确认选择
     const onFlowerConfirm = ({ selectedOptions }) => {
       showFlowerPicker.value = false;
       deviceDetal.value.flowers = selectedOptions[0].text;
-      showToast("提示:\n修改花型后需要重新设置价格");
-    }
+      showToast({
+        message: "提示:\n修改花型后需要重新设置价格",
+        duration: 3000,
+        forbidClick: true,
+      });
+    };
 
     // 点击去到编辑标签页
     const toTagSet = () => {
@@ -508,7 +502,7 @@ export default {
     };
     // 选择地区完成
     const areaPopFinish = async (e) => {
-      console.log("e", e);
+      // console.log("e", e);
       fieldValue.value = e.selectName;
       deviceDetal.value.areaId = e.selectId;
     };
@@ -561,9 +555,32 @@ export default {
     const toEditAdRule = () => {
       router.push({
         path: "/editAdRule",
-        query: { deviceId: route.query.deviceId, adRuleList: JSON.stringify(adRuleList.value) },
+        query: {
+          deviceId: route.query.deviceId,
+          adRuleList: JSON.stringify(adRuleList.value),
+        },
       });
     };
+    const clickFlowerPicker = () => {
+      const toast = showToast({
+        duration: 0,
+        forbidClick: true,
+        message:
+          "提示:\n请确认PLC版本支持修改的花型,避免出现程序错乱,导致客诉!!!倒计时 5 S",
+      });
+
+      let second = 5;
+      const timer = setInterval(() => {
+        second--;
+        if (second) {
+          toast.message = `提示:\n请确认PLC版本支持修改的花型,避免出现程序错乱,导致客诉!!!倒计时 ${second} S`;
+        } else {
+          clearInterval(timer);
+          closeToast();
+          showFlowerPicker.value = true;
+        }
+      }, 1000);
+    };
     return {
       deviceDetal,
       updateDeviceFun,
@@ -590,24 +607,147 @@ export default {
       paymentColumns,
       onConfirm,
       showPayment,
-      equimentType,
       flowerColumns,
       showFlowerPicker,
       selectedFlower,
       onFlowerConfirm,
+      clickFlowerPicker,
     };
   },
 };
 </script>
 <style lang="less" scoped>
-@import "../../common/style/common";
-@import "../../styles/deviceSet/index.less";
-
-.custom-line {
-  height: 1px;
-  background-color: #ebedf0;
-  /* 设置线条颜色 */
-  // margin-bottom: 10px; /* 根据需要调整线条与上方内容的间距 */
-  margin: 0 15px;
+@primary-color: #2c87c8;
+@card-bg: #ffffff;
+@text-primary: #2d3436;
+@border-color: #e4e7ec;
+
+.device-settings {
+  // padding: 16px;
+  background: #f8fafb;
+  min-height: 100vh;
+}
+
+.device-settings-form {
+  height: calc(100% - 50px);
+  overflow: auto;
+  overflow-x: hidden;
+}
+
+.settings-card {
+  background: @card-bg;
+  border-radius: 12px;
+  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
+  margin: 15px;
+
+  .card-header {
+    display: flex;
+    align-items: center;
+    margin-bottom: 16px;
+    padding-bottom: 12px;
+    border-bottom: 1px solid @border-color;
+
+    .header-icon {
+      width: 3px;
+      height: 16px;
+      background: @primary-color;
+      margin-right: 8px;
+      border-radius: 2px;
+    }
+
+    .card-title {
+      font-size: 15px;
+      color: @text-primary;
+      margin: 0;
+    }
+  }
+}
+
+.form-item {
+  padding: 15px;
+
+  :deep(.van-field__label) {
+    width: 120px;
+    color: #666;
+    font-size: 13px;
+  }
+
+  :deep(.van-field__control) {
+    color: @text-primary;
+    font-weight: 500;
+  }
+}
+
+.status-group {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
+  gap: 12px;
+}
+
+.tag-field {
+  padding: 12px 0;
+
+  :deep(.van-field__label) {
+    width: 120px;
+    color: #666;
+  }
+
+  :deep(.van-field__control) {
+    color: @text-primary;
+    font-weight: 500;
+  }
+
+  .tag-container {
+    display: flex;
+    flex-wrap: wrap;
+    gap: 8px;
+  }
+
+  .tag-item {
+    background: rgba(@primary-color, 0.1);
+    color: @primary-color;
+    padding: 4px 8px;
+    border-radius: 4px;
+    font-size: 12px;
+  }
+
+  .edit-btn {
+    color: @primary-color;
+    border: none;
+
+    // padding: 4px;
+  }
+  :deep(.van-button) {
+    height: auto !important;
+  }
+}
+
+.action-container {
+  text-align: center;
+  padding: 24px 0;
+
+  .submit-btn {
+    width: 80%;
+    max-width: 400px;
+    font-size: 16px;
+    height: 44px;
+    box-shadow: 0 4px 12px rgba(77, 194, 148, 0.2);
+  }
+}
+
+@media (max-width: 480px) {
+  .settings-card {
+    padding: 12px;
+    border-radius: 8px;
+  }
+
+  .form-item {
+    padding: 8px 0;
+  }
+
+  .submit-btn {
+    width: 100%;
+    font-size: 14px;
+  }
 }
 </style>

+ 13 - 6
src/views/device/doSugar.vue

@@ -16,7 +16,7 @@
             <template #option="{ option }">
               <div class="cascader-item">
                 <van-image :src="option.imgUrl" width="55px" height="55px"></van-image>
-                <div class="cascader-label">{{ option.value }}</div>
+                <div class="cascader-label">{{ option.text }}</div>
               </div>
             </template>
           </van-cascader>
@@ -38,7 +38,7 @@
             <template #option="{ option }">
               <div class="cascader-item">
                 <van-image :src="option.imgUrl" width="55px" height="55px"></van-image>
-                <div class="cascader-label">{{ option.value }}</div>
+                <div class="cascader-label">{{ option.text }}</div>
               </div>
             </template>
           </van-cascader>
@@ -94,7 +94,7 @@ import sHeader from "@/components/SimpleHeader";
 import { useRoute, useRouter } from 'vue-router';
 import {
   getDeviceDetal, selectProducts,
-  doSugar,
+  remoteProduction,
   selectSugarStatus
 } from '@/service/device'
 import { showConfirmDialog, showFailToast, showSuccessToast, showToast } from 'vant';
@@ -114,6 +114,7 @@ export default {
     const cascaderValue = ref('');
     const options = ref([]);
     const activeNames = ref(['1', '2']);
+    const productNo = ref('');
 
     // 果酱数据
     const iceName = ref();
@@ -131,7 +132,8 @@ export default {
     const onFinish = ({ selectedOptions }) => {
       console.log('onFinish', selectedOptions);
       show.value = false;
-      fieldValue.value = selectedOptions[0].value
+      fieldValue.value = selectedOptions[0].text;
+      productNo.value = selectedOptions[0].value;
     }
     const doSugartData = ref(null);
     const doSugartType = ref(true);
@@ -162,7 +164,7 @@ export default {
           options.value = data.data.map(item => {
             return {
               text: item.productName,
-              value: item.productName,
+              value: item.no,
               imgUrl: showSugarPhoto(item.no),
             };
           })
@@ -258,7 +260,12 @@ export default {
         title: t('user.tips'),
         message: t('device.confirmMake')+ fieldValue.value +'?',
       }).then(async() => {
-        const { data } = await doSugar({ equipmentId: deviceId, productName: fieldValue.value, makeCodes: makeCodes.value.join(',') });
+        const { data } = await remoteProduction({ 
+          equipmentId: deviceId, 
+          productName: fieldValue.value, 
+          makeCodes: makeCodes.value.join(','),
+          productNo: productNo.value
+         });
         if (data.code == "00000") {
           doSugartData.value = data.data;
           setTimeout(() => {

文件差異過大導致無法顯示
+ 653 - 374
src/views/device/index.vue


+ 277 - 0
src/views/device/jam/index.vue

@@ -0,0 +1,277 @@
+<template>
+    <div class="payment-settings">
+      <s-header :name="$t('remote.C30')" :noback="false" />
+  
+      <!-- 设备名称标题 -->
+      <div class="device-header">
+        <div class="vertical-indicator"></div>
+        <h3 class="device-name">
+          {{ $t("device.equipmentName") }}:{{ deviceName }}
+        </h3>
+      </div>
+  
+      <!-- 果酱抽取卡片 -->
+      <div class="settings-card">
+        <div v-for="jam in jams" :key="jam.id" class="jam-item">
+          <!-- 图片和名称行 -->
+          <div class="jam-main-row">
+            <van-image
+              :src="showSugerPhoto(jam)"
+              width="70"
+              height="70"
+              radius="8"
+              fit="cover"
+              class="jam-image"
+            />
+            <h3 class="jam-title">{{ jam.name }}</h3>
+          </div>
+          <!-- 操作按钮组 -->
+          <div class="jam-actions">
+            <van-button
+              type="primary"
+              size="small"
+              class="action-btn"
+              @click="handleExtract(jam.no, 1)"
+            >
+              {{ $t("jam.forward") }}
+            </van-button>
+            <van-button
+              type="warning"
+              size="small"
+              class="action-btn"
+              @click="handleExtract(jam.no, 2)"
+            >
+              {{ $t("jam.reverse") }}
+            </van-button>
+            <van-button
+              type="danger"
+              size="small"
+              class="action-btn"
+              @click="handleExtract(jam.no, 0)"
+            >
+              {{ $t("jam.stop") }}
+            </van-button>
+          </div>
+        </div>
+      </div>
+    </div>
+  </template>
+  
+  <script>
+  import sHeader from "@/components/SimpleHeader";
+  import { selectProducts, smokeJam } from "@/service/device/index";
+  import { useRoute } from "vue-router";
+  import { ref } from "vue";
+  import { useI18n } from "vue-i18n";
+  import { onMounted } from "vue";
+  import { showConfirmDialog, showFailToast, showSuccessToast } from "vant";
+  
+  export default {
+    components: { sHeader },
+    setup() {
+      const { t } = useI18n();
+      const route = useRoute();
+      const deviceId = ref(route.query.deviceId);
+      const deviceName = ref(route.query.name);
+      const jams = ref([]);
+  
+      // 获取商品列表
+      const getList = () => {
+        selectProducts({
+          equipmentId: deviceId.value,
+        }).then((res) => {
+          const { data } = res.data;
+          if (data) {
+            data.forEach((item) => {
+              if (item.no.includes("J")) {
+                jams.value.push(item);
+              }
+            });
+          }
+        });
+      };
+  
+      // 商品图片路径处理
+      const showSugerPhoto = (row) => {
+        let imgId = row.no;
+        if (imgId) {
+          return require(`../../../assets/order/spunSugar/goods/${imgId}.png`);
+        }
+        return imgId;
+      };
+  
+      // 果酱抽取
+      const handleExtract = (no, status) => {
+        showConfirmDialog({
+          title: t("device.operationConfirmation"),
+          message: t("device.pleaseConfirmAgainWhetherToOperate"),
+        })
+          .then(async () => {
+            const { data } = await smokeJam({
+              equipmentId: deviceId.value,
+              productNo: no,
+              status: status,
+            });
+            if (data.code === "00000") {
+              showSuccessToast(t("device.Succeed"));
+            } else {
+              showFailToast(t("device.Failed"));
+            }
+          })
+          .catch(() => {
+            // on cancel
+            showFailToast(t("device.Failed"));
+          });
+      };
+  
+      onMounted(async () => {
+        getList();
+      });
+  
+      return {
+        deviceName,
+        showSugerPhoto,
+        handleExtract,
+        jams,
+      };
+    },
+  };
+  </script>
+  
+  <style lang="less" scoped>
+  @primary-color: #4dc294;
+  @warning-color: #ff976a;
+  @danger-color: #ee0a24;
+  .payment-settings {
+    --payment-bg: #ffffff;
+    --border-color: #ebedf0;
+    --active-color: #2c87c8;
+    --text-primary: #323233;
+    --text-secondary: #969799;
+  
+    background: #f7f8fa;
+    min-height: 100vh;
+  
+    .device-header {
+      display: flex;
+      align-items: center;
+      padding: 12px 15px;
+      background: #fff;
+      margin: 12px 16px;
+      border-radius: 8px;
+      box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
+  
+      .vertical-indicator {
+        width: 4px;
+        height: 15px;
+        background: var(--active-color, #2c87c8);
+        border-radius: 2px;
+        margin-right: 10px;
+      }
+  
+      .device-name {
+        margin: 0;
+        font-size: 15px;
+        color: #404d74;
+        font-weight: 550;
+  
+        // 长名称处理
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+        max-width: 70vw;
+      }
+    }
+  
+    .settings-card {
+      padding: 16px;
+      margin: 12px 16px;
+      background: #fff;
+      border-radius: 12px;
+      box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
+    }
+  
+    .jam-item {
+      padding: 16px 0;
+      border-bottom: 1px solid #f5f5f5;
+  
+      &:last-child {
+        border-bottom: none;
+      }
+    }
+  
+    .jam-main-row {
+      display: flex;
+      align-items: center;
+      gap: 16px;
+      margin-bottom: 12px;
+    }
+  
+    .jam-image {
+      border: 1px solid #eee;
+      flex-shrink: 0;
+    }
+  
+    .jam-title {
+      font-size: 16px;
+      color: #333;
+      word-break: break-word;
+      line-height: 1.4;
+    }
+  
+    .jam-actions {
+      display: flex;
+      justify-content: center;
+      gap: 12px;
+      flex-wrap: wrap;
+  
+      .action-btn {
+        min-width: 80px;
+        border-radius: 20px;
+        font-size: 13px;
+        padding: 8px 16px;
+  
+        &--primary {
+          background: @primary-color;
+          border-color: @primary-color;
+        }
+  
+        &--warning {
+          background: @warning-color;
+          border-color: @warning-color;
+        }
+  
+        &--danger {
+          background: @danger-color;
+          border-color: @danger-color;
+        }
+      }
+    }
+  
+    @media (max-width: 480px) {
+      .jam-main-row {
+        gap: 12px;
+      }
+  
+      .jam-image {
+        width: 50px;
+        height: 50px;
+      }
+  
+      .jam-title {
+        font-size: 14px;
+      }
+  
+      .jam-actions {
+        gap: 8px;
+  
+        .action-btn {
+          min-width: 70px;
+          font-size: 12px;
+          padding: 6px 12px;
+        }
+      }
+    }
+  }
+  </style>
+  

+ 271 - 95
src/views/device/showGoods/index.vue

@@ -1,33 +1,65 @@
 <template>
-  <div class="showGoodsIdx">
-    <s-header :name="$t('device.showGoodsPage.title')" :noback="false"></s-header>
-    <div class="headerCon kBordBott o-plr-10 o-ptb-16 l-flex-RC">
-      <div class="line o-mr-6"></div>
-      <div>
-        <span class="c-color c-text-14">{{ $t('device.showGoodsPage.equipmentName') }}:</span>
-        <span class="c-text-color c-text-14">{{ equipmentName }}</span>
+  <div class="goods-management">
+    <!-- 头部优化 -->
+    <s-header
+      :name="$t('device.showGoodsPage.title')"
+      :noback="false"
+      class="management-header"
+    />
+    <div class="content-container">
+      <!-- 设备信息卡片 -->
+      <div class="device-card">
+        <div class="device-info">
+          <h3 class="device-name">
+            <div class="vertical-indicator"></div>
+            {{ $t("device.showGoodsPage.equipmentName") }}:
+            <span class="highlight">{{ equipmentName }}</span>
+          </h3>
+          <div class="goods-count">
+            {{ $t("device.modifyPricePage.total") }}
+            <van-tag color="#2c87c8">{{ tableData.length }}</van-tag>
+            {{ $t("device.modifyPricePage.goods") }}
+          </div>
+        </div>
       </div>
-    </div>
-  </div>
-  <div class="l-flex-between o-m-10">
-    <div>{{ $t('device.modifyPricePage.total') }}{{ tableData.length }}{{ $t('device.modifyPricePage.goods') }}
-    </div>
-  </div>
-  <van-row class="goods o-mlr-8" wrap="true">
-    <van-col v-for="(item, index) in tableData" :key="index" class="goodsCon o-mr-14" span="11">
-      <div class="l-flex-RC">
-        <van-image width="60" height="60" fit="contain" :src="showSugerPhoto(item)" />
-        <span class="o-ml-10" style="word-wrap: break-word; width: 50px;">{{ item.productName }}</span>
-        <van-switch class="o-ml-1" v-model="switchStates[index]" size="20px" active-color="#4dc294"
-          @change="handleChange(index)" />
+
+      <!-- 商品网格布局 -->
+      <div class="goods-grid">
+        <div v-for="(item, index) in tableData" :key="index" class="goods-card">
+          <div class="card-header" v-if="item.no != 'I01'">
+            <van-image
+              class="goods-thumb"
+              fit="cover"
+              :src="showSugerPhoto(item)"
+            />
+            <div class="goods-info">
+              <h4 class="goods-title van-ellipsis">{{ item.productName }}</h4>
+              <van-switch
+                v-model="switchStates[index]"
+                size="24px"
+                active-color="var(--primary-color)"
+                inactive-color="#dcdee0"
+                @change="handleChange(index)"
+              />
+            </div>
+          </div>
+          <van-divider class="card-divider" />
+        </div>
+      </div>
+      <!-- 粘性底栏提交按钮 -->
+      <div class="action-footer">
+        <van-button
+          round
+          block
+          color="#2c87c8"
+          class="submit-btn"
+          @click="updateShowGoods"
+        >
+          <van-icon name="passed" class="btn-icon" />
+          {{ $t("device.submitAndPushDeviceUpdates") }}
+        </van-button>
       </div>
-      <van-divider :style="{ color: '#1baeae', borderColor: '#1baeae', fontSize: '20px', fontWeight: 500 }" />
-    </van-col>
-  </van-row>
-  <div class="l-flex-center" style="margin: 16px">
-    <van-button round block class="Btn" type="primary" native-type="submit" @click="updateShowGoods()">
-      {{ $t('device.submitAndPushDeviceUpdates') }}
-    </van-button>
+    </div>
   </div>
 </template>
 
@@ -35,36 +67,22 @@
 // 导入接口
 import {
   selectProducts,
-  updateProductsShow
-} from '@/service/device/index';
+  updateProductsShow,
+  newUpdateProductsShow,
+} from "@/service/device/index";
 import sHeader from "@/components/SimpleHeader";
-import {
-  ref,
-  reactive
-} from "@vue/reactivity";
-import {
-  onMounted
-} from '@vue/runtime-core';
-import {
-  useRoute,
-  useRouter
-} from 'vue-router';
-import {
-  showFailToast, showDialog, showConfirmDialog
-} from 'vant';
-import {
-  useI18n
-} from "vue-i18n";
-import { styleUrl } from '../../../common/js/utils';
+import { ref, reactive } from "@vue/reactivity";
+import { onMounted } from "@vue/runtime-core";
+import { useRoute, useRouter } from "vue-router";
+import { showFailToast, showDialog, showConfirmDialog } from "vant";
+import { useI18n } from "vue-i18n";
 export default {
   components: {
-    sHeader
+    sHeader,
   },
   setup() {
     // 引入语言
-    const {
-      t
-    } = useI18n();
+    const { t } = useI18n();
     // 商品图片路径处理
     const showSugerPhoto = (row) => {
       let imgId = row.no;
@@ -80,12 +98,11 @@ export default {
     const tableData = ref([]);
     const switchStates = ref([]);
     // 设备名称
-    const equipmentName = ref('');
+    const equipmentName = ref("");
+    const machineType = ref(route.query.machineType || "");
 
     // 刚进页面
     onMounted(() => {
-      // 加载样式
-      styleUrl('showGoods');
       const id = route.query.deviceId || "";
       const name = route.query.name || "";
       if (id) {
@@ -93,77 +110,79 @@ export default {
         equipmentName.value = name;
         getList();
       }
-
     });
     // 获取商品列表
     const getList = () => {
       selectProducts({
-        equipmentId: cofficentForm.equipmentId
-      }).then(res => {
-        console.log('res', res)
-        const {
-          data
-        } = res.data;
+        equipmentId: cofficentForm.equipmentId,
+      }).then((res) => {
+        console.log("res", res);
+        const { data } = res.data;
         if (data) {
           if (data.length > 0) {
             // 是否修改状态
-            data.forEach(item => {
-              if (item.showType == null || item.showType == 0) {
-                switchStates.value.push(true);
-              } else {
-                switchStates.value.push(false);
+            data.forEach((item) => {
+              if (item.no != "I01") {
+                if (item.showType == null || item.showType == 0) {
+                  switchStates.value.push(true);
+                } else {
+                  switchStates.value.push(false);
+                }
               }
-            })
+            });
           }
-          tableData.value = data;
+          data.forEach((item) => {
+            if (item.no != "I01") {
+              tableData.value.push(item);
+            }
+          });
         }
-      })
-    }
+      });
+    };
     // 修改的价格
     const cofficentForm = reactive({
-      equipmentId: '',
+      equipmentId: "",
     });
 
     // 更改状态
     const handleChange = (index) => {
-      // console.log(index);
-      // console.log(switchStates.value[index]);
       if (switchStates.value[index]) {
         tableData.value[index].showType = 0;
       } else {
         tableData.value[index].showType = 1;
       }
-      // console.log(tableData.value[index]);
     };
 
-
     // 点击提交
     const updateShowGoods = () => {
       showConfirmDialog({
-        title: t('device.openRemind'),
-        message: t('device.editCheck'),
+        title: t("device.openRemind"),
+        message: t("device.editCheck"),
       }).then(() => {
         console.log(tableData.value);
         var products = tableData.value;
         var list = JSON.stringify(products);
-        updateProductsShow({
-          productList: list
-        }).then((res) => {
-          console.log(res.data.message);
-          // Toast();
-          showDialog({
-            message: t('device.modificationSucceeded'),
-          }).then(() => {
-            //返回上一页
-            router.go(-1);
+        machineType.value === '2'? newUpdateProductsShow({
+          productList: list,
+        }) : updateProductsShow({
+          productList: list,
+        })
+          .then((res) => {
+            console.log(res.data.message);
+            showDialog({
+              message: t("device.modificationSucceeded"),
+            }).then(() => {
+              //返回上一页
+              router.go(-1);
+            });
+            setTimeout(() => {
+              getList();
+            }, 1000);
+          })
+          .catch((error) => {
+            console.log(error);
+            showFailToast(t("device.unknownError"));
           });
-          setTimeout(() => {
-            getList();
-          }, 1000);
-        }).catch((error) => {
-          console.log(error);
-          showFailToast(t('device.unknownError'));
-        });
       });
     };
     return {
@@ -179,4 +198,161 @@ export default {
 };
 </script>
 
-<style lang="less" scoped></style>
+<style lang="less" scoped>
+.goods-management {
+  --primary-color: #4dc294;
+  --card-radius: 12px;
+  --card-padding: 16px;
+  --grid-gap: 12px;
+
+  background: #f7f8fa;
+
+  .content-container {
+    background: #f7f8fa;
+    height: calc(100% - 50px);
+    overflow: auto;
+    overflow-x: hidden;
+  }
+}
+
+/* 设备信息卡片 */
+.device-card {
+  display: flex;
+  align-items: center;
+  padding: 12px 15px;
+  background: #fff;
+  margin: 15px;
+  border-radius: 8px;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
+}
+
+.device-info {
+  flex: 1;
+}
+
+.device-name {
+  display: flex;
+  align-items: center;
+  font-size: 16px;
+  margin: 0 0 8px;
+  color: #404d74;
+
+  .vertical-indicator {
+    width: 4px;
+    height: 15px;
+    background: var(--active-color, #2c87c8);
+    border-radius: 2px;
+    margin-right: 10px;
+  }
+}
+
+.highlight {
+  font-size: 15px;
+  color: #404d74;
+  font-weight: 500;
+  // 长名称处理
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  max-width: 70vw;
+}
+
+.goods-count {
+  font-size: 14px;
+  color: #888;
+}
+
+/* 商品网格布局 */
+.goods-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
+  gap: var(--grid-gap);
+  padding: 0 16px;
+  margin-bottom: 20px;
+}
+
+.goods-card {
+  background: #fff;
+  border-radius: var(--card-radius);
+  overflow: hidden;
+  transition: transform 0.2s;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
+}
+
+.goods-card:hover {
+  transform: translateY(-2px);
+}
+
+.card-header {
+  display: flex;
+  padding: var(--card-padding);
+}
+
+.goods-thumb {
+  width: 80px;
+  height: 80px;
+  border-radius: 8px;
+  margin-right: 12px;
+}
+
+.goods-info {
+  flex: 1;
+  min-width: 0;
+}
+
+.goods-title {
+  font-size: 15px;
+  margin: 0 0 12px;
+  line-height: 1.4;
+}
+
+.card-divider {
+  margin: 0;
+  border-color: rgba(0, 0, 0, 0.05);
+}
+
+/* 提交按钮 */
+.action-footer {
+  position: sticky;
+  bottom: 0;
+  padding: 16px;
+  background: linear-gradient(to top, #fff 70%, rgba(255, 255, 255, 0.8));
+}
+
+.submit-btn {
+  height: 48px;
+  font-size: 16px;
+  font-weight: 500;
+}
+
+.btn-icon {
+  margin-right: 3px;
+  font-size: 12px;
+}
+
+/* 移动端适配 */
+@media (max-width: 480px) {
+  .goods-grid {
+    grid-template-columns: 1fr;
+  }
+
+  .device-card {
+    margin: 15px;
+    padding: 12px;
+  }
+
+  .goods-thumb {
+    width: 60px;
+    height: 60px;
+  }
+
+  .submit-btn {
+    height: 44px;
+    font-size: 15px;
+  }
+}
+
+:deep(.van-image__img) {
+  object-fit: contain !important;
+}
+</style>

+ 268 - 0
src/views/device/tax/index.vue

@@ -0,0 +1,268 @@
+<template>
+  <div class="payment-settings">
+    <s-header :name="$t('remote.C29')" :noback="false" />
+
+    <!-- 设备名称标题 -->
+    <div class="device-header">
+      <div class="vertical-indicator"></div>
+      <h3 class="device-name">
+        {{ $t("device.equipmentName") }}:{{ deviceName }}
+      </h3>
+    </div>
+
+    <!-- 税收设置卡片 -->
+    <div class="settings-card">
+      <!-- 税费开关 -->
+      <div class="payment-item">
+        <div class="payment-info">
+          <van-icon name="balance-pay" class="payment-icon" />
+          <div class="payment-detail">
+            <h3 class="payment-title">{{ $t("tax.taxFee") }}</h3>
+            <p class="payment-desc">{{ $t("tax.taxFeeDesc") }}</p>
+          </div>
+        </div>
+        <van-switch
+          :model-value="taxStatus"
+          size="22px"
+          @click="handleSubmit"
+        />
+      </div>
+
+      <!-- 税率输入(条件渲染) -->
+      <div v-if="taxStatus" class="tax-rate-input">
+        <van-form @submit="changeTaxRate">
+          <van-field
+            v-model="taxRate"
+            type="number"
+            :label="$t('tax.taxRate')"
+            :placeholder="$t('tax.ratePlaceholder')"
+            :rules="[
+              { required: true, message: $t('tax.rateRequired') },
+              {
+                pattern: /^([0-9]\d?|100)(\.\d{1,2})?$/,
+                message: $t('tax.rateInvalid'),
+              },
+            ]"
+          >
+            <template #right-icon>
+              <span class="percentage-symbol">%</span>
+            </template>
+          </van-field>
+          <van-button
+            type="primary"
+            size="small"
+            class="update-btn"
+            native-type="submit"
+          >
+            {{ $t("tax.update") }}
+          </van-button>
+        </van-form>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import sHeader from "@/components/SimpleHeader";
+import {
+  getDeviceDetal,
+  updateTaxStatus,
+  updateTaxRate,
+} from "@/service/device";
+import { showConfirmDialog, showSuccessToast } from "vant";
+import { useRoute } from "vue-router";
+import { ref } from "vue";
+import { useI18n } from "vue-i18n";
+import { onMounted } from "vue";
+
+export default {
+  components: { sHeader },
+  setup() {
+    const { t } = useI18n();
+    const route = useRoute();
+    const deviceId = ref(route.query.deviceId);
+    const deviceName = ref(route.query.name);
+    const deviceDetal = ref(null);
+
+    const taxStatus = ref(false);
+    const taxRate = ref("");
+
+    onMounted(async () => {
+      await getDeviceInfo();
+    });
+
+    // 获取设备数据
+    const getDeviceInfo = async () => {
+      const { data } = await getDeviceDetal({ id: deviceId.value });
+      if (data.code === "00000") {
+        deviceDetal.value = data.data;
+        if (deviceDetal.value.taxStatus) {
+          taxStatus.value = deviceDetal.value.taxStatus;
+          taxRate.value = deviceDetal.value.taxRate;
+        }
+      }
+    };
+
+    const handleSubmit = () => {
+      showConfirmDialog({
+        title: t("device.operationConfirmation"),
+        message: t("device.pleaseConfirmAgainWhetherToOperate"),
+      })
+        .then(async () => {
+          const { data } = await updateTaxStatus({
+            equipmentId: deviceId.value,
+            taxStatus: !taxStatus.value,
+          });
+          if (data.code === "00000") {
+            taxStatus.value = !taxStatus.value;
+            if (taxStatus.value) {
+              taxRate.value = deviceDetal.value.taxRate;
+            }
+          }
+        })
+        .catch(() => {
+          // on cancel
+        });
+    };
+
+    const changeTaxRate = async () => {
+      showConfirmDialog({
+        title: t("device.operationConfirmation"),
+        message: t("device.pleaseConfirmAgainWhetherToOperate"),
+      })
+        .then(async () => {
+          const { data } = await updateTaxRate({
+            equipmentId: deviceId.value,
+            taxRate: taxRate.value,
+          });
+          if (data.code === "00000") {
+            showSuccessToast(t("device.modificationSucceeded"));
+          }
+        })
+        .catch(() => {
+          // on cancel
+        });
+    };
+
+    return {
+      deviceName,
+      taxStatus,
+      taxRate,
+      handleSubmit,
+      changeTaxRate,
+    };
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.payment-settings {
+  --payment-bg: #ffffff;
+  --border-color: #ebedf0;
+  --active-color: #2c87c8;
+  --text-primary: #323233;
+  --text-secondary: #969799;
+
+  background: #f7f8fa;
+  min-height: 100vh;
+
+  .device-header {
+    display: flex;
+    align-items: center;
+    padding: 12px 15px;
+    background: #fff;
+    margin: 12px 16px;
+    border-radius: 8px;
+    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
+
+    .vertical-indicator {
+      width: 4px;
+      height: 15px;
+      background: var(--active-color, #2c87c8);
+      border-radius: 2px;
+      margin-right: 10px;
+    }
+
+    .device-name {
+      margin: 0;
+      font-size: 15px;
+      color: #404d74;
+      font-weight: 550;
+
+      // 长名称处理
+      overflow: hidden;
+      text-overflow: ellipsis;
+      white-space: nowrap;
+      max-width: 70vw;
+    }
+  }
+
+  .settings-card {
+    background: #fff;
+    border-radius: 12px;
+    margin: 12px 16px;
+    padding: 16px;
+    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
+  }
+
+  .payment-item {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+  }
+
+  .payment-info {
+    display: flex;
+    align-items: center;
+  }
+
+  .payment-icon {
+    font-size: 24px;
+    color: #4dc294;
+    margin-right: 12px;
+  }
+
+  .payment-title {
+    font-size: 15px;
+    color: #333;
+    margin-bottom: 4px;
+  }
+
+  .payment-desc {
+    font-size: 12px;
+    color: #666;
+  }
+
+  .tax-rate-input {
+    margin-top: 16px;
+    padding-top: 16px;
+    border-top: 1px solid #eee;
+  }
+
+  .percentage-symbol {
+    color: #999;
+    padding-left: 4px;
+  }
+
+  .update-btn {
+    margin-top: 12px;
+    width: 120px;
+    border-radius: 18px;
+  }
+
+  /* 移动端适配 */
+  @media (max-width: 480px) {
+    .device-name {
+      font-size: 15px;
+    }
+
+    .payment-title {
+      font-size: 14px;
+    }
+
+    .tax-rate-input {
+      margin-top: 12px;
+    }
+  }
+}
+</style>

文件差異過大導致無法顯示
+ 818 - 745
src/views/device/toDaySugarList.vue


+ 483 - 144
src/views/home/index.vue

@@ -1,123 +1,165 @@
 <template>
-  <!-- 主页 -->
-  <div class="homePage flex-col">
-    <div class="homeBox">
-      <s-header :name="sys ? sys.title : $t('public.sysName')" :noback="true" :isFixed="false"></s-header>
-      <!-- 留言滚动条 -->
-      <template v-if="noticeContent.title">
-        <van-notice-bar @click="noticeClk" mode="link" :scrollable="true" color="rgba(64,77,116,1)" background="#fff"
-          left-icon="volume-o" :text="noticeContent.title" />
-      </template>
-      <div class="intervalRow"></div>
-      <div class="nameDeviceRow flex-col">
-        <span class="txt3">{{ userName }}</span>
-        <div class="l-flex-RC">
-          <span class="info3" style="color: #2c87c8;">
-            {{ $t("home.totalEquipment") }} : {{ equipStatus.machineTotalNum }}
-          </span>
-          <div class="lineCon o-mlr-6"></div>
-          <span class="word2" style="color: #07c160;">
-            {{ $t("home.running") }} : {{ equipStatus.machineUseNum }}
-          </span>
+  <div class="home-container">
+    <!-- 头部 -->
+    <s-header
+      :name="sys ? sys.title : $t('public.sysName')"
+      :noback="true"
+      :isFixed="false"
+      class="app-header"
+    />
+    <!-- 主体内容 -->
+    <main class="main-content">
+      <!-- 通知栏 -->
+      <van-notice-bar
+        v-if="noticeContent.title"
+        class="smart-notice"
+        left-icon="volume-o"
+        :text="noticeContent.title"
+        @click="noticeClk"
+        :scrollable="true"
+        color="#404B74"
+        background="#ffffff"
+      />
+
+      <!-- 用户信息卡 -->
+      <div class="user-card">
+        <div class="user-info">
+          <div class="avatar">
+            <van-icon name="user-circle-o" size="48px" color="#2c87c8" />
+          </div>
+          <div class="user-meta">
+            <h3 class="user-name">{{ userName }}</h3>
+            <div class="device-status">
+              <span class="status-item total">
+                <van-icon name="desktop-o" size="14px" />
+                {{ $t("home.totalEquipment") }}:
+                {{ equipStatus.machineTotalNum }}
+              </span>
+              <span class="status-item running">
+                <van-icon name="desktop-o" size="14px" />
+                {{ $t("home.running") }}: {{ equipStatus.machineUseNum }}
+              </span>
+            </div>
+          </div>
         </div>
       </div>
-      <!-- 没有数据概览M14权限的人看不到数据概览和ECharts -->
+
+      <dateSelectList
+        v-if="showDataDiv"
+        @update="update($event)"
+      ></dateSelectList>
+      <typeDownMenu
+        v-if="showDataDiv"
+        :isHome="true"
+        @upselectdata="upselectdata($event)"
+      ></typeDownMenu>
       <!-- 数据概览 -->
-      <div v-if="showDataDiv" class="titleBox flex-col">
-        <div class="layer2 l-flex-RC">
-          <div class="section5 flex-col"></div>
-          <div class="TextGroup2 flex-col">
-            <span class="txt4">{{ $t("home.dataOverview") }}</span>
+      <section v-if="showDataDiv" class="data-section">
+        <div class="section-header">
+          <div class="header-main">
+            <h3 class="section-title">
+              {{ $t("home.dataOverview") }}
+            </h3>
+            <div class="data-entry" @click="pushOrderCenter">
+              <span>{{ $t("home.orderData") }}</span>
+              <van-icon name="arrow" class="entry-arrow" />
+            </div>
           </div>
         </div>
-      </div>
-      <!-- 时间选择 -->
-      <dateSelectList v-if="showDataDiv" @update="update($event)"></dateSelectList>
-      <typeDownMenu v-if="showDataDiv" :isHome="true" @upselectdata="upselectdata($event)"></typeDownMenu>
-      <!-- 订单数据 -->
-      <div v-if="showDataDiv" class="o-plr-8 o-pt-10">
-        <div class="outer5 flex-col" @click="pushOrderCenter">
-          <div class="block5 flex-col">
-            <div v-if="isOrderData" class="topTitle flex-row justify-end">
-              <span class="txt10">{{ $t("home.orderData") }}</span>
-              <div class="layer4 flex-col"></div>
-            </div>
-            <div class="outerBox flex-row">
-              <div class="main4 flex-col justify-between">
-                <div class="main5 flex-row justify-center">
-                  <!-- <span class="word8">&yen;</span> -->
-                  <span class="word8">{{ currencySymbol }}</span>
-                  <span class="word9">{{ salesVolume.toFixed(2) }}</span>
-                </div>
-                <span class="info5">{{ $t("home.totalIncome") }}</span>
-              </div>
-              <div class="TextGroup7 flex-col">
-                <div class="mod3 flex-col justify-between">
-                  <span class="txt8">{{ salesNumber }}</span>
-                  <span class="info6">{{ $t("home.productNum") }}</span>
-                </div>
-              </div>
-              <div class="TextGroup8 flex-col">
-                <div class="outer6 flex-col justify-between">
-                  <span class="txt9">{{ orderNumber }}</span>
-                  <span class="word10">{{ $t("home.numberOfOrders") }}</span>
+
+        <!-- 数据卡片 -->
+        <div class="data-cards">
+          <div class="data-card income">
+            <div class="card-content">
+              <div class="card-text">
+                <div class="value">
+                  {{ currencySymbol }}{{ salesVolume.toFixed(2) }}
                 </div>
+                <div class="label">{{ $t("home.totalIncome") }}</div>
               </div>
             </div>
           </div>
-        </div>
-      </div>
-      <!-- 时间 -->
-      <div v-if="showDataDiv" class="c-text-c" style="font-size: 18px; margin-top: 5px;">
-        {{ Format_time(dateSelect.startDate, 'YYYY/MM/DD') }}-{{ Format_time(dateSelect.endDate, 'YYYY/MM/DD') }}
-      </div>
-      <!-- ECharts
-      <template v-if="showDataDiv && !noData(salesVolume, salesNumber)">
-        <div ref="chartBox" class="Chart1 flex-col"></div>
-      </template>
-      <template v-else>
-        <kNoData v-if="showDataDiv"></kNoData>
-      </template> -->
-      <!-- <div> -->
-      <div v-if="showDataDiv && !noData(salesVolume, salesNumber)">
-        <div ref="chartBox" class="Chart1 flex-col"></div>
-      </div>
-      <kNoData v-else></kNoData>
-      <!-- </div> -->
-      <!-- 常用工具 -->
-      <div class="outer9 flex-col justify-center">
-        <div class="main24 flex-col justify-between">
-          <div class="ImageText10 flex-col">
-            <div class="wrap2 flex-row justify-between">
-              <div class="outer10 flex-col"></div>
-              <div class="TextGroup13 flex-col">
-                <span class="txt13">{{ $t("home.commonTools") }}</span>
+
+          <div class="data-card sales">
+            <div class="card-content">
+              <div class="card-text">
+                <div class="value">{{ salesNumber }}</div>
+                <div class="label">{{ $t("home.productNum") }}</div>
               </div>
             </div>
           </div>
         </div>
-      </div>
-      <div class="outer11 flex-row">
-        <div class="main25 flex-col" v-for="(item, index) in pushToolList" :key="index" @click="pushToolPage(item)">
-          <img class="mod7 flex-col" :src="showLogo(item)" />
-          <div class="TextGroup14 flex-col">
-            <span class="info15">{{ $t("permission." + item) }}</span>
-          </div>
+
+        <div
+          v-if="showDataDiv"
+          class="c-text-c"
+          style="font-size: 18px; margin-top: 5px"
+        >
+          {{ Format_time(dateSelect.startDate, "YYYY/MM/DD") }}-{{
+            Format_time(dateSelect.endDate, "YYYY/MM/DD")
+          }}
         </div>
-      </div>
-    </div>
+
+        <!-- 图表 -->
+        <div class="chart-container">
+          <div
+            v-if="!noData(salesVolume, salesNumber)"
+            ref="chartBox"
+            class="sales-chart"
+          ></div>
+          <k-no-data v-else />
+        </div>
+      </section>
+
+      <!-- 常用工具 -->
+      <section class="tools-section">
+        <h3 class="section-title">{{ $t("home.commonTools") }}</h3>
+        <van-row :gutter="12">
+          <van-col v-for="(item, index) in pushToolList" :key="index" span="8">
+            <div class="tool-item" @click="pushToolPage(item)">
+              <img class="tool-icon" :src="showLogo(item)" />
+              <span class="tool-name">{{ $t("permission." + item) }}</span>
+            </div>
+          </van-col>
+        </van-row>
+      </section>
+    </main>
+
     <!-- 通知弹窗 -->
-    <kDialog :dialogTitle="$t('home.notificationPop.notification')" :cancelBtnTxt="$t('home.notificationPop.nextTime')"
-      :confirmBtnTxt="$t('home.notificationPop.roger')" ref="kDialogRef" @confirmclk="confirmClk">
+    <kDialog
+      :dialogTitle="$t('home.notificationPop.notification')"
+      :cancelBtnTxt="$t('home.notificationPop.nextTime')"
+      :confirmBtnTxt="$t('home.notificationPop.roger')"
+      ref="kDialogRef"
+      @confirmclk="confirmClk"
+    >
       <template #content>
-        <div class="o-w" style="max-height: 50vh; overflow-y: auto" v-html="noticeContent.note"></div>
+        <div
+          class="o-w"
+          style="max-height: 50vh; overflow-y: auto"
+          v-html="noticeContent.note"
+        ></div>
       </template>
     </kDialog>
-    <van-dialog v-model:show="showAlarm" :title="$t('home.alarmTitle')" @confirm="confirmAlarm">
-      <div style="max-height: 30vh; overflow-y: auto;">
-        <div v-for="(item, index) in alarmList" :key="index" style="padding: 2px 5px;">
+    <van-dialog
+      v-model:show="showAlarm"
+      :title="$t('home.alarmTitle')"
+      @confirm="confirmAlarm"
+    >
+      <div style="max-height: 30vh; overflow-y: auto">
+        <div
+          v-for="(item, index) in alarmList"
+          :key="index"
+          style="padding: 2px 5px"
+        >
           <van-cell
-            :title="$t('home.alarmDevice') + (item.name ? item.name : item.clientId.slice(-6)) + $t('home.alarmContent') + item.alarmContent" />
+            :title="
+              $t('home.alarmDevice') +
+              (item.name ? item.name : item.clientId.slice(-6)) +
+              $t('home.alarmContent') +
+              item.alarmContent
+            "
+          />
         </div>
       </div>
     </van-dialog>
@@ -132,7 +174,7 @@ import { onMounted, ref, nextTick } from "vue";
 import sHeader from "../../components/SimpleHeader";
 import dateSelectList from "../../components/dateSelectList";
 import typeDownMenu from "../../components/typeDownMenu";
-import { getLoginUser, Format_time, styleUrl, getLocal, setLocal, navigatorLanguage } from "../../common/js/utils";
+import { getLoginUser, Format_time } from "../../common/js/utils";
 import { useRouter } from "vue-router";
 import {
   getStatistics,
@@ -145,6 +187,7 @@ import { getAdminRole } from "@/service/user";
 import dateUtil from "../../utils/dateUtil";
 import { useI18n } from "vue-i18n";
 import { showToast } from "vant";
+import { getLocal, setLocal, navigatorLanguage } from "@/common/js/utils";
 
 export default {
   name: "home",
@@ -161,7 +204,6 @@ export default {
     // 获取设备情况
     const getMachineNum = () => {
       Api_postMachineNum({ adminId: user.id }).then((res) => {
-        // console.log("res", res);
         equipStatus.value = res.data.data || {};
       });
     };
@@ -169,7 +211,6 @@ export default {
     // 获取公告
     const getNotice = () => {
       Api_getNotice({ adminId: user.id }).then((res) => {
-        // console.log("res", res);
         noticeContent.value = res.data.data || {};
       });
     };
@@ -181,12 +222,10 @@ export default {
       kDialogRef.value.openDialog();
     };
     // 点击右侧按钮
-    const confirmClk = (e) => {
-      console.log(e, 2222);
+    const confirmClk = () => {
       Api_getUpdateNotice({
         adminId: user.id,
       }).then((res) => {
-        // console.log("res", res);
         showToast(res.data.message);
         setTimeout(() => {
           getNotice();
@@ -198,8 +237,7 @@ export default {
     const router = useRouter();
     const userName = ref(user.name);
     const sys = ref(null);
-    const sysTitle = ref('');
-
+    const sysTitle = ref("");
     // 自定义货币符号
     const currencySymbol = ref("¥");
     if (user.currencySymbol) {
@@ -213,9 +251,7 @@ export default {
     let chartObj = null;
     // 跳转订单中心
     const pushOrderCenter = () => {
-      if (isOrderData.value) {
-        router.push({ path: "/orderCenter" });
-      }
+      router.push({ path: "/orderCenter" });
     };
     const dateSelect = ref({});
     const update = (uDate) => {
@@ -234,8 +270,12 @@ export default {
     const getStatisticsFun = async () => {
       const params = {
         ...dateSelect.value,
-        adminId: typeSelectData.adminId === null ? user.id : typeSelectData.adminId,
-        ifForeign: typeSelectData.ifForeign === '' ? user.ifForeign : typeSelectData.ifForeign,
+        adminId:
+          typeSelectData.adminId === null ? user.id : typeSelectData.adminId,
+        ifForeign:
+          typeSelectData.ifForeign === ""
+            ? user.ifForeign
+            : typeSelectData.ifForeign,
         payType: typeSelectData.payType,
         clientId: typeSelectData.clientId,
         username: typeSelectData.userName, // 商家
@@ -280,7 +320,7 @@ export default {
           if (item == "周日") {
             data.data.categories[index] = t("home.week.sun");
           }
-        })
+        });
         // 解决eacharts与v-if的渲染问题
         await nextTick();
         if (chartBox.value) {
@@ -296,10 +336,12 @@ export default {
               },
             },
             grid: {
+              top: "10%",
               left: "3%",
               right: "4%",
               bottom: "10%",
               containLabel: true,
+              height: "auto",
             },
             legend: {
               bottom: 0,
@@ -325,15 +367,15 @@ export default {
                 type: "inside",
                 xAxisIndex: 0,
                 filterMode: "none",
-                startValue: null,
-                endValue: null,
+                startValue: 0,
+                endValue: 50,
                 zoomLock: true,
               },
             ],
             xAxis: {
               type: "category",
               axisLabel: {
-                rotate: 45,
+                rotate: 35,
               },
               data: data.data.categories,
             },
@@ -344,7 +386,7 @@ export default {
               {
                 ...data.data.series[0],
                 type: "bar",
-                itemStyle: { color: "#ddae27" },
+                itemStyle: { color: "#f6d258" },
                 name: t("home.productNum"),
                 label: {
                   show: true,
@@ -365,9 +407,13 @@ export default {
           };
 
           option.dataZoom[0]["startValue"] =
-            data.data.categories[data.data.categories.length - 5];
+            data.data.categories[data.data.categories.length - 4];
           option.dataZoom[0]["endValue"] =
             data.data.categories[data.data.categories.length - 1];
+          // option.dataZoom[0].start =
+          //   (data.data.categories.length - 5) * 10;
+          // option.dataZoom[0].end =
+          //   (data.data.categories.length - 1) * 10;
           chartObj && chartObj.setOption(option);
           //图形宽度随屏幕宽度改变而改变
           window.onresize = chartObj.resize;
@@ -381,7 +427,6 @@ export default {
     // 页面初始化
     onMounted(async () => {
       // 加载样式
-      styleUrl('home');
       // 检测语言是否有缓存
       if (!getLocal("curLang")) {
         //  根据浏览器语言重新缓存到localstorage
@@ -391,7 +436,7 @@ export default {
         const loginSysString = localStorage.getItem("loginSys");
         sys.value = JSON.parse(loginSysString);
       }
-      firstLogin.value = localStorage.getItem('firstLogin');
+      firstLogin.value = localStorage.getItem("firstLogin");
       // 设置菜单权限
       // menuSet();
       // 设置菜单权限, 只执行一次
@@ -427,7 +472,7 @@ export default {
         };
         const { data } = await getIsAlarm(queryParams);
         if (data.data != null) {
-          if (firstLogin.value == 'true') {
+          if (firstLogin.value == "true") {
             showAlarm.value = true;
           }
           alarmList.value = data.data;
@@ -436,22 +481,21 @@ export default {
       getDomainFunc();
     });
 
-
     const getDomainFunc = async () => {
       const currentDomain = window.location.href;
       console.log("href >>>", currentDomain);
       switch (true) {
-        case currentDomain.includes('sskj.qxfoodom'):  // 食神科技 sskj.qxfoodom.com
-          sysTitle.value = '食神科技';
+        case currentDomain.includes("sskj.qxfoodom"): // 食神科技 sskj.qxfoodom.com
+          sysTitle.value = "食神科技";
           break;
         default:
-          sysTitle.value = t('public.sysName');
+          sysTitle.value = t("public.sysName");
       }
-    }
+    };
 
     const confirmAlarm = () => {
-      localStorage.setItem('firstLogin', false);
-    }
+      localStorage.setItem("firstLogin", false);
+    };
 
     const menuList = [];
 
@@ -462,7 +506,7 @@ export default {
     // 获取账号权限
     const getAccountPer = async () => {
       const { data } = await getAdminRole({ adminId: user.id });
-      if (data.code === '00000') {
+      if (data.code === "00000") {
         if (data.data.menuCodesJson !== null) {
           menuList.value = sortedArray(data.data.menuCodesJson);
         }
@@ -498,32 +542,30 @@ export default {
           }
         });
       }
-    }
+    };
 
     // 解析 + 排序计算属性
     const sortedArray = (value) => {
       try {
         // 1. 安全解析JSON
-        const parsed = JSON.parse(value)
-        if (!Array.isArray(parsed)) return []
+        const parsed = JSON.parse(value);
+        if (!Array.isArray(parsed)) return [];
 
         // 2. 自定义排序函数
-        const getNumber = str => parseInt(str.match(/\d+/)?.[0] || 0)
+        const getNumber = (str) => parseInt(str.match(/\d+/)?.[0] || 0);
 
         // 3. 执行排序(数字从小到大)
         return [...parsed].sort((a, b) => {
-          return getNumber(a) - getNumber(b)
-        })
-
+          return getNumber(a) - getNumber(b);
+        });
       } catch (error) {
-        console.error('解析失败:', error)
-        return []
+        console.error("解析失败:", error);
+        return [];
       }
     };
 
     // 常用操作跳转页面
     const pushToolPage = (index) => {
-      // console.log("常用操作跳转页面menuList >>> " + menuList);
       switch (index) {
         case "M1":
           router.push({ path: "/device" }); // 设备管理
@@ -549,6 +591,9 @@ export default {
         case "M9":
           router.push({ path: "/orderExport" });
           break;
+        case "M10":
+          router.push({ path: "/subLedgerManage" });
+          break;
         case "M11":
           router.push({ path: "/robotranking" });
           break;
@@ -573,7 +618,6 @@ export default {
       }
     };
 
-
     // 如果是空数据
     const noData = (volumes, nums) => {
       if (!volumes && !nums) {
@@ -587,6 +631,7 @@ export default {
     };
 
     return {
+      user,
       userName,
       update,
       upselectdata,
@@ -608,7 +653,6 @@ export default {
       dateSelect,
       Format_time,
       showDataDiv,
-      isOrderData,
       currencySymbol,
       showAlarm,
       alarmList,
@@ -616,10 +660,305 @@ export default {
       sysTitle,
     };
   },
-
 };
 </script>
 
 <style lang="less" scoped>
 @import "../../common/style/common";
-</style>
+
+.home-container {
+  --primary-color: #2c87c8;
+  --secondary-color: #07c160;
+  --text-primary: #2d354d;
+  --text-secondary: #666f8c;
+  --background: #f5f7fa;
+  --card-radius: 12px;
+  --shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
+  --tabbar-height: 40px;
+  --tabbar-padding: calc(var(--tabbar-height) + 20px);
+
+  background: var(--background);
+  min-height: 100vh;
+
+  .app-header {
+    box-shadow: var(--shadow);
+  }
+
+  .main-content {
+    background-color: #f5f7fa;
+    height: calc(100% - 95px);
+    overflow: auto;
+    overflow-x: hidden;
+  }
+
+  .smart-notice {
+    border-radius: 8px;
+    font-weight: 600;
+  }
+
+  .user-card {
+    background: white;
+    border-radius: var(--card-radius);
+    padding: 16px;
+    margin-bottom: 20px;
+    margin: 10px;
+    box-shadow: var(--shadow);
+
+    .user-info {
+      display: flex;
+      align-items: center;
+      gap: 12px;
+
+      .user-meta {
+        flex: 1;
+
+        .user-name {
+          margin: 0 0 4px;
+          font-size: 18px;
+          color: var(--text-primary);
+        }
+
+        .device-status {
+          display: flex;
+          gap: 16px;
+          font-size: 13px;
+
+          .status-item {
+            display: flex;
+            align-items: center;
+            gap: 6px;
+            padding: 4px 8px;
+            border-radius: 16px;
+            background: #f5f7fa;
+
+            &.total {
+              color: var(--primary-color);
+              background: rgba(77, 106, 221, 0.1);
+            }
+
+            &.running {
+              color: var(--secondary-color);
+              background: rgba(7, 193, 96, 0.1);
+            }
+          }
+        }
+      }
+    }
+  }
+
+  .data-section {
+    background: white;
+    border-radius: var(--card-radius);
+    padding: 16px;
+    margin: 10px;
+    box-shadow: var(--shadow);
+
+    .section-header {
+      .header-main {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        margin-bottom: 12px;
+
+        .section-title {
+          position: relative;
+          margin: 0;
+          font-size: 16px;
+          color: var(--text-primary);
+          display: flex;
+          align-items: center;
+
+          .title-arrow {
+            margin-left: 6px;
+            font-size: 14px;
+            transition: transform 0.2s;
+          }
+
+          &:hover .title-arrow {
+            transform: translateX(2px);
+          }
+        }
+
+        .data-entry {
+          display: flex;
+          align-items: center;
+          color: var(--primary-color);
+          font-size: 13px;
+          cursor: pointer;
+          transition: all 0.2s;
+          padding: 4px 8px;
+          border-radius: 16px;
+          background: rgba(77, 106, 221, 0.05);
+
+          .entry-arrow {
+            margin-left: 4px;
+            font-size: 12px;
+            transition: transform 0.2s;
+          }
+        }
+      }
+    }
+
+    .data-cards {
+      display: grid;
+      grid-template-columns: repeat(2, 1fr);
+      gap: 12px;
+      margin-bottom: 20px;
+
+      .data-card {
+        padding: 15px;
+        border-radius: 8px;
+
+        &.income {
+          background: linear-gradient(
+            135deg,
+            var(--primary-color) 0%,
+            #5ebcff 100%
+          );
+          color: white;
+        }
+
+        &.sales {
+          background: linear-gradient(135deg, #ebc611 0%, #fce15b 100%);
+          color: white;
+        }
+
+        .card-content {
+          display: flex;
+          align-items: center;
+
+          .card-text {
+            .value {
+              font-size: 18px;
+              font-weight: 600;
+              line-height: 1.2;
+            }
+
+            .label {
+              font-size: 13px;
+              opacity: 0.9;
+            }
+          }
+        }
+      }
+    }
+
+    .chart-container {
+      height: 300px;
+      background: white;
+      border-radius: 8px;
+
+      .sales-chart {
+        height: 270px;
+        width: 100%;
+      }
+    }
+  }
+
+  .tools-section {
+    padding: 10px 16px;
+    background: #fff;
+    border-radius: var(--card-radius);
+    margin: 10px;
+    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
+
+    .section-title {
+      font-size: 16px;
+      color: #333;
+      // margin-bottom: 16px;
+    }
+
+    .tool-item {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      padding: 12px;
+      margin-bottom: 12px;
+      border-radius: 8px;
+      transition: all 0.2s;
+
+      &:active {
+        background: #f1f3f5;
+        transform: scale(0.98);
+      }
+
+      .tool-icon {
+        width: 48px;
+        height: 48px;
+        margin-bottom: 8px;
+        border-radius: 8px;
+      }
+
+      .tool-name {
+        font-size: 12px;
+        color: #666;
+        text-align: center;
+        line-height: 1.4;
+        display: -webkit-box;
+        -webkit-line-clamp: 2;
+        -webkit-box-orient: vertical;
+        overflow: hidden;
+      }
+    }
+
+    // 处理最后一行的边距
+    :deep(.van-row) {
+      margin-bottom: -12px;
+
+      .van-col {
+        margin-bottom: 12px;
+      }
+    }
+  }
+
+  .machine-sales {
+    margin: 10px;
+
+    .sales-list {
+      display: grid;
+      gap: 12px;
+
+      .sales-item {
+        background: white;
+        border-radius: var(--card-radius);
+        overflow: hidden;
+        box-shadow: var(--shadow);
+
+        .machine-header {
+          padding: 12px 16px;
+          font-weight: 500;
+          color: var(--text-primary);
+          border-bottom: 1px solid #eee;
+          display: flex;
+          align-items: center;
+
+          .machine-icon {
+            margin-right: 8px;
+            font-size: 18px;
+            color: var(--primary-color);
+          }
+        }
+
+        .sale-cell {
+          &:deep(.van-cell__title) {
+            flex: none;
+            width: 100px;
+          }
+
+          &:deep(.van-cell__value) {
+            color: var(--text-primary);
+            font-weight: 500;
+          }
+        }
+
+        .total-cell {
+          &:deep(.van-cell__value) {
+            color: var(--primary-color);
+            font-weight: 600;
+          }
+        }
+      }
+    }
+  }
+}
+</style>

文件差異過大導致無法顯示
+ 1040 - 349
src/views/orderCenter/index.vue


+ 2 - 2
src/views/orderCenter/orderSearch.vue

@@ -18,7 +18,7 @@
           <van-row justify="space-around" style="padding: 2em;">
             <van-button class="clearBtn" span="5" round plain type="primary" style="height: 2em; padding: 0 2em;"
               @click="registerClick">{{ $t('device.emptyingConditions') }}</van-button>
-            <van-button span="5" round type="primary" style="height: 2em; padding: 0 2em;" native-type="submit">
+            <van-button span="5" round color="#2c87c8" style="height: 2em; padding: 0 2em;" native-type="submit">
               {{ $t('orderCenter.clickSearch') }}
             </van-button>
           </van-row>
@@ -33,7 +33,7 @@
       <van-date-picker v-model="endDateValue" :title="$t('orderCenter.selectFullTime')"
         @confirm="endDateConFirm($event)" @cancel="endDateCancel()" :min-date="minDate" :max-date="maxDate" />
     </van-popup>
-    <van-calendar color="#4d6add" v-model:show="showOrderDate" @confirm="calendarConfirm" type="range"
+    <van-calendar color="#2c87c8" v-model:show="showOrderDate" @confirm="calendarConfirm" type="range"
       :allow-same-day="true" :min-date="minDate" :max-date="maxDate" :max-range="31" />
   </div>
 </template>

+ 405 - 142
src/views/robotRanking.vue

@@ -1,100 +1,129 @@
 <template>
-  <div class="robotRanking flex-col" v-if="showRobotRankingDiv">
-    <div class="box1 flex-col">
-      <s-header :name="$t('robotRanking.machineSalesRanking')" :noback="true" :isFixed="false"></s-header>
-      <div class="box3 flex-col">
-        <div class="main1 flex-col">
-          <div class="mod1 flex-col">
-            <div class="section1 flex-row justify-between">
-              <div class="ImageText1 flex-col">
-                <div class="group4 flex-row justify-between">
-                  <div class="layer3 flex-col"></div>
-                  <span class="word3 flex-col">
-                    {{ $t("robotRanking.machineSalesRanking") }}
-                  </span>
-                </div>
-              </div>
-              <div class="flex-col">
-                <div @click="noticeClk" class="main5 flex-row justify-between">
-                  <img class="label2" src="@/assets/device/searchIcon.png" />
-                </div>
-              </div>
-            </div>
-          </div>
-          <img class="img1" referrerpolicy="no-referrer" src="../assets/line.png" />
-          <div class="l-f l-flex-e o-plr-15">
-            <span class="robotLabelName l-in c-text-13" style="color: #404d74">{{ $t("robotRanking.dailySalesRanking")
-            }}:</span>
-            <kTabs @tabclk="(e) => tabclk(e, 'day')" :tabList="tabDayList"></kTabs>
+  <div class="robotRanking">
+    <!-- 头部 -->
+    <s-header
+      :name="$t('robotRanking.machineSalesRanking')"
+      :noback="true"
+      class="modern-header"
+    />
+    <div class="sales-rank-view">
+      <!-- 主体内容 -->
+      <main class="rank-container">
+        <!-- 筛选栏 -->
+        <div class="filter-card">
+          <div class="card-header">
+            <h3 class="card-title">
+              <span class="title-accent"></span>
+              {{ $t("robotRanking.machineSalesRanking") }}
+            </h3>
+            <van-icon name="filter-o" class="filter-icon" @click="noticeClk" />
           </div>
-          <div v-if="!totalNoData('day')" ref="dayChartBox" class="mod3 flex-col"></div>
-          <kNoData v-else></kNoData>
-          <div class="groove"></div>
-          <div class="l-f l-flex-e o-plr-15">
-            <span class="robotLabelName l-in o-mr-6 c-text-13" style="color: #404d74">{{
-              $t("robotRanking.salesRankingThisWeek") }}:</span>
-            <kTabs @tabclk="(e) => tabclk(e, 'week')" :tabList="tabWeekList"></kTabs>
-          </div>
-          <div v-if="!totalNoData('week')" ref="weekChartBox" class="mod5 flex-col"></div>
-          <kNoData v-else></kNoData>
-          <div class="groove"></div>
-          <div class="l-f l-flex-e o-plr-15">
-            <span class="robotLabelName l-in o-mr-6 c-text-13" style="color: #404d74">{{
-              $t("robotRanking.salesRankingThisMonth") }}:</span>
-            <kTabs @tabclk="(e) => tabclk(e, 'month')" :tabList="tabMonthList"></kTabs>
+        </div>
+
+        <!-- 时间维度卡片 -->
+        <div
+          v-for="(period, index) in timePeriods"
+          :key="index"
+          class="rank-card"
+        >
+          <div class="period-header">
+            <h3 class="period-title">
+              <span class="period-icon"></span>
+              {{ $t(`robotRanking.${period.titleKey}`) }}
+            </h3>
+            <kTabs
+              :tabList="period.tabList"
+              @tabclk="(e) => tabclk(e, period.type)"
+              class="type-tabs"
+            />
           </div>
-          <div v-if="!totalNoData('month')" ref="monthChartBox" class="mod9 flex-col"></div>
-          <kNoData v-else></kNoData>
-          <div class="groove"></div>
-          <div class="l-f l-flex-e o-plr-15">
-            <span class="robotLabelName l-in o-mr-6 c-text-13" style="color: #404d74">{{
-              $t("robotRanking.salesRankingThisYear") }}:</span>
-            <kTabs @tabclk="(e) => tabclk(e, 'year')" :tabList="tabYearList"></kTabs>
+
+          <div class="chart-wrapper">
+            <div
+              v-if="!totalNoData(period.type)"
+              :ref="(el) => setChartRef(el, period.type)"
+              class="chart-box"
+            ></div>
+            <kNoData v-else class="no-data-tip" />
           </div>
-          <div v-if="!totalNoData('year')" ref="yearChartBox" class="mod11 flex-col"></div>
-          <kNoData v-else></kNoData>
-          <div class="groove"></div>
         </div>
-      </div>
+      </main>
     </div>
     <!-- 筛选弹窗 -->
-    <kDialog :dialogTitle="$t('orderExport.searchPop.title')" :confirmBtnTxt="$t('orderExport.searchPop.filter')"
-      ref="kDialogRef" @confirmclk="confirmClk">
+    <kDialog
+      :dialogTitle="$t('orderExport.searchPop.title')"
+      :confirmBtnTxt="$t('orderExport.searchPop.filter')"
+      ref="kDialogRef"
+      @confirmclk="confirmClk"
+    >
       <template #content>
         <div class="cust_vantBorder">
-          <van-field @click-input="changeTypeInpClk" readonly clearable v-model="searchForm.changeTypeName"
-            :placeholder="$t('robotRanking.changeTypePlace')" :label="$t('robotRanking.changeType')">
+          <van-field
+            @click-input="changeTypeInpClk"
+            readonly
+            clearable
+            v-model="searchForm.changeTypeName"
+            :placeholder="$t('robotRanking.changeTypePlace')"
+            :label="$t('robotRanking.changeType')"
+          >
             <template #right-icon>
               <div class="l-flex-RC">
-                <van-icon v-if="searchForm.changeTypeName" @click="
-                  searchForm.changeTypeName = '';
-                searchForm.changeType = '';
-                " class="o-mr-6" name="clear" />
+                <van-icon
+                  v-if="searchForm.changeTypeName"
+                  @click="
+                    searchForm.changeTypeName = '';
+                    searchForm.changeType = '';
+                  "
+                  class="o-mr-6"
+                  name="clear"
+                />
                 <van-icon @click="changeTypeInpClk" name="arrow-down" />
               </div>
             </template>
           </van-field>
-          <van-field @click-input="machineTypeInpClk" readonly clearable v-model="searchForm.machineTypeName"
-            :placeholder="$t('robotRanking.machineTypePlace')" :label="$t('robotRanking.machineType')">
+          <van-field
+            @click-input="machineTypeInpClk"
+            readonly
+            clearable
+            v-model="searchForm.machineTypeName"
+            :placeholder="$t('robotRanking.machineTypePlace')"
+            :label="$t('robotRanking.machineType')"
+          >
             <template #right-icon>
               <div class="l-flex-RC">
-                <van-icon v-if="searchForm.machineTypeName" @click="
-                  searchForm.machineTypeName = '';
-                searchForm.machineType = '';
-                " class="o-mr-6" name="clear" />
+                <van-icon
+                  v-if="searchForm.machineTypeName"
+                  @click="
+                    searchForm.machineTypeName = '';
+                    searchForm.machineType = '';
+                  "
+                  class="o-mr-6"
+                  name="clear"
+                />
                 <van-icon @click="machineTypeInpClk" name="arrow-down" />
               </div>
             </template>
           </van-field>
-          <van-field v-if="isAdmin()" @click-input="companyTypeInpClk" readonly clearable
-            v-model="searchForm.companyTypeName" :placeholder="$t('robotRanking.companyTypePlaceholder')"
-            :label="$t('robotRanking.companyTypeLabel')">
+          <van-field
+            v-if="isAdmin()"
+            @click-input="companyTypeInpClk"
+            readonly
+            clearable
+            v-model="searchForm.companyTypeName"
+            :placeholder="$t('robotRanking.companyTypePlaceholder')"
+            :label="$t('robotRanking.companyTypeLabel')"
+          >
             <template #right-icon>
               <div class="l-flex-RC">
-                <van-icon v-if="searchForm.companyTypeName" @click="
-                  searchForm.companyTypeName = '';
-                searchForm.companyType = '';
-                " class="o-mr-6" name="clear" />
+                <van-icon
+                  v-if="searchForm.companyTypeName"
+                  @click="
+                    searchForm.companyTypeName = '';
+                    searchForm.companyType = '';
+                  "
+                  class="o-mr-6"
+                  name="clear"
+                />
                 <van-icon @click="companyTypeInpClk" name="arrow-down" />
               </div>
             </template>
@@ -102,56 +131,89 @@
         </div>
       </template>
     </kDialog>
-    <!-- 商家选择框 -->
-    <van-popup v-model:show="busiPopShow" position="bottom">
-      <van-picker :title="$t('subLedgerManage.search.busiPlaceholder')" :columns="busiPopList"
-        :columns-field-names="busiPopFieldName" @confirm="busiPopConfirm" @cancel="busiPopShow = false" />
-    </van-popup>
     <!-- 统计方式弹窗 -->
     <van-popup v-model:show="changeTypeShow" position="bottom">
-      <van-picker :default-index="chgTypeDefaIdx" :title="$t('robotRanking.changeTypePlace')" :columns="changeTypePopList"
-        :columns-field-names="yearPopFieldName" @confirm="changeTypePopConfirm" @cancel="changeTypeShow = false" />
+      <van-picker
+        :default-index="chgTypeDefaIdx"
+        :title="$t('robotRanking.changeTypePlace')"
+        :columns="changeTypePopList"
+        :columns-field-names="yearPopFieldName"
+        @confirm="changeTypePopConfirm"
+        @cancel="changeTypeShow = false"
+      />
     </van-popup>
     <!-- 设备类型弹窗 -->
     <van-popup v-model:show="machineTypeShow" position="bottom">
-      <van-picker :default-index="maTypeDefaIdx" :title="$t('robotRanking.machineTypePlace')"
-        :columns="machineTypePopList" :columns-field-names="yearPopFieldName" @confirm="machineTypePopConfirm"
-        @cancel="machineTypeShow = false" />
+      <van-picker
+        :default-index="maTypeDefaIdx"
+        :title="$t('robotRanking.machineTypePlace')"
+        :columns="machineTypePopList"
+        :columns-field-names="yearPopFieldName"
+        @confirm="machineTypePopConfirm"
+        @cancel="machineTypeShow = false"
+      />
     </van-popup>
     <!-- 公司平台弹窗 -->
     <van-popup v-model:show="companyTypeShow" position="bottom">
-      <van-picker :default-index="maTypeDefaIdx" :title="$t('robotRanking.companyTypePlaceholder')"
-        :columns="companyTypePopList" :columns-field-names="yearPopFieldName" @confirm="companyTypePopConfirm"
-        @cancel="companyTypeShow = false" />
+      <van-picker
+        :default-index="maTypeDefaIdx"
+        :title="$t('robotRanking.companyTypePlaceholder')"
+        :columns="companyTypePopList"
+        :columns-field-names="yearPopFieldName"
+        @confirm="companyTypePopConfirm"
+        @cancel="companyTypeShow = false"
+      />
     </van-popup>
     <!-- 日的日期选择弹窗 -->
-    <van-calendar @confirm="calendarDayConfirm" v-model:show="dayShow" color="#2c87c8" :min-date="minDate" :max-date="maxDate"
-      :show-confirm="false" />
+    <van-calendar
+      @confirm="calendarDayConfirm"
+      v-model:show="dayShow"
+      color="#2c87c8"
+      :min-date="minDate"
+      :max-date="maxDate"
+      :show-confirm="false"
+    />
     <!-- 周的日期选择弹窗 -->
-    <van-calendar @confirm="(e) => {
-      calendarWeekOrMonConfirm(e, 1);
-    }
-      " v-model:show="weekShow" :allow-same-day="true" color="#2c87c8" :min-date="minDate" :max-date="maxDate" type="range" :max-range="7"/>
+    <van-calendar
+      @confirm="
+        (e) => {
+          calendarWeekOrMonConfirm(e, 1);
+        }
+      "
+      v-model:show="weekShow"
+      :allow-same-day="true"
+      color="#2c87c8"
+      :min-date="minDate"
+      :max-date="maxDate"
+      type="range"
+      :max-range="7"
+    />
     <!-- 月的日期选择弹窗 -->
-    <van-calendar @confirm="(e) => {
-      calendarWeekOrMonConfirm(e, 2);
-    }
-      " v-model:show="monthShow" :allow-same-day="true" color="#2c87c8" :min-date="minDate" :max-date="maxDate" type="range" :max-range="31" />
+    <van-calendar
+      @confirm="
+        (e) => {
+          calendarWeekOrMonConfirm(e, 2);
+        }
+      "
+      v-model:show="monthShow"
+      :allow-same-day="true"
+      color="#2c87c8"
+      :min-date="minDate"
+      :max-date="maxDate"
+      type="range"
+      :max-range="31"
+    />
     <!-- 年的日期选择弹窗 -->
     <van-popup v-model:show="yearShow" position="bottom">
-      <van-picker :title="$t('robotRanking.yearPopTitle')" :columns="yearPopList" :columns-field-names="yearPopFieldName"
-        @confirm="yearPopConfirm" @cancel="yearShow = false" />
+      <van-picker
+        :title="$t('robotRanking.yearPopTitle')"
+        :columns="yearPopList"
+        :columns-field-names="yearPopFieldName"
+        @confirm="yearPopConfirm"
+        @cancel="yearShow = false"
+      />
     </van-popup>
   </div>
-  <div v-else class="noPermission" style="justify-content: center;">
-    <div class="box1 flex-col" style="text-align: center;">
-      <s-header :name="$t('robotRanking.machineSalesRanking')" :noback="true" :isFixed="false"></s-header>
-      <view>
-        <br />
-      </view>
-      <view>{{ $t('robotRanking.noPermission') }}</view>
-    </div>
-  </div>
 </template>
 
 <script>
@@ -159,8 +221,9 @@
 import kNoData from "../components/commom/kNoData/index.vue";
 import { onMounted, ref, reactive, computed, nextTick } from "vue";
 import sHeader from "../components/SimpleHeader";
+// import navBar from "../components/NavBar";
 import { getRankingList } from "../service/robotRanking";
-import { getLoginUser, styleUrl } from "../common/js/utils";
+import { getLoginUser } from "../common/js/utils";
 import kTabs from "../components/commom/kTabs/index.vue";
 import kDialog from "../components/commom/kDialog/index.vue";
 import moment from "moment";
@@ -204,7 +267,9 @@ export default {
       changeTypeShow.value = true;
     };
     // 是否管理员
-    const isAdmin = () => { return (user && user.type === 0); }
+    const isAdmin = () => {
+      return user && user.type === 0;
+    };
     // 公司平台弹窗
     const companyTypeInpClk = () => {
       companyTypeShow.value = true;
@@ -410,6 +475,29 @@ export default {
         id: 3,
       },
     ]);
+
+    const timePeriods = ref([
+      {
+        type: "day",
+        titleKey: "dailySalesRanking",
+        tabList: tabDayList.value,
+      },
+      {
+        type: "week",
+        titleKey: "salesRankingThisWeek",
+        tabList: tabWeekList.value,
+      },
+      {
+        type: "month",
+        titleKey: "salesRankingThisMonth",
+        tabList: tabMonthList.value,
+      },
+      {
+        type: "year",
+        titleKey: "salesRankingThisYear",
+        tabList: tabYearList.value,
+      },
+    ]);
     // 默认进来的时间
     const defaultTime = reactive({
       // 今日
@@ -428,8 +516,18 @@ export default {
       weekStart: moment().weekday(1).format("YYYY-MM-DD") + " 00:00:00",
       weekEnd: moment().weekday(7).format("YYYY-MM-DD") + " 23:59:59",
       // 上周
-      lastWeekStart: moment().week(moment().week() - 1).startOf('week').add(1, 'days').format("YYYY-MM-DD") + " 00:00:00",
-      lastWeekEnd: moment().week(moment().week() - 1).endOf('week').add(1, 'days').format("YYYY-MM-DD") + " 23:59:59",
+      lastWeekStart:
+        moment()
+          .week(moment().week() - 1)
+          .startOf("week")
+          .add(1, "days")
+          .format("YYYY-MM-DD") + " 00:00:00",
+      lastWeekEnd:
+        moment()
+          .week(moment().week() - 1)
+          .endOf("week")
+          .add(1, "days")
+          .format("YYYY-MM-DD") + " 23:59:59",
 
       // 这个月
       monthStart: moment().startOf("month").format("YYYY-MM-DD") + " 00:00:00",
@@ -530,7 +628,6 @@ export default {
           }
           break;
       }
-      console.log("startDate", defaultTime.colastdayStart);
       // 如果是点击其他,不用请求
       if (e.name !== 2) {
         //  获取日、周、月、年的排行数据
@@ -584,9 +681,9 @@ export default {
                 type: "shadow",
               },
               borderWidth: 1,
-              textStyle:{
-                fontSize : 12
-              }
+              textStyle: {
+                fontSize: 12,
+              },
             },
             // 固定屏幕显示多少个,其余的滑动
             dataZoom: [
@@ -611,8 +708,8 @@ export default {
               },
             ],
             grid: {
-              left: "3%",
-              right: "4%",
+              left: "5%",
+              right: "5%",
               bottom: "10%",
               containLabel: true,
             },
@@ -656,7 +753,7 @@ export default {
               {
                 ...data.data.series[0],
                 type: "bar",
-                itemStyle: { color: "#ddae27" },
+                itemStyle: { color: "#f6d258" },
                 name: t("home.productNum"),
                 label: {
                   show: true,
@@ -712,11 +809,7 @@ export default {
       });
     };
     const user = getLoginUser();
-    // 默认能看到机器排行
-    const showRobotRankingDiv = ref(true);
-    console.log("user.menuCodeList>>>", user.menuCodeList);
-    console.log("user.type>>>", user.type);
-    const isM11Included = user.menuCodeList.some((item) => item === "M11");
+
     // 日、周、月、年的图表
     const dayChartBox = ref();
     const weekChartBox = ref();
@@ -724,25 +817,12 @@ export default {
     const yearChartBox = ref();
     // 初始化页面获取列表
     onMounted(async () => {
-      // 加载样式
-      styleUrl('robotRanking');
       // 默认筛选选中
       searchForm.changeTypeName = t("robotRanking.salesStatistics");
       searchForm.changeType = 0;
       searchForm.companyTypeName = t("robotRanking.whole");
       searchForm.machineTypeName = t("robotRanking.whole");
-      // 查询是否有订单数据权限
-      // 子商家type=3和公司人员type=1,默认看不到 
-      if ((user.type > 2 || user.type === 1) && !isM11Included) {
-        showRobotRankingDiv.value = false;
-      }
-      // 如果是type为admin或者商家或者是有订单数据权限M4的子商家才可以查看
-      // if (user.type === 0 || user.type === 2 || isOrderData) {
-      //   init();
-      // }
-      if (user.type === 0 || user.type === 2 || isM11Included) {
-        init();
-      }
+      init();
 
       window.addEventListener("resize", () => {
         chartObj.day && chartObj.day.resize();
@@ -769,7 +849,7 @@ export default {
       machineTypeName: "",
       machineType: "",
       companyTypeName: "",
-      companyType: ""
+      companyType: "",
     });
     const kDialogRef = ref(null);
     const busiPopShow = ref(false);
@@ -814,6 +894,25 @@ export default {
     const busiPopCancel = () => {
       busiPopShow.value = false;
     };
+
+    const setChartRef = (el, type) => {
+      if (el) {
+        switch (type) {
+          case "day":
+            dayChartBox.value = el;
+            break;
+          case "week":
+            weekChartBox.value = el;
+            break;
+          case "month":
+            monthChartBox.value = el;
+            break;
+          case "year":
+            yearChartBox.value = el;
+            break;
+        }
+      }
+    };
     return {
       dayChartBox,
       weekChartBox,
@@ -866,12 +965,176 @@ export default {
       maTypeDefaIdx,
       chgTypeDefaIdx,
       isAdmin,
-
-      showRobotRankingDiv,
+      timePeriods,
+      setChartRef,
     };
   },
   components: { sHeader, kTabs, kDialog, kNoData },
 };
 </script>
 
-<style lang="less" scoped></style>
+<style lang="less" scoped>
+@primary-color: #2c87c8;
+@text-primary: #2d3542;
+@text-secondary: #64748b;
+@border-color: #e4e7ec;
+@card-bg: #ffffff;
+
+.sales-rank-view {
+  background: #f8f9fb;
+  height: calc(100% - 95px);
+  overflow: auto;
+  overflow-x: hidden;
+}
+
+.modern-header {
+  box-shadow: 0 2px 12px rgba(@primary-color, 0.1);
+}
+
+.rank-container {
+  padding: 0 10px;
+}
+
+:deep(.van-tab--active) {
+  color: #2c87c8 !important;
+}
+:deep(.van-tabs__line) {
+  background-color: #2c87c8 !important;
+}
+
+.filter-card {
+  background: @card-bg;
+  border-radius: 12px;
+  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
+  overflow: hidden;
+  margin: 10px 0;
+}
+
+.card-header {
+  padding: 16px 24px;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+}
+
+.card-title {
+  display: flex;
+  align-items: center;
+  margin: 0;
+  font-size: 16px;
+  color: @text-primary;
+  font-weight: 600;
+
+  .title-accent {
+    width: 4px;
+    height: 18px;
+    background: @primary-color;
+    border-radius: 2px;
+    margin-right: 12px;
+  }
+}
+
+.filter-icon {
+  font-size: 22px;
+  color: @text-primary;
+  transition: all 0.3s ease;
+  padding: 8px;
+  cursor: pointer;
+
+  &:hover {
+    color: @primary-color;
+    transform: rotate(90deg) scale(1.1);
+  }
+
+  &:active {
+    transform: rotate(90deg) scale(0.9);
+  }
+}
+
+@media (max-width: 768px) {
+  .card-header {
+    padding: 12px 16px;
+  }
+
+  .filter-icon {
+    font-size: 18px;
+    padding: 6px;
+  }
+}
+
+.rank-card {
+  background: white;
+  border-radius: 12px;
+  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.06);
+  margin-bottom: 10px;
+  height: 400px;
+  overflow: hidden;
+
+  .period-header {
+    padding: 16px;
+
+    .period-title {
+      display: flex;
+      align-items: center;
+      margin: 0 0 12px;
+      font-size: 16px;
+      color: @text-primary;
+
+      .period-icon {
+        width: 6px;
+        height: 6px;
+        background: @primary-color;
+        border-radius: 50%;
+        margin-right: 10px;
+      }
+    }
+
+    .type-tabs {
+      width: 100% !important;
+    }
+  }
+
+  .chart-wrapper {
+    padding: 0 16px 16px;
+    height: 400px;
+
+    .chart-box {
+      height: 300px;
+      width: 100%;
+      border-radius: 8px;
+      overflow: hidden;
+    }
+
+    .no-data-tip {
+      height: 300px;
+    }
+  }
+}
+
+/* 响应式设计 */
+@media (max-width: 768px) {
+  .rank-container {
+    padding: 0 10px;
+  }
+
+  .rank-card {
+    margin-bottom: 10px;
+
+    .chart-wrapper {
+      height: 250px;
+      padding: 0 12px 12px;
+    }
+  }
+
+  .filter-container {
+    .rank-title {
+      font-size: 16px;
+    }
+
+    .filter-btn {
+      padding: 6px 16px;
+      font-size: 13px;
+    }
+  }
+}
+</style>

文件差異過大導致無法顯示
+ 816 - 300
src/views/user.vue