浏览代码

feat:“同步2025.08.09“

soobin 1 周之前
父节点
当前提交
b934b3375a

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "sc-vue3-app",
-  "version": "1.5.702",
+  "version": "1.5.811",
   "private": true,
   "scripts": {
     "start": "vue-cli-service serve",

+ 2 - 2
public/version.json

@@ -1,5 +1,5 @@
 {
-  "version": "1.5.702",
-  "timestamp": "2025-07-03T17:02:01.949",
+  "version": "1.5.811",
+  "timestamp": "2025-08-11T09:49:18.558",
   "commitHash": "dev-build"
 }

二进制
src/assets/device/operIcon/goodsMan.png


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

@@ -416,6 +416,8 @@
     "equipmentStatus": "Status",
     "pleaseSelectTheDeviceStatus": "Select status",
     "plzSelectDeviceGroup": "Select group",
+    "isAbroad": "Region",
+    "isAbroadPlaceholder": "Select region",
     "emptyingConditions": "Reset Filters",
     "clickSearch": "Search",
     "spunSugar": "Cotton Candy",
@@ -550,7 +552,13 @@
       "batchPricePlace": "Enter price",
       "modifySubmit": "Apply Changes"
     },
+    "onShelf": "Available",
+    "offShelf": "Discontinued",
+    "editProductName": "Edit Product Name",
+    "enterProductName": "Enter product name",
+    "enterProductPrice": "Enter product price",
     "materialMonitor": "Material Monitoring",
+    "openRemindMaterial": "Toggle material monitoring?",
     "showGoodsPage": {
       "title": "Product Display",
       "equipmentName": "Machine Name"
@@ -615,6 +623,13 @@
     "cheese": "Cheese",
     "peach": "Peach",
     "caramel": "Caramel",
+    "C01": "Crushed Fruit (1)",
+    "C02": "Crushed Fruit (2)",
+    "J01": "Fruit Jam (1)",
+    "J02": "Fruit Jam (2)",
+    "J03": "Fruit Jam (3)",
+    "sweet": "Sweet Corn",
+    "salty": "Salted Corn",
     "sentSuccessfully": "Sent",
     "turnOffSleep": "Sleep Mode",
     "turnOnSleep": "Active",
@@ -1009,6 +1024,7 @@
     "tradeName": "Product",
     "dividingDomesticService": "Commission",
     "tax": "Taxes & Fees",
+    "memberCode": "Member ID",
     "business": "Merchant",
     "orderNo": "Order No",
     "commodity": "Item",
@@ -1574,8 +1590,13 @@
   },
   "bindWechat": {
     "cancel": "Cancel",
+    "welcomeTitle": "WeChat Binding",
+    "welcomeSubtitle": "Bind WeChat for easy login and important notifications",
+    "unbind": "Unlink",
+    "unbindTips": "Confirm unlinking WeChat account?",
+    "unbindSuccess": "WeChat unlinked",
     "bindCommit": "Bind WeChat",
-    "bindSuccess": "Bound Successfully"
+    "bindSuccess": "WeChat linked"
   },
   "labelMan": {
     "title": "Group Management",
@@ -1867,6 +1888,7 @@
     "C29": "Tax Administration",
     "C30": "Jam Extraction",
     "C31": "Maintenance Details",
-    "C32": "Payment Configuration"
+    "C32": "Payment Configuration",
+    "C33": "Product Management"
   }
 }

+ 25 - 3
src/assets/language/es.json

@@ -416,6 +416,8 @@
         "equipmentStatus": "Estado",
         "pleaseSelectTheDeviceStatus": "Seleccionar",
         "plzSelectDeviceGroup": "Seleccionar grupo",
+        "isAbroad": "Región",
+        "isAbroadPlaceholder": "Seleccione región",
         "emptyingConditions": "Vaciar criterios",
         "clickSearch": "Buscar",
         "spunSugar": "Algodón azúcar",
@@ -550,7 +552,13 @@
             "batchPricePlace": "Ej: 5.99",
             "modifySubmit": "Confirmar cambios"
         },
+        "onShelf": "Disponible",
+        "offShelf": "Retirado",
+        "editProductName": "Editar nombre del producto",
+        "enterProductName": "Introduzca el nombre del producto",
+        "enterProductPrice": "Introduzca el precio del producto",
         "materialMonitor": "Control inventario",
+        "openRemindMaterial": "¿Cambiar monitoreo de materiales?",
         "showGoodsPage": {
             "title": "Config. productos",
             "equipmentName": "Equipo"
@@ -615,6 +623,13 @@
         "cheese": "Queso",
         "peach": "Melocotón",
         "caramel": "Caramelo",
+        "C01": "Fruta triturada (1)",
+        "C02": "Fruta triturada (2)",
+        "J01": "Mermelada (1)",
+        "J02": "Mermelada (2)",
+        "J03": "Mermelada (3)",
+        "sweet": "Maíz Dulce",
+        "salty": "Maíz Salado",
         "sentSuccessfully": "Solicitud enviada",
         "turnOffSleep": "Modo descanso",
         "turnOnSleep": "Modo activo",
@@ -1009,6 +1024,7 @@
         "tradeName": "Producto",
         "dividingDomesticService": "Comisión",
         "tax": "Impuestos",
+        "memberCode": "Código de socio",
         "business": "Comercio",
         "orderNo": "N° pedido",
         "commodity": "Artículo",
@@ -1573,8 +1589,13 @@
     },
     "bindWechat": {
         "cancel": "Cancelar",
-        "bindCommit": "Vincular",
-        "bindSuccess": "Vinculado"
+        "welcomeTitle": "Vinculación WeChat",
+        "welcomeSubtitle": "Vincula WeChat para inicio fácil y notificaciones",
+        "unbind": "Desvincular",
+        "unbindTips": "¿Desvincular cuenta WeChat actual?",
+        "unbindSuccess": "WeChat desvinculado",
+        "bindCommit": "Vincular WeChat",
+        "bindSuccess": "WeChat vinculado"
     },
     "labelMan": {
         "title": "Gestión de grupos",
@@ -1866,6 +1887,7 @@
         "C29": "Gestión Tributaria",
         "C30": "Extracción de Mermelada",
         "C31": "Detalles de Mantenimiento",
-        "C32": "Configuración de pagos"
+        "C32": "Configuración de pagos",
+        "C33": "Gestión de productos"
     }
 }

+ 24 - 2
src/assets/language/fr.json

@@ -416,6 +416,8 @@
         "equipmentStatus": "État",
         "pleaseSelectTheDeviceStatus": "Sélectionner état",
         "plzSelectDeviceGroup": "Choisir groupe",
+        "isAbroad": "Région",
+        "isAbroadPlaceholder": "Sélectionnez une région", 
         "emptyingConditions": "Réinitialiser filtres",
         "clickSearch": "Rechercher",
         "spunSugar": "Barbe à papa",
@@ -550,7 +552,13 @@
             "batchPricePlace": "Ex: 5.99",
             "modifySubmit": "Valider modifications"
         },
+        "onShelf": "En vente",
+        "offShelf": "Retiré",
+        "editProductName": "Modifier nom du produit",
+        "enterProductName": "Saisir le nom du produit",
+        "enterProductPrice": "Saisir le prix du produit",
         "materialMonitor": "Surveillance matières",
+        "openRemindMaterial": "Basculer le suivi des matières?",
         "showGoodsPage": {
             "title": "Affichage produits",
             "equipmentName": "Nom appareil"
@@ -615,6 +623,13 @@
         "cheese": "Fromage",
         "peach": "Pêche",
         "caramel": "Caramel",
+        "C01": "Fruits concassés (1)",
+        "C02": "Fruits concassés (2)",
+        "J01": "Confiture (1)",
+        "J02": "Confiture (2)",
+        "J03": "Confiture (3)",
+        "sweet": "Maïs Sucré",
+        "salty": "Maïs Salé",
         "sentSuccessfully": "Envoyé",
         "turnOffSleep": "Veille activée",
         "turnOnSleep": "Veille désactivée",
@@ -1009,6 +1024,7 @@
         "tradeName": "Produit",
         "dividingDomesticService": "Commission",
         "tax": "Taxes",
+        "memberCode": "Code membre",
         "business": "Marchand",
         "orderNo": "N° commande",
         "commodity": "Article",
@@ -1604,8 +1620,13 @@
     },
     "bindWechat": {
         "cancel": "Annuler",
+        "welcomeTitle": "Liaison WeChat",
+        "welcomeSubtitle": "Liez WeChat pour un accès facile et notifications importantes",
+        "unbind": "Dissocier",
+        "unbindTips": "Dissocier le compte WeChat actuel?",
+        "unbindSuccess": "WeChat dissocié",
         "bindCommit": "Lier WeChat",
-        "bindSuccess": "Compte lié"
+        "bindSuccess": "WeChat lié"
     },
     "labelMan": {
         "title": "Gestion des groupes",
@@ -1897,6 +1918,7 @@
         "C29": "Gestion Fiscale",
         "C30": "Extraction de Confiture",
         "C31": "Détails de la maintenance",
-        "C32": "Configuration de paiement"
+        "C32": "Configuration de paiement",
+        "C33": "Gestion des produits"
     }
 }

+ 25 - 3
src/assets/language/ja.json

@@ -411,6 +411,8 @@
         "deviceGrouping": "デバイスパケット",
         "emptyingConditions": "条件をクリア",
         "plzSelectDeviceGroup": "デバイスグループを選択してください",
+        "isAbroad": "地域",
+        "isAbroadPlaceholder": "地域を選択",
         "clickSearch": "クリックして検索",
         "spunSugar": "綿菓子",
         "popcorn": "ポップコーン",
@@ -544,7 +546,13 @@
             "batchPricePlace": "一括価格を入力してください",
             "modifySubmit": "変更を提出"
         },
+        "onShelf": "販売中",
+        "offShelf": "販売終了",
+        "editProductName": "商品名編集",
+        "enterProductName": "商品名を入力",
+        "enterProductPrice": "価格を入力",
         "materialMonitor": "材料監視",
+        "openRemindMaterial": "材料監視モードを切り替えますか?",
         "showGoodsPage": {
             "title": "商品表示設定",
             "equipmentName": "装置名"
@@ -609,6 +617,13 @@
         "cheese": "チーズ",
         "peach": "桃",
         "caramel": "キャラメル",
+        "C01": "フルーツ細粒 (1)",
+        "C02": "フルーツ細粒 (2)",
+        "J01": "フルーツジャム (1)",
+        "J02": "フルーツジャム (2)",
+        "J03": "フルーツジャム (3)",
+        "sweet": "スイートコーン",
+        "salty": "塩味コーン",
         "sentSuccessfully": "リクエスト送信完了",
         "turnOffSleep": "スリープ中",
         "turnOnSleep": "スリープしていない",
@@ -998,6 +1013,7 @@
         "tradeName": "商品名",
         "dividingDomesticService": "コミッション分配",
         "tax": "税金",
+        "memberCode": "会員コード",
         "business": "ビジネス",
         "orderNo": "注文番号",
         "commodity": "商品",
@@ -1565,8 +1581,13 @@
     },
     "bindWechat": {
         "cancel": "キャンセル",
-        "bindCommit": "WeChatをバインドする",
-        "bindSuccess": "バインドに成功しました"
+        "welcomeTitle": "WeChat連携",
+        "welcomeSubtitle": "WeChat連携で簡単ログインと通知を受け取れます",
+        "unbind": "連携解除",
+        "unbindTips": "現在のWeChat連携を解除しますか?",
+        "unbindSuccess": "連携解除成功",
+        "bindCommit": "WeChat連携",
+        "bindSuccess": "連携成功"
     },
     "labelMan": {
         "title": "グループ管理",
@@ -1858,6 +1879,7 @@
         "C29": "税務管理",
         "C30": "ジャム抽出",
         "C31": "メンテナンス記録",
-        "C32": "決済設定"
+        "C32": "決済設定",
+        "C33": "商品管理"
     }
 }

+ 24 - 2
src/assets/language/pt.json

@@ -416,6 +416,8 @@
         "equipmentStatus": "Status",
         "pleaseSelectTheDeviceStatus": "Selecione",
         "plzSelectDeviceGroup": "Selecione grupo",
+        "isAbroad": "Região",
+        "isAbroadPlaceholder": "Selecione a região",
         "emptyingConditions": "Limpar Filtros",
         "clickSearch": "Buscar",
         "spunSugar": "Máquina Algodão Doce",
@@ -550,7 +552,13 @@
             "batchPricePlace": "Ex: 15.90",
             "modifySubmit": "Confirmar Alterações"
         },
+        "onShelf": "Disponível",
+        "offShelf": "Descontinuado",
+        "editProductName": "Editar nome do produto",
+        "enterProductName": "Digite o nome do produto",
+        "enterProductPrice": "Digite o preço do produto",
         "materialMonitor": "Monitor de Insumos",
+        "openRemindMaterial": "Alternar monitoramento de materiais?",
         "showGoodsPage": {
             "title": "Configurar Exibição",
             "equipmentName": "Equipamento"
@@ -615,6 +623,13 @@
         "cheese": "Queijo",
         "peach": "Pêssego",
         "caramel": "Caramelo",
+        "C01": "Frutas trituradas (1)",
+        "C02": "Frutas trituradas (2)",
+        "J01": "Geleia (1)",
+        "J02": "Geleia (2)",
+        "J03": "Geleia (3)",
+        "sweet": "Milho Doce",
+        "salty": "Milho Salgado",
         "sentSuccessfully": "Comando Enviado",
         "turnOffSleep": "Modo Repouso Ativo",
         "turnOnSleep": "Modo Repouso Inativo",
@@ -1009,6 +1024,7 @@
         "tradeName": "Produto",
         "dividingDomesticService": "Comissão",
         "tax": "Tributos e Taxas",
+        "memberCode": "Código de membro",
         "business": "Comerciante",
         "orderNo": "Nº do Pedido",
         "commodity": "Item",
@@ -1573,8 +1589,13 @@
     },
     "bindWechat": {
         "cancel": "Cancelar",
+        "welcomeTitle": "Associação WeChat",
+        "welcomeSubtitle": "Associe WeChat para login fácil e notificações",
+        "unbind": "Desvincular",
+        "unbindTips": "Desvincular conta WeChat atual?",
+        "unbindSuccess": "WeChat desvinculado",
         "bindCommit": "Vincular WeChat",
-        "bindSuccess": "Vinculado"
+        "bindSuccess": "WeChat vinculado"
     },
     "labelMan": {
         "title": "Gestão de Grupos",
@@ -1866,6 +1887,7 @@
         "C29": "Gestão Tributária",
         "C30": "Extração de Geleia",
         "C31": "Registros de Manutenção",
-        "C32": "Configuração de pagamento"
+        "C32": "Configuração de pagamento",
+        "C33": "Gestão de produtos"
     }
 }

+ 25 - 3
src/assets/language/ru.json

@@ -416,6 +416,8 @@
         "equipmentStatus": "Статус",
         "pleaseSelectTheDeviceStatus": "Статус устройства",
         "plzSelectDeviceGroup": "Группа устройств",
+        "isAbroad": "Регион",
+        "isAbroadPlaceholder": "Выберите регион",
         "emptyingConditions": "Очистка",
         "clickSearch": "Поиск",
         "spunSugar": "Сахар.вата",
@@ -550,7 +552,13 @@
             "batchPricePlace": "Цена...",
             "modifySubmit": "Сохранить"
         },
+        "onShelf": "В продаже",
+        "offShelf": "Снято с продажи",
+        "editProductName": "Изменить название товара",
+        "enterProductName": "Введите название товара",
+        "enterProductPrice": "Введите цену товара",
         "materialMonitor": "Контроль мат.",
+        "openRemindMaterial": "Переключить мониторинг материалов?",
         "showGoodsPage": {
             "title": "Отображение товаров",
             "equipmentName": "Устройство"
@@ -615,6 +623,13 @@
         "cheese": "Сыр",
         "peach": "Персик",
         "caramel": "Карамель",
+        "C01": "Фруктовая крошка (1)",
+        "C02": "Фруктовая крошка (2)",
+        "J01": "Фруктовый джем (1)",
+        "J02": "Фруктовый джем (2)",
+        "J03": "Фруктовый джем (3)",
+        "sweet": "Сладкая кукуруза",
+        "salty": "Солёная кукуруза",
         "sentSuccessfully": "Отправлено",
         "turnOffSleep": "Сон zzZ",
         "turnOnSleep": "Активно",
@@ -1009,6 +1024,7 @@
         "tradeName": "Товар",
         "dividingDomesticService": "Комиссия",
         "tax": "Налоги и сборы",
+        "memberCode": "Код участника",
         "business": "Мерчант",
         "orderNo": "№ заказа",
         "commodity": "Товар",
@@ -1604,8 +1620,13 @@
     },
     "bindWechat": {
         "cancel": "Отмена",
-        "bindCommit": "Привязать",
-        "bindSuccess": "Успешно"
+        "welcomeTitle": "Привязка WeChat",
+        "welcomeSubtitle": "Привяжите WeChat для простого входа и получения уведомлений",
+        "unbind": "Отвязать",
+        "unbindTips": "Отвязать текущий аккаунт WeChat?",
+        "unbindSuccess": "WeChat отвязан",
+        "bindCommit": "Привязать WeChat",
+        "bindSuccess": "WeChat привязан"
     },
     "labelMan": {
         "title": "Управление группами",
@@ -1897,6 +1918,7 @@
         "C29": "Управление налогообложением",
         "C30": "Экстракция джема",
         "C31": "Журнал обслуживания",
-        "C32": "Настройка платежей"
+        "C32": "Настройка платежей",
+        "C33": "Управление товарами"
     }
 }

+ 25 - 3
src/assets/language/uk.json

@@ -416,6 +416,8 @@
         "equipmentStatus": "Стан",
         "pleaseSelectTheDeviceStatus": "Обрати стан",
         "plzSelectDeviceGroup": "Обрати групу",
+        "isAbroad": "Регіон",
+        "isAbroadPlaceholder": "Оберіть регіон",
         "emptyingConditions": "Очищення",
         "clickSearch": "Пошук",
         "spunSugar": "Цукерки",
@@ -550,7 +552,13 @@
             "batchPricePlace": "Введіть ціну",
             "modifySubmit": "Зберегти зміни"
         },
+        "onShelf": "У продажу",
+        "offShelf": "Знято з продажу",
+        "editProductName": "Редагувати назву товару",
+        "enterProductName": "Введіть назву товару",
+        "enterProductPrice": "Введіть ціну товару",
         "materialMonitor": "Моніторинг матеріалів",
+        "openRemindMaterial": "Перемкнути моніторинг матеріалів?",
         "showGoodsPage": {
             "title": "Налаштування відображення",
             "equipmentName": "Пристрій"
@@ -615,6 +623,13 @@
         "cheese": "Сир",
         "peach": "Персик",
         "caramel": "Карамель",
+        "C01": "Фруктовий крихт (1)",
+        "C02": "Фруктовий крихт (2)",
+        "J01": "Фруктовий джем (1)",
+        "J02": "Фруктовий джем (2)",
+        "J03": "Фруктовий джем (3)",
+        "sweet": "Солодка кукурудза",
+        "salty": "Солона кукурудза",
         "sentSuccessfully": "Запит відправлено",
         "turnOffSleep": "Сон zzZ",
         "turnOnSleep": "Не спить",
@@ -1009,6 +1024,7 @@
         "tradeName": "Товар",
         "dividingDomesticService": "Розподіл комісій",
         "tax": "Податки та збори",
+        "memberCode": "Код члена",
         "business": "Продавець",
         "orderNo": "Номер замовлення",
         "commodity": "Товар",
@@ -1574,8 +1590,13 @@
     },
     "bindWechat": {
         "cancel": "Скасувати",
-        "bindCommit": "Прив'язка",
-        "bindSuccess": "Успішно прив'язано"
+        "welcomeTitle": "Прив'язка WeChat",
+        "welcomeSubtitle": "Прив'яжіть WeChat для входу та сповіщень",
+        "unbind": "Відв'язати",
+        "unbindTips": "Відв'язати поточний WeChat?",
+        "unbindSuccess": "WeChat відв'язано",
+        "bindCommit": "Прив'язати WeChat",
+        "bindSuccess": "WeChat прив'язано"
     },
     "labelMan": {
         "title": "Керування групами",
@@ -1867,6 +1888,7 @@
         "C29": "Управління оподаткуванням",
         "C30": "Витяг джему",
         "C31": "Журнал обслуговування",
-        "C32": "Налаштування платежів"
+        "C32": "Налаштування платежів",
+        "C33": "Управління товарами"
     }
 }

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

@@ -425,6 +425,8 @@
     "equipmentStatus": "设备状态",
     "pleaseSelectTheDeviceStatus": "请选择设备状态",
     "plzSelectDeviceGroup": "请选择设备分组",
+    "isAbroad": "地区",
+    "isAbroadPlaceholder": "请选择地区",
     "emptyingConditions": "清空条件",
     "clickSearch": "点击搜索",
     "spunSugar": "棉花糖",
@@ -559,7 +561,13 @@
       "batchPricePlace": "请输入批量价格",
       "modifySubmit": "修改提交"
     },
+    "onShelf": "上架中",
+    "offShelf": "已下架",
+    "editProductName": "编辑商品名称",
+    "enterProductName": "请输入商品名称",
+    "enterProductPrice": "请输入商品价格",
     "materialMonitor": "物料监控",
+    "openRemindMaterial": "是否切换物料监控开关?",
     "showGoodsPage": {
       "title": "商品显示设置",
       "equipmentName": "设备名称"
@@ -624,6 +632,13 @@
     "cheese": "芝士",
     "peach": "水蜜桃",
     "caramel": "焦糖",
+    "C01": "果碎(1)",
+    "C02": "果碎(2)",
+    "J01": "果酱(1)",
+    "J02": "果酱(2)",
+    "J03": "果酱(3)",
+    "sweet": "甜玉米",
+    "salty": "咸玉米",
     "sentSuccessfully": "发送请求成功",
     "turnOffSleep": "睡眠中zzZ",
     "turnOnSleep": "未睡眠",
@@ -1018,6 +1033,7 @@
     "tradeName": "商品名称",
     "dividingDomesticService": "分佣",
     "tax": "税费",
+    "memberCode": "会员代码",
     "business": "商家",
     "orderNo": "订单编号",
     "commodity": "商品",
@@ -1583,6 +1599,11 @@
   },
   "bindWechat": {
     "cancel": "取消",
+    "welcomeTitle": "微信绑定",
+    "welcomeSubtitle": "绑定微信,轻松登录并接收重要通知",
+    "unbind": "解绑",
+    "unbindTips": "确定要解绑当前微信吗?",
+    "unbindSuccess": "解绑成功",
     "bindCommit": "绑定微信",
     "bindSuccess": "绑定成功"
   },
@@ -1876,6 +1897,7 @@
     "C29": "税收管理",
     "C30": "果酱抽取",
     "C31": "维护记录",
-    "C32": "支付配置"
+    "C32": "支付配置",
+    "C33": "商品管理"
   }
 }

+ 16 - 0
src/common/js/countries-en.js

@@ -1367,6 +1367,22 @@ export const countriesDataEn = [
     ],
   },
   {
+    text: "Montenegro",
+    value: "ME",
+    children: [
+      { text: "Podgorica", value: "Podgorica" },
+      { text: "Bar", value: "Bar" },
+      { text: "Budva", value: "Budva" },
+      { text: "Cetinje", value: "Cetinje" },
+      { text: "Herceg Novi", value: "Herceg Novi" },
+      { text: "Kotor", value: "Kotor" },
+      { text: "Nikšić", value: "Nikšić" },
+      { text: "Pljevlja", value: "Pljevlja" },
+      { text: "Tivat", value: "Tivat" },
+      { text: "Ulcinj", value: "Ulcinj" },
+    ],
+  },
+  {
     text: "Madagascar",
     value: "MG",
     children: [

+ 16 - 0
src/common/js/countries.js

@@ -1355,6 +1355,22 @@ export const countriesData = [
     ],
   },
   {
+    text: "黑山",
+    value: "ME",
+    children: [
+      { text: "波德戈里察", value: "Podgorica" },
+      { text: "巴尔", value: "Bar" },
+      { text: "布德瓦", value: "Budva" },
+      { text: "采蒂涅", value: "Cetinje" },
+      { text: "新海尔采格", value: "Herceg Novi" },
+      { text: "科托尔", value: "Kotor" },
+      { text: "尼克希奇", value: "Nikšić" },
+      { text: "普列夫利亚", value: "Pljevlja" },
+      { text: "蒂瓦特", value: "Tivat" },
+      { text: "乌尔齐尼", value: "Ulcinj" },
+    ],
+  },
+  {
     text: "马达加斯加",
     value: "MG",
     children: [

+ 1 - 1
src/components/typeDownMenu/index.vue

@@ -430,7 +430,7 @@ export default {
       border-radius: var(--card-radius);
       box-shadow: var(--card-shadow);
       border: 0;
-      max-height: 60vh;
+      max-height: 45vh;
       z-index: 9999;
       /* 确保层级 */
     }

+ 7 - 0
src/router/index.js

@@ -532,6 +532,13 @@ const router = createRouter({
       component: () => import("@/views/purse/index"),
       meta: { index: 1 },
     },
+    // 商品管理
+    {
+      path: "/goodsMan",
+      name: "goodsMan",
+      component: () => import("@/views/device/goodsMan/index"),
+      meta: { index: 1 },
+    },
     // 修改支付方式
     {
       path: "/payment",

+ 6 - 0
src/service/bindWechat.js

@@ -1,4 +1,5 @@
 import axios from '../utils/axios';
+import { stringToUrl } from '@/common/js/utils';
 
 // 绑定微信
 export function bindWechat(adminId) {
@@ -20,4 +21,9 @@ export function auth(code, state) {
 // 获取微信头像
 export function getAvatar(adminId) {
     return axios.get(`SZWL-SERVER/tWechat/getAvatar?adminId=${adminId}`);
+}
+
+// 解绑
+export function unbindWechat(params) {
+    return axios.get(`/SZWL-SERVER/tWechat/unbind?${stringToUrl(params)}`);
 }

+ 39 - 17
src/service/device/index.js

@@ -9,6 +9,11 @@ export function getDeviceList(params) {
   );
 }
 
+// 获取机器列表
+export function getMachineList(params) {
+  return axios.post(`/SZWL-SERVER/tEquipment/list`, params);
+}
+
 // 获取设备详情
 export function getDeviceDetal(params) {
   return axios.post(
@@ -38,11 +43,9 @@ export function eliminate(params) {
 }
 
 // 重启炉头/开启关闭炉头
+// 重启炉头/开启关闭炉头
 export function setFurnace(params) {
-  return axios.post(
-    `/SZWL-SERVER/tEquipment/onOff?${stringToUrl(params)}`,
-    params
-  );
+  return axios.post(`/SZWL-SERVER/tEquipment/powerOnOff`, params);
 }
 
 // 雪糕机机器复位
@@ -55,10 +58,7 @@ export function machineReset(params) {
 
 // 睡眠
 export function sleepEquipment(params) {
-  return axios.post(
-    `/SZWL-SERVER/tEquipment/sleep?${stringToUrl(params)}`,
-    params
-  );
+  return axios.post(`/SZWL-SERVER/tEquipment/switchSleep`, params);
 }
 
 // 远程开门
@@ -71,7 +71,7 @@ export function openDoor(params) {
 
 // 新版远程开门,包含内门外门
 export function Api_openDoor(params) {
-  return axios.get(`/SZWL-SERVER/tEquipment/openDoors`, { params });
+  return axios.post(`/SZWL-SERVER/tEquipment/newOpenDoor`, params);
 }
 
 // 纸币器禁能
@@ -89,10 +89,7 @@ export function deviceTuoji(params) {
 
 // 音量调解
 export function updateVolume(params) {
-  return axios.post(
-    `/SZWL-SERVER/tEquipment/updateVolume?${stringToUrl(params)}`,
-    params
-  );
+  return axios.post(`/SZWL-SERVER/tEquipment/changeVolume`, params);
 }
 
 // 获取商品下拉列表
@@ -112,6 +109,11 @@ export function remoteProduction(params) {
   return axios.post(`/SZWL-SERVER/tSugarDo/remoteProduction`, params);
 }
 
+// 制作商品
+export function produceGoods(params) {
+  return axios.post(`/SZWL-SERVER/tEquipment/produceGoods`, params);
+}
+
 // 查询做糖状态
 export function selectSugarStatus(params) {
   return axios.get(
@@ -199,9 +201,9 @@ export function humidityParameters(params) {
   return axios.post(`/SZWL-SERVER/tEquipment/humidityParameters`, params);
 }
 
-// 启用物料监控
-export function enableMaterial(params) {
-  return axios.post(`/SZWL-SERVER/tParameters/enableMaterial`, params);
+// 新物料监控开关
+export function changeMaterial(params) {
+  return axios.post(`/SZWL-SERVER/tEquipment/material`, params);
 }
 
 // 分销人回显
@@ -229,6 +231,11 @@ export function Api_getTApkInfo_updateApk(params) {
   return axios.get(`/SZWL-SERVER/tApkInfo/updateApk`, { params });
 }
 
+// MQTT远程推送更新
+export function pushAppUpdate(params) {
+  return axios.post(`/SZWL-SERVER/tEquipment/pushAppUpdate`, params);
+}
+
 // 修改优惠码开关状态
 export function Api_getDiscCodeStatus(params) {
   return axios.get(`/SZWL-SERVER/tEquipment/updateCouponStatus`, { params });
@@ -255,6 +262,11 @@ export function newUpdateProductsShow(params) {
 }
 
 // 远程修改机器密码
+export function changePassword(params) {
+  return axios.post(`/SZWL-SERVER/tEquipment/changePassword`, params);
+}
+
+// 远程修改机器密码
 export function updateDevicePassword(params) {
   return axios.post(`/SZWL-SERVER/tEquipment/updatePassword`, params);
 }
@@ -320,7 +332,7 @@ export function queryLog(params) {
 
 // 重启触摸屏
 export function restartScreen(params) {
-  return axios.get(`/SZWL-SERVER/tEquipment/openScreen`, { params });
+  return axios.get(`/SZWL-SERVER/tEquipment/restartScreen`, { params });
 }
 
 // 远程切换雪糕机工作模式
@@ -399,3 +411,13 @@ export function getPayConfig(params) {
 export function pushPayInfo(params) {
   return axios.post(`/SZWL-SERVER/openPayInfo/pushPayInfo`, params);
 }
+
+// 修改商品信息
+export function updateProductInfo(params) {
+  return axios.post(`/SZWL-SERVER/tEquipment/updateProductInfo`, params);
+}
+
+// 批量修改商品价格
+export function batchUpdatePrice(params) {
+  return axios.post(`/SZWL-SERVER/tEquipment/batchUpdatePrice`, params);
+}

+ 0 - 10
src/views/accountPer/add.vue

@@ -39,10 +39,6 @@
           ]"
         />
 
-        <!-- <van-field v-model="phone" :label="$t('accountPer.phoneLabel')" :placeholder="$t('accountPer.phonePlaceholder')"
-          left-icon="phone" class="modern-field"
-          :rules="[{ required: true, message: $t('accountPer.phonePlaceholder') }]" /> -->
-
         <!-- 类型选择 -->
         <van-field name="radio" v-if="user.type === 0" class="radio-field">
           <template #input>
@@ -90,12 +86,6 @@
           readonly
           clearable
           @click="busiEquipInpClk"
-          :rules="[
-            {
-              required: true,
-              message: $t('accountPer.manageMachinesPlaceholder'),
-            },
-          ]"
         >
           <template #right-icon>
             <div class="field-icons">

+ 2 - 54
src/views/bindBankCard/huifuBind.vue

@@ -594,33 +594,6 @@
               required
               :rules="[{ required: true, message: '请输入银行账号' }]"
             />
-            <!-- <van-field label="结算方式" required>
-              <template #input>
-                <div class="settlement-container">
-                  <van-radio-group
-                    v-model="formData.settMode"
-                    direction="horizontal"
-                  >
-                    <van-radio
-                      :name="1"
-                      checked-color="#2d88c9"
-                      icon-size="18px"
-                      >自动结算</van-radio
-                    >
-                    <van-radio
-                      :name="2"
-                      checked-color="#2d88c9"
-                      icon-size="18px"
-                      >手动提现</van-radio
-                    >
-                  </van-radio-group>
-                  <div class="settlement-tip">
-                    <van-icon name="info" color="#999" size="14px" />
-                    <span>24小时内到账</span>
-                  </div>
-                </div>
-              </template>
-            </van-field> -->
             <!-- 银行地址 -->
             <van-field
               v-model="bankAddress"
@@ -666,33 +639,6 @@
               required
               :rules="[{ required: true, message: '请输入联行号' }]"
             />
-            <!-- <van-field label="结算方式" required>
-              <template #input>
-                <div class="settlement-container">
-                  <van-radio-group
-                    v-model="formData.settMode"
-                    direction="horizontal"
-                  >
-                    <van-radio
-                      :name="1"
-                      checked-color="#2d88c9"
-                      icon-size="18px"
-                      >自动结算</van-radio
-                    >
-                    <van-radio
-                      :name="2"
-                      checked-color="#2d88c9"
-                      icon-size="18px"
-                      >手动提现</van-radio
-                    >
-                  </van-radio-group>
-                  <div class="settlement-tip">
-                    <van-icon name="info" color="#999" size="14px" />
-                    <span>自动结算和手工提现均为次日到账</span>
-                  </div>
-                </div>
-              </template>
-            </van-field> -->
             <van-field
               v-model="bankAddress"
               readonly
@@ -757,6 +703,7 @@
         :min-date="minDate"
         :max-date="maxDate"
         @confirm="idStartDateConfirm"
+        @cancel="showStartDatePicker = false"
       />
     </van-popup>
     <van-popup
@@ -771,6 +718,7 @@
         :min-date="minDate"
         :max-date="maxDate"
         @confirm="idEndDateConfirm"
+        @cancel="showEndDatePicker = false"
       />
     </van-popup>
     <!-- 公司注册日期选择器弹窗 -->

+ 1 - 0
src/views/bindBankCard/joinPayBind.vue

@@ -681,6 +681,7 @@
         :min-date="minDate"
         :max-date="maxDate"
         @confirm="idDateConfirm"
+        @cancel="showDatePicker = false"
       />
     </van-popup>
     <!-- 公司注册日期选择器弹窗 -->

+ 214 - 41
src/views/bindWechat.vue

@@ -1,45 +1,75 @@
 <template>
-  <!-- 绑定微信 -->
   <div class="bindWechat">
-    <s-header :name="$t('wechat.headerName')" :noback="false"></s-header>
-    <div class="loginFormBox">
-      <van-form @submit="onSubmit">
-        <!-- 微信头像 -->
-        <div style="display: flex;justify-content: center;align-items: center">
-          <van-image width="100px" height="100px" :src="wechatInfo.avatarUrl" fit="cover" radius="50%"
-            style="margin: auto" />
-        </div>
-        <br>
-        <br>
-        <br>
-        <div class="buttonBox">
-          <!-- 取消绑定微信,返回登录页 -->
-          <van-button round type="primary" class="register" @click="cancelClick">{{ $t('bindWechat.cancel') }}
-          </van-button>
-          <!-- 用户回车,默认触发 form 表单提交操作 -->
-          <van-button round type="primary" native-type="submit" id="bind-btn">{{ $t('bindWechat.bindCommit') }}
-          </van-button>
+    <s-header :name="$t('wechat.headerName')" :noback="false" />
+
+    <!-- 内容区域 -->
+    <div class="content">
+      <!-- 欢迎标题 -->
+      <div class="welcome">
+        <h2 class="title">{{ $t("bindWechat.welcomeTitle") }}</h2>
+        <p class="subtitle">{{ $t("bindWechat.welcomeSubtitle") }}</p>
+      </div>
+
+      <!-- 微信头像卡片 -->
+      <div class="avatar-card">
+        <div class="avatar-container">
+          <van-image
+            width="120px"
+            height="120px"
+            fit="cover"
+            :src="wechatInfo.avatarUrl"
+            radius="50%"
+            class="avatar-image"
+          />
+          <div class="avatar-ring"></div>
         </div>
+      </div>
 
-      </van-form>
+      <!-- 底部按钮区域 -->
+      <div class="action-buttons">
+        <van-button
+          v-if="wechatInfo.avatarUrl !== ''"
+          round
+          class="cancel-btn"
+          @click="unbindClick"
+        >
+          <van-icon name="close" class="btn-icon" size="20px" />
+          {{ $t("bindWechat.unbind") }}
+        </van-button>
+
+        <van-button
+          v-if="wechatInfo.avatarUrl === ''"
+          round
+          type="primary"
+          class="bind-btn"
+          @click="onSubmit"
+        >
+          <van-icon name="wechat" class="btn-icon" size="20px" />
+          {{ $t("bindWechat.bindCommit") }}
+        </van-button>
+      </div>
     </div>
   </div>
 </template>
 
 <script>
 import { onMounted, reactive, ref } from "vue";
-import { showSuccessToast, showFailToast } from 'vant';
-import { bindWechat, getAvatar } from "@/service/bindWechat";
-import { setLocal, getLocal, navigatorLanguage, getLoginUser, styleUrl } from "@/common/js/utils";
+import { showSuccessToast, showFailToast, showConfirmDialog } from "vant";
+import { bindWechat, getAvatar, unbindWechat } from "@/service/bindWechat";
+import {
+  setLocal,
+  getLocal,
+  navigatorLanguage,
+  getLoginUser,
+} from "@/common/js/utils";
 import sHeader from "@/components/SimpleHeader";
 import logiLogoImgUrl from "@/assets/login/logo.png";
 import { useRouter } from "vue-router";
 import { useI18n } from "vue-i18n";
 
 export default {
-  setup: function () {
+  setup() {
     let languageName = ref(getLocal("curLang"));
-    // eslint-disable-next-line no-unused-vars
     const { t } = useI18n();
 
     const checked = ref(false); // 是否记住密码状态
@@ -50,7 +80,6 @@ export default {
     // 页面初始化
     onMounted(async () => {
       // 加载样式
-      styleUrl('bindWechat');
       // localStorage.clear();
       // 如果没有语言缓存
       if (!getLocal("curLang")) {
@@ -62,23 +91,37 @@ export default {
 
     const user = getLoginUser();
 
-    // 返回用户页
-    const cancelClick = async () => {
-      await router.push("/user");
-    }
+    // 解绑
+    const unbindClick = async () => {
+      showConfirmDialog({
+        title: t("user.tips"),
+        message: t("bindWechat.unbindTips"),
+      })
+        .then(async () => {
+          const { data } = await unbindWechat({ adminId: user.id });
+          if (data.code === "00000") {
+            showSuccessToast(t("bindWechat.unbindSuccess"));
+            setTimeout(() => {
+              router.go(0);
+            }, 1500);
+          } else {
+            showFailToast(data.message);
+          }
+        })
+        .catch((error) => {
+          console.error(error);
+        });
+    };
 
     // 绑定微信
     const onSubmit = async () => {
       try {
-        const { data } = await bindWechat(
-          user.id
-        );
+        const { data } = await bindWechat(user.id);
         if (data.code === "00000") {
-          console.log(data.data);
           // 在当前窗口打开链接
           window.location.href = data.data;
           // 绑定成功
-          showSuccessToast("绑定成功")
+          showSuccessToast(t("bindWechat.bindSuccess"));
         } else {
           showFailToast("调用微信授权失败");
         }
@@ -90,8 +133,8 @@ export default {
 
     // 存储微信头像的链接
     const wechatInfo = reactive({
-      avatarUrl: ''
-    })
+      avatarUrl: "",
+    });
 
     // 在页面加载时调用后端接口获取信息
     onMounted(async () => {
@@ -101,7 +144,7 @@ export default {
       } catch (error) {
         console.error("获取微信头像失败");
       }
-    })
+    });
 
     return {
       logiLogoImgUrl,
@@ -110,8 +153,8 @@ export default {
       userPwd,
       onSubmit,
       sys,
-      cancelClick,
-      wechatInfo
+      unbindClick,
+      wechatInfo,
     };
   },
   components: { sHeader },
@@ -119,5 +162,135 @@ export default {
 </script>
 
 <style lang="less" scoped>
-@import "../common/style/mixin";
+@primary-color: #2c87c8;
+@light-blue: #5b86e5;
+@light-cyan: #36d1dc;
+@text-dark: #333;
+@text-gray: #666;
+@border-color: #e4e7ec;
+@bg-color: #f8fafb;
+@success-green: #4caf50;
+@card-bg: #ffffff;
+@radius: 16px;
+
+.bindWechat {
+  display: flex;
+  flex-direction: column;
+  height: 100vh;
+  width: 100%;
+  background: @bg-color;
+}
+
+.content {
+  flex: 1;
+  overflow: auto;
+  overflow-x: hidden;
+  width: 100%;
+}
+
+.welcome {
+  text-align: center;
+  margin-bottom: 40px;
+
+  .title {
+    font-size: 24px;
+    font-weight: 600;
+    color: @text-dark;
+    margin-bottom: 12px;
+    position: relative;
+
+    &::after {
+      content: "";
+      position: absolute;
+      bottom: -8px;
+      left: 50%;
+      transform: translateX(-50%);
+      width: 40px;
+      height: 3px;
+      background: linear-gradient(to right, @light-cyan, @light-blue);
+      border-radius: 2px;
+    }
+  }
+
+  .subtitle {
+    font-size: 15px;
+    color: @text-gray;
+    line-height: 1.6;
+    max-width: 320px;
+    margin: 0 auto;
+  }
+}
+
+.avatar-card {
+  display: flex;
+  justify-content: center;
+  margin-bottom: 20px;
+}
+
+.avatar-container {
+  margin-bottom: 25px;
+
+  .avatar-image {
+    border: 3px solid white;
+    box-shadow: 0 10px 25px rgba(0, 0, 0, 0.12);
+  }
+}
+
+.action-buttons {
+  display: flex;
+  justify-content: center;
+
+  .cancel-btn {
+    border: 1px solid @border-color;
+    background: #fb725f;
+    color: #f5f7ff;
+    transition: all 0.3s ease;
+    padding: 0 55px;
+
+    .btn-icon {
+      margin-right: 5px;
+    }
+
+    &:active {
+      background: #f5f7ff;
+    }
+  }
+
+  .bind-btn {
+    background: linear-gradient(to right, @light-cyan, @light-blue);
+    border: none;
+    box-shadow: 0 5px 15px rgba(91, 134, 229, 0.4);
+    transition: all 0.3s ease;
+    padding: 0 55px;
+
+    .btn-icon {
+      margin-right: 5px;
+    }
+
+    &:active {
+      transform: translateY(2px);
+      box-shadow: 0 3px 10px rgba(91, 134, 229, 0.4);
+    }
+  }
+}
+
+// 响应式设计
+@media (max-width: 480px) {
+  .welcome {
+    .title {
+      font-size: 22px;
+    }
+
+    .subtitle {
+      font-size: 14px;
+    }
+  }
+
+  .avatar-container {
+    .avatar-image {
+      width: 100px;
+      height: 100px;
+    }
+  }
+}
 </style>

+ 147 - 56
src/views/device/alarmClock.vue

@@ -7,7 +7,7 @@
       <!-- 添加按钮 -->
       <div class="add-button" @click="addAlarmClock">
         <van-icon name="plus" class="add-icon" />
-        <span>{{ $t('device.addAlarmClock') }}</span>
+        <span>{{ $t("device.addAlarmClock") }}</span>
       </div>
 
       <!-- 分隔线 -->
@@ -35,11 +35,26 @@
 
           <!-- 右侧操作区 -->
           <div class="action-group">
-            <van-switch :model-value="item.status" :active-value="'1'" :inactive-value="'0'" size="20px"
-              @change="updateStatus(item, value)" />
+            <van-switch
+              :model-value="item.status"
+              :active-value="'1'"
+              :inactive-value="'0'"
+              size="20px"
+              @change="updateStatus(item, value)"
+            />
             <div class="action-buttons">
-              <van-button icon="edit" size="small" class="edit-btn" @click="setAlarm(item)" />
-              <van-button icon="delete" size="small" class="delete-btn" @click="deleteAlarm(item.id)" />
+              <van-button
+                icon="edit"
+                size="small"
+                class="edit-btn"
+                @click="setAlarm(item)"
+              />
+              <van-button
+                icon="delete"
+                size="small"
+                class="delete-btn"
+                @click="deleteAlarm(item.id)"
+              />
             </div>
           </div>
         </div>
@@ -48,13 +63,18 @@
   </div>
 </template>
 <script>
-import { onMounted, ref } from 'vue';
+import { onMounted, ref } from "vue";
 import sHeader from "@/components/SimpleHeader";
-import { getAlaramClockList, getAlaramClockByDevice, deleteAlaramClock, updateAlaramClockStatus } from '@/service/device'
-import { showConfirmDialog, showFailToast, showSuccessToast } from 'vant';
-import { getLoginUser } from '@/common/js/utils';
-import { useRoute, useRouter } from 'vue-router';
-import { useI18n } from 'vue-i18n';
+import {
+  getAlaramClockList,
+  getAlaramClockByDevice,
+  deleteAlaramClock,
+  alaramClockUpdate,
+} from "@/service/device";
+import { showConfirmDialog, showFailToast, showSuccessToast } from "vant";
+import { getLoginUser } from "@/common/js/utils";
+import { useRoute, useRouter } from "vue-router";
+import { useI18n } from "vue-i18n";
 
 export default {
   setup() {
@@ -73,7 +93,10 @@ export default {
     // 获取设备列表数据
     const getAlaramClockListFun = async () => {
       if (deviceId.value) {
-        const { data } = await getAlaramClockByDevice({ equipmentId: deviceId.value, adminId: user.id });
+        const { data } = await getAlaramClockByDevice({
+          equipmentId: deviceId.value,
+          adminId: user.id,
+        });
         if (data.code) {
           list.value = data.data;
         }
@@ -83,71 +106,130 @@ export default {
           list.value = data.data;
         }
       }
-    }
+    };
 
     const addAlarmClock = () => {
-      router.push({ path: 'alarmClockAdd', query: { deviceId: route.query.deviceId } })
-    }
+      router.push({
+        path: "alarmClockAdd",
+        query: { deviceId: route.query.deviceId },
+      });
+    };
 
     const showTypeText = (e) => {
-      if (e === '0') { return t('device.furnaceHeadOn'); }
-      if (e === '1') { return t('device.furnaceHeadClosed'); }
-      if (e === '2') { return t('device.startSleep'); }
-      if (e === '3') { return t('device.endSleep'); }
-      return '';
-    }
+      if (e === "0") {
+        return t("device.furnaceHeadOn");
+      }
+      if (e === "1") {
+        return t("device.furnaceHeadClosed");
+      }
+      if (e === "2") {
+        return t("device.startSleep");
+      }
+      if (e === "3") {
+        return t("device.endSleep");
+      }
+      return "";
+    };
 
     const showWeek = (e) => {
-      if (e.indexOf('1') > -1 && e.indexOf('2') > -1 && e.indexOf('3') > -1 && e.indexOf('4') > -1 && e.indexOf('5') > -1 && e.indexOf('6') > -1 && e.indexOf('7') > -1) {
-        return t('device.everyDay')
+      if (
+        e.indexOf("1") > -1 &&
+        e.indexOf("2") > -1 &&
+        e.indexOf("3") > -1 &&
+        e.indexOf("4") > -1 &&
+        e.indexOf("5") > -1 &&
+        e.indexOf("6") > -1 &&
+        e.indexOf("7") > -1
+      ) {
+        return t("device.everyDay");
+      }
+      if (
+        e.indexOf("1") > -1 &&
+        e.indexOf("2") > -1 &&
+        e.indexOf("3") > -1 &&
+        e.indexOf("4") > -1 &&
+        e.indexOf("5") > -1 &&
+        e.indexOf("6") == -1 &&
+        e.indexOf("7") == -1
+      ) {
+        return t("device.weekday2");
+      }
+      if (
+        e.indexOf("1") == -1 &&
+        e.indexOf("2") == -1 &&
+        e.indexOf("3") == -1 &&
+        e.indexOf("4") == -1 &&
+        e.indexOf("5") == -1 &&
+        e.indexOf("6") > -1 &&
+        e.indexOf("7") > -1
+      ) {
+        return t("device.weekend2");
+      }
+      let retVal = "";
+      if (e.indexOf("1") > -1) {
+        retVal = retVal + `${t("device.monday")} `;
+      }
+      if (e.indexOf("2") > -1) {
+        retVal = retVal + `${t("device.tuesday")} `;
       }
-      if (e.indexOf('1') > -1 && e.indexOf('2') > -1 && e.indexOf('3') > -1 && e.indexOf('4') > -1 && e.indexOf('5') > -1 && e.indexOf('6') == -1 && e.indexOf('7') == -1) {
-        return t('device.weekday2')
+      if (e.indexOf("3") > -1) {
+        retVal = retVal + `${t("device.wednesday")} `;
       }
-      // if (e === '1,2,3,4,5,') { return t('device.weekday2') }
-      // if (e === '6,7,') { return t('device.weekend2') }
-      if (e.indexOf('1') == -1 && e.indexOf('2') == -1 && e.indexOf('3') == -1 && e.indexOf('4') == -1 && e.indexOf('5') == -1 && e.indexOf('6') > -1 && e.indexOf('7') > -1) {
-        return t('device.weekend2')
+      if (e.indexOf("4") > -1) {
+        retVal = retVal + `${t("device.thursday")} `;
+      }
+      if (e.indexOf("5") > -1) {
+        retVal = retVal + `${t("device.friday")} `;
+      }
+      if (e.indexOf("6") > -1) {
+        retVal = retVal + `${t("device.saturday")} `;
+      }
+      if (e.indexOf("7") > -1) {
+        retVal = retVal + `${t("device.sunday")} `;
       }
-      let retVal = '';
-      if (e.indexOf('1') > -1) { retVal = retVal + `${t('device.monday')} ` }
-      if (e.indexOf('2') > -1) { retVal = retVal + `${t('device.tuesday')} ` }
-      if (e.indexOf('3') > -1) { retVal = retVal + `${t('device.wednesday')} ` }
-      if (e.indexOf('4') > -1) { retVal = retVal + `${t('device.thursday')} ` }
-      if (e.indexOf('5') > -1) { retVal = retVal + `${t('device.friday')} ` }
-      if (e.indexOf('6') > -1) { retVal = retVal + `${t('device.saturday')} ` }
-      if (e.indexOf('7') > -1) { retVal = retVal + `${t('device.sunday')} ` }
       return retVal;
-    }
+    };
 
     const deleteAlarm = async (id) => {
       showConfirmDialog({
-        title: t('device.operationConfirmation'),
-        message: t('device.pleaseConfirmAgainWhetherToOperate'),
+        title: t("device.operationConfirmation"),
+        message: t("device.pleaseConfirmAgainWhetherToOperate"),
       }).then(async () => {
         const { data } = await deleteAlaramClock({ id: id });
         if (data.code) {
-          showSuccessToast(t('device.deletionSucceeded'));
+          showSuccessToast(t("device.deletionSucceeded"));
           setTimeout(() => {
             getAlaramClockListFun();
           }, 1000);
-        } else { showFailToast(data.message); }
-      })
-    }
+        } else {
+          showFailToast(data.message);
+        }
+      });
+    };
 
     const setAlarm = async (item) => {
-      router.push({ path: 'alarmClockSet', query: { alarmId: item.id } });
-    }
+      router.push({ path: "alarmClockSet", query: { alarmId: item.id } });
+    };
 
     // 修改状态
     const updateStatus = async (item) => {
+      console.log(item);
+      const params = {
+        id: item.id,
+        adminId: item.adminId,
+        equipmentIds: item.equipmentIds,
+        hour: item.hour,
+        name: item.name,
+        status: item.status === "1" ? "0" : "1",
+        type: item.type,
+        week: item.week,
+      };
+      console.log(params);
       showConfirmDialog({
-        title: t('device.operationConfirmation'),
-        message: t('device.pleaseConfirmAgainWhetherToOperate'),
+        title: t("device.operationConfirmation"),
+        message: t("device.pleaseConfirmAgainWhetherToOperate"),
       }).then(async () => {
-        if (item.status == '1') { item.status = '0'; } else { item.status = '1'; }
-        const { data } = await updateAlaramClockStatus({ id: item.id, status: item.status });
-        console.log("data", data);
+        const { data } = await alaramClockUpdate(params);
         if (data.code) {
           showSuccessToast(t("device.modificationSucceeded"));
           setTimeout(() => {
@@ -156,10 +238,18 @@ export default {
         } else {
           showFailToast(data.message);
         }
-      })
-    }
-
-    return { list, addAlarmClock, showTypeText, showWeek, deleteAlarm, setAlarm, updateStatus };
+      });
+    };
+
+    return {
+      list,
+      addAlarmClock,
+      showTypeText,
+      showWeek,
+      deleteAlarm,
+      setAlarm,
+      updateStatus,
+    };
   },
   components: { sHeader },
 };
@@ -289,4 +379,5 @@ export default {
       }
     }
   }
-}</style>
+}
+</style>

+ 41 - 84
src/views/device/deviceOper.vue

@@ -98,7 +98,7 @@
 
       <!-- 关闭炉头/设备 -->
       <div
-        v-if="controlList.includes('C4')"
+      v-if="controlList.includes('C4') && device.equimentType != 'SBM10'"
         class="operation-item"
         @click="openOffFurnace(0)"
       >
@@ -363,30 +363,6 @@
           <span class="operation-text">{{ $t("remote.C28") }}</span>
         </div>
       </div>
-      <!-- 物料监控 -->
-      <div
-        v-if="device.equimentType != 'SI320' && controlList.includes('C12')"
-        class="operation-item"
-        @click="materialMonitorClk()"
-      >
-        <div class="icon-wrapper">
-          <img
-            class="operation-icon"
-            v-if="materialIcon === '0'"
-            src="../../assets/device/operIcon/materialMonitor.png"
-            alt="materialMonitor"
-          />
-          <img
-            class="operation-icon"
-            v-else
-            src="../../assets/device/operIcon/materialMonitorOff.png"
-            alt="materialMonitorOff"
-          />
-        </div>
-        <div class="text-wrapper">
-          <span class="operation-text">{{ materialTitle }}</span>
-        </div>
-      </div>
       <!-- 屏蔽/展示商品 -->
       <div
         v-if="controlList.includes('C13')"
@@ -633,6 +609,19 @@
           <span class="operation-text">{{ $t("remote.C32") }}</span>
         </div>
       </div>
+      <!-- 商品管理 -->
+      <div v-if="user.type == 0" class="operation-item" @click="goodsManClk()">
+        <div class="icon-wrapper">
+          <img
+            class="operation-icon"
+            src="../../assets/device/operIcon/goodsMan.png"
+            alt="goodsMan"
+          />
+        </div>
+        <div class="text-wrapper">
+          <span class="operation-text">{{ $t("remote.C33") }}</span>
+        </div>
+      </div>
     </div>
   </van-dialog>
   <van-dialog
@@ -651,11 +640,8 @@ import { onMounted, ref, onBeforeUnmount } from "vue";
 import {
   setFurnace,
   sleepEquipment,
-  // openDoor,
-  Api_openDoor,
   deviceTuoji,
   delOneDevice,
-  enableMaterial,
   restartScreen,
   machineReset,
   changeWorkingMode,
@@ -784,6 +770,13 @@ export default {
         },
       });
     };
+    // 点击修改价格
+    const goodsManClk = () => {
+      router.push({
+        path: "goodsMan",
+        query: { deviceId: device.value.id, name: device.value.name },
+      });
+    };
     const { t } = useI18n();
     const user = getLoginUser();
     const router = useRouter();
@@ -854,24 +847,14 @@ export default {
       operCheckShow.value = true;
     };
     // 远程开门
-    /*    const openDoorFun = () => {
-          operType.value = 4;
-          operCheckShow.value = true;
-        }; */
     const openDoorFun = () => {
-      if (device.value.machineType === "2") {
-        operType.value = 4;
-        operCheckShow.value = true;
-      } else {
-        // router.push({ path: "openDoor", query: { deviceId: device.value.id } });
-        router.push({
-          path: "openDoor",
-          query: {
-            deviceId: device.value.id,
-            machineType: device.value.machineType,
-          },
-        });
-      }
+      router.push({
+        path: "openDoor",
+        query: {
+          deviceId: device.value.id,
+          machineType: device.value.machineType,
+        },
+      });
     };
     // 日志功能
     const viewLogs = () => {
@@ -936,7 +919,11 @@ export default {
     const changePasswordClk = () => {
       router.push({
         path: "devicePassword",
-        query: { deviceId: device.value.id, name: device.value.name },
+        query: {
+          deviceId: device.value.id,
+          name: device.value.name,
+          equimentType: device.value.equimentType,
+        },
       });
     };
     // 删除设备
@@ -980,7 +967,7 @@ export default {
           }
         } else {
           const { data } = await setFurnace({
-            equipmentId: device.value.id,
+            id: device.value.id,
             eqeStatus: 1,
           });
           if (data.code) {
@@ -994,12 +981,14 @@ export default {
       // 睡眠
       if (operType.value === 2) {
         const { data } = await sleepEquipment({
-          equipmentId: device.value.id,
-          eqeStatus: device.value.isSleep ? "0" : "1",
+          id: device.value.id,
+          isSleep: device.value.isSleep ? "0" : "1",
         });
         if (data.code) {
           showSuccessToast(t("device.sleepSuccessfully"));
-          operCheckShow.value = false;
+          setTimeout(() => {
+            operCheckShow.value = false;
+          }, 1500);
         } else {
           showFailToast(data.message);
         }
@@ -1008,7 +997,7 @@ export default {
       if (operType.value === 3) {
         device.value.eqeStatus = clkOpenOrClose.value;
         const { data } = await setFurnace({
-          equipmentId: device.value.id,
+          id: device.value.id,
           eqeStatus: device.value.eqeStatus,
         });
         if (data.code) {
@@ -1025,21 +1014,6 @@ export default {
           showFailToast(data.message);
         }
       }
-      // 远程开门
-      if (operType.value === 4) {
-        // const { data } = await openDoor({ equipmentId: device.value.id });
-        const { data } = await Api_openDoor({
-          equipmentId: device.value.id,
-          type: 0,
-          status: 1,
-        });
-        if (data.code) {
-          showSuccessToast(t("device.remoteDoorOpeningSucceeded"));
-          operCheckShow.value = false;
-        } else {
-          showFailToast(data.message);
-        }
-      }
       // 系统脱机
       if (operType.value === 5) {
         const { data } = await deviceTuoji({
@@ -1067,24 +1041,6 @@ export default {
           showFailToast(t("device.deleteDeviceFailed"));
         }
       }
-      // 启用物料监控
-      if (operType.value === 7) {
-        let materialMonitorStatus = 0; // 0默认是未开启
-        // isMaterialUse是1时,物料监控已启用,按钮是关闭功能
-        if (device.value.isMaterialUse === "1") {
-          materialMonitorStatus = 1; // 1代表已开启
-        }
-        const { data } = await enableMaterial({
-          equipmentId: device.value.id,
-          materialMonitorStatus,
-        });
-        if (data.code === "00000") {
-          showSuccessToast(t("device.enableMaterialSucceed"));
-          operCheckShow.value = false;
-        } else {
-          showFailToast(t("device.enableMaterialFailed"));
-        }
-      }
       // 重启触摸屏
       if (operType.value === 9) {
         const { data } = await restartScreen({
@@ -1144,6 +1100,7 @@ export default {
       tuojiEquipmentFun,
       isRole,
       modifyPriceClk,
+      goodsManClk,
       showGoodsClk,
       diyFlowerClk,
       sleepTitle,

+ 471 - 424
src/views/device/devicePassword/index.vue

@@ -1,431 +1,478 @@
 <template>
-	<div class="password-manager">
-	  <s-header :name="$t('device.devicePasswordPage.title')" :noback="false" />
-  
-	  <!-- 设备信息卡片 -->
-	  <div class="device-card">
-		<div class="device-header">
-		  <div class="header-indicator"></div>
-		  <h3 class="device-name">
-			{{ $t("device.devicePasswordPage.equipmentName") }}:{{
-			  equipmentName
-			}}
-		  </h3>
-		</div>
-	  </div>
-  
-	  <!-- 密码类型选择 -->
-	  <van-config-provider :theme-vars="themeVars">
-		<div class="password-selector">
-		  <van-dropdown-menu :overlay="false">
-			<van-dropdown-item
-			  v-model="pwdValue"
-			  :options="pwdType"
-			  class="modern-dropdown"
-			/>
-		  </van-dropdown-menu>
-  
-		  <!-- 密码表单 -->
-		  <div class="form-card">
-			<van-form @submit="onSubmit">
-			  <van-cell-group inset>
-				<!-- 管理员密码 -->
-				<template v-if="pwdValue === 0">
-				  <van-field
-					v-model="adminPwd"
-					type="password"
-					:label="$t('device.devicePasswordPage.deivcePwd')"
-					:placeholder="
-					  $t('device.devicePasswordPage.passwordPlaceholder')
-					"
-					:rules="[{ validator, message: $t('device.devicePasswordPage.passwordPlaceholder') }]"
-					class="password-field"
-				  >
-					<template #left-icon>
-					  <van-icon name="lock" class="field-icon" />
-					</template>
-				  </van-field>
-				  <van-field
-					v-model="checkAmdinPwd"
-					type="password"
-					:label="$t('device.devicePasswordPage.checkDeivcePwd')"
-					:placeholder="
-					  $t('device.devicePasswordPage.passwordCheckRequired')
-					"
-					:rules="[{ validator, message: $t('device.devicePasswordPage.passwordPlaceholder') }]"
-					class="password-field"
-				  >
-					<template #left-icon>
-					  <van-icon name="certificate" class="field-icon" />
-					</template>
-				  </van-field>
-				</template>
-  
-				<!-- 访客密码 -->
-				<template v-else>
-				  <van-field
-					v-model="guestPwd"
-					type="password"
-					:label="$t('device.devicePasswordPage.deivcePwd')"
-					:placeholder="
-					  $t('device.devicePasswordPage.passwordPlaceholder')
-					"
-					:rules="[{ validator, message: $t('device.devicePasswordPage.passwordPlaceholder') }]"
-					class="password-field"
-				  >
-					<template #left-icon>
-					  <van-icon name="lock" class="field-icon" />
-					</template>
-				  </van-field>
-				  <van-field
-					v-model="checkGuestPwd"
-					type="password"
-					:label="$t('device.devicePasswordPage.checkDeivcePwd')"
-					:placeholder="
-					  $t('device.devicePasswordPage.passwordCheckRequired')
-					"
-					:rules="[{ validator, message: $t('device.devicePasswordPage.passwordPlaceholder') }]"
-					class="password-field"
-				  >
-					<template #left-icon>
-					  <van-icon name="certificate" class="field-icon" />
-					</template>
-				  </van-field>
-				</template>
-			  </van-cell-group>
-  
-			  <!-- 提交按钮 -->
-			  <div class="submit-section">
-				<van-button
-				  round
-				  block
-				  type="primary"
-				  native-type="submit"
-				  class="submit-btn"
-				>
-				  <template #loading>
-					<van-loading type="spinner" size="20px" />
-				  </template>
-				  {{ $t("device.submitAndPushDeviceUpdates") }}
-				</van-button>
-			  </div>
-			</van-form>
-		  </div>
-		</div>
-	  </van-config-provider>
-	</div>
-  </template>
-  
-  <script>
-  // 导入接口
-  import { updateDevicePassword } 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 { showNotify, showDialog, showConfirmDialog, showFailToast } from "vant";
-  import { useI18n } from "vue-i18n";
-  export default {
-	components: {
-	  sHeader,
-	},
-	setup() {
-	  // 引入语言
-	  const { t } = useI18n();
-	  // 路由
-	  const route = useRoute();
-	  const router = useRouter();
-	  // 设备名称
-	  const equipmentName = ref("");
-	  const pwdValue = ref();
-	  const adminPwd = ref();
-	  const checkAmdinPwd = ref();
-	  const guestPwd = ref();
-	  const checkGuestPwd = ref();
-  
-	  const validator = (val) => /\w{6,}/.test(val);
-	  const themeVars = {
-		dropdownMenuTitleTextColor: "#404d74",
-	  };
-	  const pwdType = [
-		{
-		  text: t("device.devicePasswordPage.adminPassword"),
-		  value: 0,
-		},
-		{
-		  text: t("device.devicePasswordPage.guestPassword"),
-		  value: 1,
-		},
-	  ];
-	  // 刚进页面
-	  onMounted(() => {
-		// 加载样式
-		pwdValue.value = pwdType[0].value;
-		const id = route.query.deviceId || "";
-		const name = route.query.name || "";
-		if (id) {
-		  passwordForm.equipmentId = id;
-		  equipmentName.value = name;
-		}
-	  });
-	  // 修改的价格
-	  const passwordForm = reactive({
-		equipmentId: "",
-		adminPwd: "",
-		guestPwd: "",
-	  });
-  
-	  // 点击提交
-	  const onSubmit = () => {
-		passwordForm.adminPwd = adminPwd.value;
-		passwordForm.guestPwd = guestPwd.value;
-		console.log(passwordForm);
-		if (
-		  passwordForm.adminPwd != checkAmdinPwd.value ||
-		  passwordForm.guestPwd != checkGuestPwd.value
-		) {
-		  showNotify({
-			type: "danger",
-			message: t("device.devicePasswordPage.passwordMatch"),
-		  });
-		  return;
-		}
-		if (pwdValue.value == 0) {
-		  passwordForm.guestPwd = "";
-		}
-		if (pwdValue.value == 1) {
-		  passwordForm.adminPwd = "";
-		}
-		showConfirmDialog({
-		  // title: "提示",
-		  message: t("device.editCheck"),
-		}).then(() => {
-		  console.log(passwordForm);
-		  updateDevicePassword({
-			equipmentId: passwordForm.equipmentId,
-			adminPwd: passwordForm.adminPwd,
-			guestPwd: passwordForm.guestPwd,
-		  }).then((res) => {
-			if (res.data.code == "A0001") {
-			  showFailToast(t("device.unknownError"));
-			  return;
-			}
-			showDialog({
-			  message: t("device.modificationSucceeded"),
-			}).then(() => {
-			  //返回上一页
-			  router.go(-1);
-			});
-		  });
-		});
-	  };
-  
-	  return {
-		passwordForm,
-		equipmentName,
-		pwdType,
-		pwdValue,
-		adminPwd,
-		checkAmdinPwd,
-		guestPwd,
-		checkGuestPwd,
-		onSubmit,
-		validator,
-		themeVars,
-	  };
-	},
-  };
-  </script>
-  
-  <style lang="less" scoped>
-  @primary-color: #2d88c9;
-  @card-bg: #ffffff;
-  @text-primary: #2d3436;
-  @border-color: #e4e7ec;
-  @title-color: #404d74;
-  @active-color: #2d88c9;
-  @item-padding: 16px 24px;
-  @card-shadow: 0 4px 20px rgba(77, 106, 221, 0.1);
-  
-  .password-manager {
-	background: #f8fafb;
-	min-height: 100vh;
+  <div class="password-manager">
+    <s-header :name="$t('device.devicePasswordPage.title')" :noback="false" />
+
+    <!-- 设备信息卡片 -->
+    <div class="device-card">
+      <div class="device-header">
+        <div class="header-indicator"></div>
+        <h3 class="device-name">
+          {{ $t("device.devicePasswordPage.equipmentName") }}:{{
+            equipmentName
+          }}
+        </h3>
+      </div>
+    </div>
+
+    <!-- 密码类型选择 -->
+    <van-config-provider :theme-vars="themeVars">
+      <div class="password-selector">
+        <van-dropdown-menu :overlay="false">
+          <van-dropdown-item
+            v-model="pwdValue"
+            :options="pwdType"
+            class="modern-dropdown"
+          />
+        </van-dropdown-menu>
+
+        <!-- 密码表单 -->
+        <div class="form-card">
+          <van-form @submit="onSubmit">
+            <van-cell-group inset>
+              <!-- 管理员密码 -->
+              <template v-if="pwdValue === 0">
+                <van-field
+                  v-model="adminPwd"
+                  type="password"
+                  :label="$t('device.devicePasswordPage.deivcePwd')"
+                  :placeholder="
+                    $t('device.devicePasswordPage.passwordPlaceholder')
+                  "
+                  :rules="[
+                    {
+                      validator,
+                      message: $t(
+                        'device.devicePasswordPage.passwordPlaceholder'
+                      ),
+                    },
+                  ]"
+                  class="password-field"
+                >
+                  <template #left-icon>
+                    <van-icon name="lock" class="field-icon" />
+                  </template>
+                </van-field>
+                <van-field
+                  v-model="checkAmdinPwd"
+                  type="password"
+                  :label="$t('device.devicePasswordPage.checkDeivcePwd')"
+                  :placeholder="
+                    $t('device.devicePasswordPage.passwordCheckRequired')
+                  "
+                  :rules="[
+                    {
+                      validator,
+                      message: $t(
+                        'device.devicePasswordPage.passwordPlaceholder'
+                      ),
+                    },
+                  ]"
+                  class="password-field"
+                >
+                  <template #left-icon>
+                    <van-icon name="certificate" class="field-icon" />
+                  </template>
+                </van-field>
+              </template>
+
+              <!-- 访客密码 -->
+              <template v-else>
+                <van-field
+                  v-model="guestPwd"
+                  type="password"
+                  :label="$t('device.devicePasswordPage.deivcePwd')"
+                  :placeholder="
+                    $t('device.devicePasswordPage.passwordPlaceholder')
+                  "
+                  :rules="[
+                    {
+                      validator,
+                      message: $t(
+                        'device.devicePasswordPage.passwordPlaceholder'
+                      ),
+                    },
+                  ]"
+                  class="password-field"
+                >
+                  <template #left-icon>
+                    <van-icon name="lock" class="field-icon" />
+                  </template>
+                </van-field>
+                <van-field
+                  v-model="checkGuestPwd"
+                  type="password"
+                  :label="$t('device.devicePasswordPage.checkDeivcePwd')"
+                  :placeholder="
+                    $t('device.devicePasswordPage.passwordCheckRequired')
+                  "
+                  :rules="[
+                    {
+                      validator,
+                      message: $t(
+                        'device.devicePasswordPage.passwordPlaceholder'
+                      ),
+                    },
+                  ]"
+                  class="password-field"
+                >
+                  <template #left-icon>
+                    <van-icon name="certificate" class="field-icon" />
+                  </template>
+                </van-field>
+              </template>
+            </van-cell-group>
+
+            <!-- 提交按钮 -->
+            <div class="submit-section">
+              <van-button
+                round
+                block
+                type="primary"
+                native-type="submit"
+                class="submit-btn"
+              >
+                <template #loading>
+                  <van-loading type="spinner" size="20px" />
+                </template>
+                {{ $t("device.submitAndPushDeviceUpdates") }}
+              </van-button>
+            </div>
+          </van-form>
+        </div>
+      </div>
+    </van-config-provider>
+  </div>
+</template>
+
+<script>
+// 导入接口
+import { updateDevicePassword, changePassword } 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 {
+  showNotify,
+  showConfirmDialog,
+  showFailToast,
+  showSuccessToast,
+} from "vant";
+import { useI18n } from "vue-i18n";
+export default {
+  components: {
+    sHeader,
+  },
+  setup() {
+    // 引入语言
+    const { t } = useI18n();
+    // 路由
+    const route = useRoute();
+    const router = useRouter();
+    // 设备名称
+    const equipmentName = ref("");
+    const pwdValue = ref();
+    const adminPwd = ref();
+    const checkAmdinPwd = ref();
+    const guestPwd = ref();
+    const checkGuestPwd = ref();
+    const equimentType = ref(route.query.equimentType || "");
+
+    const validator = (val) => /\w{6,}/.test(val);
+    const themeVars = {
+      dropdownMenuTitleTextColor: "#404d74",
+    };
+    const pwdType = [
+      {
+        text: t("device.devicePasswordPage.adminPassword"),
+        value: 0,
+      },
+      {
+        text: t("device.devicePasswordPage.guestPassword"),
+        value: 1,
+      },
+    ];
+    // 刚进页面
+    onMounted(() => {
+      // 加载样式
+      pwdValue.value = pwdType[0].value;
+      const id = route.query.deviceId || "";
+      const name = route.query.name || "";
+      if (id) {
+        passwordForm.equipmentId = id;
+        equipmentName.value = name;
+      }
+    });
+    // 修改的价格
+    const passwordForm = reactive({
+      equipmentId: "",
+      adminPwd: "",
+      guestPwd: "",
+    });
+
+    // 点击提交
+    const onSubmit = () => {
+      passwordForm.adminPwd = adminPwd.value;
+      passwordForm.guestPwd = guestPwd.value;
+      console.log(passwordForm);
+      if (
+        passwordForm.adminPwd != checkAmdinPwd.value ||
+        passwordForm.guestPwd != checkGuestPwd.value
+      ) {
+        showNotify({
+          type: "danger",
+          message: t("device.devicePasswordPage.passwordMatch"),
+        });
+        return;
+      }
+      if (pwdValue.value == 0) {
+        passwordForm.guestPwd = "";
+      }
+      if (pwdValue.value == 1) {
+        passwordForm.adminPwd = "";
+      }
+      showConfirmDialog({
+        // title: "提示",
+        message: t("device.editCheck"),
+      }).then(() => {
+        if (equimentType.value == "SBM10") {
+          changePassword({
+            id: passwordForm.equipmentId,
+            adminPwd: passwordForm.adminPwd,
+            guestPwd: passwordForm.guestPwd,
+          }).then((res) => {
+            if (res.data.code == "00000") {
+              showSuccessToast(t("device.modificationSucceeded"));
+              setTimeout(() => {
+                router.go(-1);
+              }, 1500);
+            } else {
+              showFailToast(res.data.message);
+            }
+          });
+        } else {
+          updateDevicePassword({
+            equipmentId: passwordForm.equipmentId,
+            adminPwd: passwordForm.adminPwd,
+            guestPwd: passwordForm.guestPwd,
+          }).then((res) => {
+            if (res.data.code == "00000") {
+              showSuccessToast(t("device.modificationSucceeded"));
+              setTimeout(() => {
+                router.go(-1);
+              }, 1500);
+            } else {
+              showFailToast(res.data.message);
+            }
+          });
+        }
+      });
+    };
+
+    return {
+      passwordForm,
+      equipmentName,
+      pwdType,
+      pwdValue,
+      adminPwd,
+      checkAmdinPwd,
+      guestPwd,
+      checkGuestPwd,
+      onSubmit,
+      validator,
+      themeVars,
+    };
+  },
+};
+</script>
+
+<style lang="less" scoped>
+@primary-color: #2d88c9;
+@card-bg: #ffffff;
+@text-primary: #2d3436;
+@border-color: #e4e7ec;
+@title-color: #404d74;
+@active-color: #2d88c9;
+@item-padding: 16px 24px;
+@card-shadow: 0 4px 20px rgba(77, 106, 221, 0.1);
+
+.password-manager {
+  background: #f8fafb;
+  min-height: 100vh;
+}
+
+.device-card {
+  background: #fff;
+  border-radius: 12px;
+  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
+  margin: 10px;
+  padding: 16px;
+
+  .device-header {
+    display: flex;
+    align-items: center;
+
+    .header-indicator {
+      width: 3px;
+      height: 20px;
+      background: @primary-color;
+      margin-right: 12px;
+      border-radius: 2px;
+    }
+
+    .device-name {
+      font-size: 15px;
+      color: #404d74;
+      margin: 0;
+    }
   }
-  
-  .device-card {
-	background: #fff;
-	border-radius: 12px;
-	box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
-	margin: 10px;
-	padding: 16px;
-  
-	.device-header {
-	  display: flex;
-	  align-items: center;
-  
-	  .header-indicator {
-		width: 3px;
-		height: 20px;
-		background: @primary-color;
-		margin-right: 12px;
-		border-radius: 2px;
-	  }
-  
-	  .device-name {
-		font-size: 15px;
-		color: #404d74;
-		margin: 0;
-	  }
-	}
+}
+
+.password-selector {
+  margin: 10px;
+
+  .modern-dropdown {
+    :deep(.van-dropdown-menu__bar) {
+      background: @card-bg;
+      box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
+      overflow: hidden;
+
+      :deep(.van-dropdown-menu__title) {
+        display: flex !important;
+        align-items: center;
+        justify-content: space-between;
+        color: @title-color;
+        font-size: 10px;
+        font-weight: 500;
+        transition: all 0.5s;
+        width: auto !important;
+
+        &::after {
+          content: "";
+          position: relative !important;
+          right: 0 !important;
+          top: 0 !important;
+          transform: none !important;
+          display: inline-block;
+          width: 0;
+          height: 0;
+          border: 5px solid;
+          border-color: @title-color transparent transparent;
+          margin-left: 8px;
+          margin-top: 3px;
+          order: 1;
+          transition: transform 0.5s;
+        }
+
+        &--active {
+          color: @active-color;
+
+          &::after {
+            border-color: @active-color transparent transparent;
+            transform: rotate(-180deg) translateY(2px) !important;
+          }
+        }
+      }
+    }
   }
-  
-  .password-selector {
-	margin: 10px;
-  
-	.modern-dropdown {
-	  :deep(.van-dropdown-menu__bar) {
-		background: @card-bg;
-		box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
-		overflow: hidden;
-  
-		:deep(.van-dropdown-menu__title) {
-		  display: flex !important;
-		  align-items: center;
-		  justify-content: space-between;
-		  color: @title-color;
-		  font-size: 10px;
-		  font-weight: 500;
-		  transition: all 0.5s;
-		  width: auto !important;
-  
-		  &::after {
-			content: "";
-			position: relative !important;
-			right: 0 !important;
-			top: 0 !important;
-			transform: none !important;
-			display: inline-block;
-			width: 0;
-			height: 0;
-			border: 5px solid;
-			border-color: @title-color transparent transparent;
-			margin-left: 8px;
-			margin-top: 3px;
-			order: 1;
-			transition: transform 0.5s;
-		  }
-  
-		  &--active {
-			color: @active-color;
-  
-			&::after {
-			  border-color: @active-color transparent transparent;
-			  transform: rotate(-180deg) translateY(2px) !important;
-			}
-		  }
-		}
-	  }
-	}
-	:deep(.van-dropdown-menu__item) {
-	  flex: 1;
-	  min-width: 82px;
-	  position: relative;
-	  padding: 8px 0px;
-  
-	  &:not(:last-child)::after {
-		content: "";
-		position: absolute;
-		right: 0;
-		top: 50%;
-		transform: translateY(-50%);
-		width: 1px;
-		height: 24px;
-		background: #eef0fa;
-	  }
-	}
-  
-	:deep(.van-dropdown-item) {
-	  margin: 10px;
-  
-	  &__content {
-		left: 0 !important;
-		right: 0 !important;
-		transform: none !important;
-		border-radius: 12px;
-		box-shadow: 0 4px 20px rgba(77, 106, 221, 0.1);
-		border: 0;
-		max-height: 60vh;
-		z-index: 9999;
-		/* 确保层级 */
-	  }
-	}
+  :deep(.van-dropdown-menu__item) {
+    flex: 1;
+    min-width: 82px;
+    position: relative;
+    padding: 8px 0px;
+
+    &:not(:last-child)::after {
+      content: "";
+      position: absolute;
+      right: 0;
+      top: 50%;
+      transform: translateY(-50%);
+      width: 1px;
+      height: 24px;
+      background: #eef0fa;
+    }
   }
-  
+
+  :deep(.van-dropdown-item) {
+    margin: 10px;
+
+    &__content {
+      left: 0 !important;
+      right: 0 !important;
+      transform: none !important;
+      border-radius: 12px;
+      box-shadow: 0 4px 20px rgba(77, 106, 221, 0.1);
+      border: 0;
+      max-height: 60vh;
+      z-index: 9999;
+      /* 确保层级 */
+    }
+  }
+}
+
+.form-card {
+  background: @card-bg;
+  border-radius: 0 0 12px 12px;
+  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
+  padding: 10px;
+
+  .password-field {
+    :deep(.van-field__label) {
+      font-weight: 500;
+    }
+
+    :deep(.van-cell) {
+      background: #f8fafb;
+      border-radius: 8px;
+      // margin: 12px 0;
+      transition: all 0.3s;
+
+      &:focus-within {
+        box-shadow: 0 2px 8px rgba(77, 194, 148, 0.2);
+      }
+    }
+
+    .field-icon {
+      color: @primary-color;
+      margin-right: 12px;
+      font-size: 18px;
+    }
+  }
+
+  .submit-section {
+    margin-top: 32px;
+
+    .submit-btn {
+      height: 48px;
+      font-size: 16px;
+      font-weight: 500;
+      background: linear-gradient(135deg, @primary-color 0%, #3daa80 100%);
+      border: none;
+      transition: transform 0.2s;
+
+      &:active {
+        transform: scale(0.98);
+      }
+    }
+  }
+}
+
+@media (max-width: 480px) {
   .form-card {
-	background: @card-bg;
-	border-radius: 0 0 12px 12px;
-	box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
-	padding: 10px;
-  
-	.password-field {
-	  :deep(.van-field__label) {
-		font-weight: 500;
-	  }
-  
-	  :deep(.van-cell) {
-		background: #f8fafb;
-		border-radius: 8px;
-		// margin: 12px 0;
-		transition: all 0.3s;
-  
-		&:focus-within {
-		  box-shadow: 0 2px 8px rgba(77, 194, 148, 0.2);
-		}
-	  }
-  
-	  .field-icon {
-		color: @primary-color;
-		margin-right: 12px;
-		font-size: 18px;
-	  }
-	}
-  
-	.submit-section {
-	  margin-top: 32px;
-  
-	  .submit-btn {
-		height: 48px;
-		font-size: 16px;
-		font-weight: 500;
-		background: linear-gradient(135deg, @primary-color 0%, #3daa80 100%);
-		border: none;
-		transition: transform 0.2s;
-  
-		&:active {
-		  transform: scale(0.98);
-		}
-	  }
-	}
+    padding: 10px;
+
+    .submit-btn {
+      height: 44px !important;
+      font-size: 14px;
+    }
   }
-  
-  @media (max-width: 480px) {
-	.form-card {
-	  padding: 10px;
-  
-	  .submit-btn {
-		height: 44px !important;
-		font-size: 14px;
-	  }
-	}
-  
-	:deep(.van-dropdown-menu__title) {
-	  padding: 2px 4px !important;
-	  font-size: 12px;
-  
-	  &::after {
-		margin-right: -5px;
-	  }
-	}
+
+  :deep(.van-dropdown-menu__title) {
+    padding: 2px 4px !important;
+    font-size: 12px;
+
+    &::after {
+      margin-right: -5px;
+    }
   }
-  </style>
-  
+}
+</style>

+ 72 - 19
src/views/device/deviceSearch.vue

@@ -31,25 +31,49 @@
           />
           <!-- 公司平台 -->
           <div v-if="isShowCompany()">
-            <van-field
-              label-width="86"
-              v-model="companyTypeText"
-              is-link
-              readonly
-              :label="$t('device.companyTypeLabel')"
-              :placeholder="$t('device.companyTypePlaceholder')"
-              @click="companyTypeShow = true"
-              class="field"
-            />
-            <van-popup v-model:show="companyTypeShow" round position="bottom">
-              <van-cascader
-                v-model="companyType"
-                :title="$t('device.companyTypePlaceholder')"
-                :options="companyTypeOptions"
-                @close="companyTypeShow = false"
-                @finish="companyTypeFinish"
-              />
-            </van-popup>
+            <van-row>
+              <van-col span="12"> 
+                <van-field
+                  label-width="66"
+                  v-model="companyTypeText"
+                  is-link
+                  readonly
+                  :label="$t('device.companyTypeLabel')"
+                  :placeholder="$t('device.companyTypePlaceholder')"
+                  @click="companyTypeShow = true"
+                  class="field"
+                />
+                <van-popup v-model:show="companyTypeShow" round position="bottom">
+                  <van-cascader
+                    v-model="companyType"
+                    :title="$t('device.companyTypePlaceholder')"
+                    :options="companyTypeOptions"
+                    @close="companyTypeShow = false"
+                    @finish="companyTypeFinish"
+                  />
+                </van-popup>
+              </van-col>
+              <van-col span="12"> 
+                <van-field
+                  label-width="66"
+                  v-model="isAbroadText"
+                  is-link
+                  readonly
+                  :label="$t('device.isAbroad')"
+                  :placeholder="$t('device.isAbroadPlaceholder')"
+                  @click="isAbroadShow = true"
+                />
+                <van-popup v-model:show="isAbroadShow" round position="bottom"> 
+                  <van-cascader
+                    v-model="isAbroad"
+                    :title="$t('device.isAbroadPlaceholder')"
+                    :options="isAbroadOptions"
+                    @close="isAbroadShow = false"
+                    @finish="isAbroadFinish"
+                  />
+                </van-popup>
+              </van-col>
+            </van-row>
           </div>
           <!-- <van-field
             v-model="areaName"
@@ -198,8 +222,11 @@ export default {
     const machineTypeShow = ref(false); // 设备类型级联状态
     const companyType = ref(""); // 公司平台
     const deviceGroup = ref(""); // 设备分组
+    const isAbroad = ref(null); // 设备所在地
     const companyTypeText = ref(""); // 公司平台 - 页面显示
     const deviceGroupText = ref(""); // 设备分组 - 页面显示
+    const isAbroadText = ref(""); // 设备所在地_页面显示
+    const isAbroadShow = ref(false); // 设备所在地级联状态
     const companyTypeShow = ref(false); // 公司平台级联状态
     const deviceGroupShow = ref(false); // 设备分组级联状态
     const user = getLoginUser(); // 获取登录用户
@@ -227,6 +254,16 @@ export default {
         value: "1",
       },
     ]);
+    const isAbroadOptions = ref([
+      {
+        text: t("register.chinese"),
+        value: false,
+      },
+      {
+        text: t("register.other"),
+        value: true,
+      },
+    ]);
     const deviceGroupOptions = ref([]);
     const machineTypeFinish = ({ selectedOptions }) => {
       machineTypeShow.value = false;
@@ -277,6 +314,13 @@ export default {
         .join("/");
     }; // 公司平台级联选择
 
+    const isAbroadFinish = ({ selectedOptions }) => { 
+      isAbroadShow.value = false;
+      isAbroadText.value = selectedOptions
+        .map((option) => option.text)
+        .join("/");
+    }; // 设备所在地级联选择
+
     const equimentType = ref(""); // 设备机型
     const equimentTypeText = ref(""); // 设备机型 - 页面显示
     const equimentTypeShow = ref(false); // 设备机型级联状态
@@ -412,6 +456,7 @@ export default {
         isUsing: isUsing.value,
         payType: payType.value,
         channel: channel.value,
+        isAbroad: isAbroad.value,
       };
       context.emit("search", searchParam);
       sheetShow.value = false;
@@ -426,6 +471,8 @@ export default {
       machineTypeText.value = "";
       companyType.value = "";
       companyTypeText.value = "";
+      isAbroad.value = null;
+      isAbroadText.value = "";
       deviceGroup.value = "";
       deviceGroupText.value = "";
       equimentType.value = "";
@@ -520,6 +567,12 @@ export default {
       companyTypeOptions,
       companyTypeFinish,
 
+      isAbroad,
+      isAbroadText,
+      isAbroadShow,
+      isAbroadOptions,
+      isAbroadFinish,
+
       deviceGroup,
       deviceGroupText,
       deviceGroupShow,

+ 51 - 14
src/views/device/deviceSet.vue

@@ -194,6 +194,8 @@
         <van-field
           v-model="deviceDetal.url"
           center
+          autosize
+          type="textarea"
           clearable
           class="form-item"
           :label="$t('device.url')"
@@ -205,6 +207,23 @@
             }}</van-button>
           </template>
         </van-field>
+
+        <van-field
+          v-model="mqttUrl"
+          center
+          autosize
+          type="textarea"
+          clearable
+          class="form-item"
+          label="MQTT URL"
+          :placeholder="$t('device.urlPlace')"
+        >
+          <template #button>
+            <van-button size="small" type="primary" @click="mqttUrlClk">{{
+              $t("device.update")
+            }}</van-button>
+          </template>
+        </van-field>
       </div>
 
       <!-- 操作按钮 -->
@@ -263,15 +282,22 @@ import { Api_getGetEquipmentToLabel } from "@/service/labelMan";
 import kCascader from "@/components/commom/kCascader/index.vue";
 import { computed, onMounted, reactive, ref } from "vue";
 import sHeader from "@/components/SimpleHeader";
-import { useRoute, useRouter, onBeforeRouteLeave } from "vue-router";
+import { useRoute, useRouter } from "vue-router";
 import {
   getDeviceDetal,
   updateDevice,
   Api_getTApkInfo_updateApk,
   Api_getDiscCodeStatus,
   getGoodsNumber,
+  pushAppUpdate,
 } from "@/service/device/index";
-import { showFailToast, showSuccessToast, showToast, closeToast } from "vant";
+import {
+  showFailToast,
+  showSuccessToast,
+  showToast,
+  closeToast,
+  showConfirmDialog,
+} from "vant";
 import { useI18n } from "vue-i18n";
 import dateUtil from "@/utils/dateUtil";
 
@@ -307,13 +333,6 @@ export default {
     let tagsList = reactive({
       arr: [],
     });
-    onBeforeRouteLeave((to, from, next) => {
-      if (isUpdate.value) {
-        // console.log("to.meta.keepAlive>>>", to.meta.keepAlive);
-        // to.meta.keepAlive = false;
-      }
-      next();
-    });
     // 过滤时间
     const filterDate = (date) => {
       if (date) {
@@ -349,11 +368,6 @@ export default {
     };
     // 初始化页面获取列表
     onMounted(async () => {
-      // 加载样式
-      // 从标签设置回来
-      // let tagList = sessionStorage.getItem("tagList") || "[]";
-      // tagsList.arr = JSON.parse(tagList);
-      // sessionStorage.removeItem("tagList");
       getDeviceDetalFun();
       getLabelDetail();
       // 如果user.type<2那么则是公司人员
@@ -520,6 +534,27 @@ export default {
       }
       kDialogRef.value.openDialog();
     };
+    const mqttUrl = ref("");
+    // 点击MQTT的推送app
+    const mqttUrlClk = () => {
+      showConfirmDialog({
+        title: "提醒",
+        message: "是否推送app更新?",
+      }).then(async () => {
+        const { data } = await pushAppUpdate({
+          id: deviceDetal.value.id,
+          url: mqttUrl.value,
+        });
+        if (data.code === "00000") {
+          showSuccessToast("推送成功");
+          setTimeout(() => {
+            router.go(-1);
+          }, 1500);
+        } else {
+          showFailToast(data.message);
+        }
+      });
+    };
     // 点击更新弹窗的确定
     const confirmClk = () => {
       Api_getTApkInfo_updateApk({
@@ -595,6 +630,8 @@ export default {
       getAreaName,
       isAdmind,
       updateUrlClk,
+      mqttUrl,
+      mqttUrlClk,
       confirmClk,
       kDialogRef,
       couponStatusChg,

+ 36 - 16
src/views/device/doSugar.vue

@@ -162,6 +162,7 @@ import {
   getDeviceDetal,
   selectProducts,
   remoteProduction,
+  produceGoods,
   selectSugarStatus,
 } from "@/service/device";
 import {
@@ -296,6 +297,10 @@ export default {
       }
     };
     const submitDoSugar = async () => {
+      if (fieldValue.value === "") {
+        showToast(t("device.pleaseSelectAPattern"));
+        return;
+      }
       const makeCodes = ref([1, 0, 0]);
       doSugartData.value = null;
       doSugartType.value = true;
@@ -335,28 +340,43 @@ export default {
           fieldValue.value = iceName.value + "(" + fieldValue.value + ")";
         }
       }
-      if (fieldValue.value === "") {
-        showFailToast(t("device.pleaseSelectAPattern"));
-        return;
-      }
       showConfirmDialog({
         title: t("user.tips"),
         message: t("device.confirmMake") + fieldValue.value + "?",
       })
         .then(async () => {
-          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(() => {
-              doSugartType.value = false;
-            }, 5000);
+          if (deviceDetal.value.equimentType == "SBM10") {
+            await produceGoods({
+              equipmentId: deviceId,
+              productName: fieldValue.value,
+              makeCodes: makeCodes.value.join(","),
+              productNo: productNo.value,
+            }).then((data) => {
+              if (data.data.code == "00000") {
+                doSugartData.value = data.data.data;
+                setTimeout(() => {
+                  doSugartType.value = false;
+                }, 5000);
+              } else {
+                showFailToast(data.data.message);
+              }
+            });
           } else {
-            showFailToast(data.message);
+            await remoteProduction({
+              equipmentId: deviceId,
+              productName: fieldValue.value,
+              makeCodes: makeCodes.value.join(","),
+              productNo: productNo.value,
+            }).then((data) => {
+              if (data.data.code == "00000") {
+                doSugartData.value = data.data.data;
+                setTimeout(() => {
+                  doSugartType.value = false;
+                }, 5000);
+              } else {
+                showFailToast(data.data.message);
+              }
+            });
           }
         })
         .catch((error) => {

+ 600 - 0
src/views/device/goodsMan/index.vue

@@ -0,0 +1,600 @@
+<template>
+    <div class="price-editor">
+      <s-header :name="$t('device.modifyPricePage.title')" :noback="false" />
+      <div class="content-container">
+        <!-- 设备信息卡片 -->
+        <div class="device-card">
+          <div class="device-header">
+            <div class="header-indicator"></div>
+            <h3 class="device-name">
+              {{ $t("device.modifyPricePage.equipmentName") }}:{{
+                equipmentName
+              }}
+            </h3>
+          </div>
+        </div>
+  
+        <!-- 商品列表卡片 -->
+        <div class="goods-card">
+          <!-- 操作头部 -->
+          <div class="card-header">
+            <div class="goods-count">
+              {{ $t("device.modifyPricePage.total") }}
+              <span class="highlight">{{ tableData.length }}</span>
+              {{ $t("device.modifyPricePage.goods") }}
+            </div>
+            <van-button icon="edit" @click="noticeClk" class="batch-btn">
+              {{ $t("device.modifyPricePage.batchModify") }}
+            </van-button>
+          </div>
+  
+          <!-- 商品列表 -->
+          <div class="goods-list">
+            <div
+              v-for="(item, index) in tableData"
+              :key="index"
+              class="goods-item"
+              :class="{ 'off-shelf': item.shelfStatus === 0 }"
+            >
+              <!-- 左侧商品图片 -->
+              <div class="goods-image-container">
+                <van-image
+                  class="goods-image"
+                  :src="showSugerPhoto(item)"
+                  fit="cover"
+                />
+              </div>
+  
+              <!-- 中间商品信息 -->
+              <div class="goods-info">
+                <!-- 商品名称行 -->
+                <div class="name-row">
+                  <template v-if="item.isEditName">
+                    <van-field
+                      v-model="item.productName"
+                      class="name-input"
+                      :border="false"
+                      clearable
+                    >
+                    </van-field>
+                    <van-icon
+                      name="success"
+                      class="action-icon"
+                      @click="updateProduct(item, 1)"
+                    />
+                  </template>
+                  <template v-else>
+                    <span class="goods-name">{{ item.productName }}</span>
+                    <van-icon
+                      name="edit"
+                      class="name-edit-icon"
+                      @click="item.isEditName = true"
+                    />
+                  </template>
+                </div>
+  
+                <!-- 价格行 -->
+                <div class="price-row">
+                  <template v-if="item.isEditPrice">
+                    <van-field
+                      type="number"
+                      v-model="item.rmbPrice"
+                      class="price-input"
+                      :border="false"
+                      clearable
+                    >
+                      <template #extra>
+                        <span class="currency-symbol">{{ currencySymbol }}</span>
+                      </template>
+                    </van-field>
+                    <van-icon
+                      name="success"
+                      class="action-icon"
+                      @click="updateProduct(item, 2)"
+                    />
+                  </template>
+                  <template v-else>
+                    <div class="price-display">
+                      <span class="currency">{{ currencySymbol }}</span>
+                      <span class="price">{{ item.rmbPrice }}</span>
+                    </div>
+                    <van-icon
+                      name="edit"
+                      class="action-icon"
+                      @click="item.isEditPrice = true"
+                    />
+                  </template>
+                </div>
+              </div>
+  
+              <!-- 右侧开关控制 -->
+              <div class="shelf-control">
+                <van-switch
+                  v-model="item.sellStatus"
+                  :active-value="true"
+                  :inactive-value="false"
+                  size="22px"
+                  active-color="#4d6add"
+                  inactive-color="#dcdee0"
+                  @change="updateProduct(item, 3)"
+                />
+                <span class="shelf-status">
+                  {{
+                    item.sellStatus ? $t("device.onShelf") : $t("device.offShelf")
+                  }}
+                </span>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+  
+      <!-- 批量修改弹窗 -->
+      <kDialog
+        :isCloseForConfirm="false"
+        :dialogTitle="$t('device.modifyPricePage.batchPrice')"
+        :confirmBtnTxt="$t('device.modifyPricePage.modifySubmit')"
+        ref="kDialogRef"
+        @confirmclk="confirmClk"
+      >
+        <template #content>
+          <van-field
+            type="number"
+            v-model="cofficentForm.price"
+            :placeholder="$t('device.modifyPricePage.batchPricePlace')"
+            :label="$t('device.modifyPricePage.batchPrice')"
+            class="batch-field"
+          >
+            <template #extra>
+              <span class="currency-symbol">{{ currencySymbol }}</span>
+            </template>
+          </van-field>
+        </template>
+      </kDialog>
+    </div>
+  </template>
+  
+  <script>
+  import kDialog from "@/components/commom/kDialog/index.vue";
+  // 导入接口
+  import {
+    selectProducts,
+    updateProductInfo,
+    batchUpdatePrice,
+  } from "@/service/device/index";
+  import sHeader from "@/components/SimpleHeader";
+  import { reactive, ref } from "@vue/reactivity";
+  import { onMounted } from "@vue/runtime-core";
+  import { useRoute } from "vue-router";
+  import { showToast } from "vant";
+  import { useI18n } from "vue-i18n";
+  
+  export default {
+    components: { sHeader, kDialog },
+    setup() {
+      // 引入语言
+      const { t } = useI18n();
+      // 批量修改弹窗
+      const kDialogRef = ref(null);
+      // 点击批量修改
+      const noticeClk = () => {
+        cofficentForm.price = "";
+        kDialogRef.value.openDialog();
+      };
+      // 修改商品信息提交参数
+      const params = ref();
+      // 点击确定按钮
+      const confirmClk = async() => {
+        if (!cofficentForm.price) {
+          showToast(t("device.modifyPricePage.batchPricePlace"));
+          return;
+        }
+        params.value = {
+          equipmentId: cofficentForm.equipmentId,
+          rmbPrice: cofficentForm.price,
+        };
+        try {
+          const { data } = await batchUpdatePrice(params.value);
+          console.log(data);
+        } catch (error) {
+          console.log(error);
+        }
+        kDialogRef.value.closeDialog();
+      };
+      // 商品图片路径处理
+      const showSugerPhoto = (row) => {
+        let imgId = row.no;
+        if (imgId) {
+          return require(`../../../assets/order/spunSugar/goods/${imgId}.png`);
+        }
+        return imgId;
+      };
+      // 路由
+      const route = useRoute();
+      // 商品数据
+      const tableData = ref([]);
+      // 设备名称
+      const equipmentName = ref("");
+      // 刚进页面
+      onMounted(() => {
+        // 加载样式
+        const id = route.query.deviceId || "";
+        const name = route.query.name || "";
+        if (id) {
+          cofficentForm.equipmentId = id;
+          equipmentName.value = name;
+          getList();
+        }
+      });
+      // 获取商品列表
+      const getList = () => {
+        selectProducts({ equipmentId: cofficentForm.equipmentId }).then((res) => {
+          const { data } = res.data;
+          if (data) {
+            if (data.length > 0) {
+              // 是否修改状态
+              data.forEach((item) => {
+                item.isEditPrice = false;
+                item.isEditName = false;
+              });
+            }
+            tableData.value = data;
+          }
+        });
+      };
+      // 修改的价格
+      const cofficentForm = reactive({
+        equipmentId: "",
+        price: "",
+      });
+      // 自定义货币符号
+      const currencySymbol = ref("¥");
+      const loginUserStr = localStorage.getItem("loginUser");
+      const loginUser = JSON.parse(loginUserStr);
+      if (loginUser.currencySymbol) {
+        currencySymbol.value = loginUser.currencySymbol;
+      } else {
+        currencySymbol.value = "¥";
+      }
+  
+      // 修改商品信息
+      const updateProduct = async (item, index) => {
+        // 排除掉isEditPrice、isEditName
+        if (index == 1) {
+          if (item.productName == "") {
+            showToast(t("device.enterProductName"));
+            return;
+          }
+          // 修改名称
+          item.isEditName = false;
+        } else if (index == 2) {
+          // 修改价格
+          if (item.rmbPrice == "") {
+            showToast(t("device.enterProductPrice"));
+            return;
+          }
+          item.codePrice = item.rmbPrice;
+          item.isEditPrice = false;
+        }
+        params.value = {
+          codePrice: item.codePrice,
+          equipmentId: item.equipmentId,
+          productName: item.productName,
+          name: item.name,
+          rmbPrice: item.rmbPrice,
+          sellStatus: item.sellStatus,
+          no: item.no,
+          // 故意省略 isEditPrice 和 isEditName
+        };
+        try {
+          const { data } = await updateProductInfo(params.value);
+          console.log(data);
+        } catch (error) {
+          console.log(error);
+        }
+      };
+      
+      return {
+        cofficentForm,
+        tableData,
+        showSugerPhoto,
+        kDialogRef,
+        noticeClk,
+        confirmClk,
+  
+        // 参数
+  
+        equipmentName,
+        currencySymbol,
+  
+        // 方法
+        updateProduct,
+      };
+    },
+  };
+  </script>
+  
+  <style lang="less" scoped>
+  @primary-color: #2d87c8;
+  @light-bg: #f5f8ff;
+  @card-bg: #ffffff;
+  @text-dark: #333;
+  @text-light: #666;
+  @text-lighter: #999;
+  @border-color: #e4e7ec;
+  @border-radius: 12px;
+  @card-shadow: 0 4px 12px rgba(77, 106, 221, 0.15);
+  @hover-shadow: 0 8px 20px rgba(77, 106, 221, 0.25);
+  @transition: all 0.3s ease;
+  
+  .price-editor {
+    background: @light-bg;
+    min-height: 100vh;
+  }
+  
+  .content-container {
+    padding: 15px;
+  }
+  
+  .device-card {
+    background: @card-bg;
+    border-radius: @border-radius;
+    box-shadow: @card-shadow;
+    margin: 0 0 15px;
+    padding: 16px;
+  
+    .device-header {
+      display: flex;
+      align-items: center;
+  
+      .header-indicator {
+        width: 3px;
+        height: 20px;
+        background: @primary-color;
+        margin-right: 12px;
+        border-radius: 2px;
+      }
+  
+      .device-name {
+        margin: 0;
+        font-size: 16px;
+        color: #404d74;
+        font-weight: 550;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+        max-width: 85%;
+      }
+    }
+  }
+  
+  .goods-card {
+    background: @card-bg;
+    border-radius: @border-radius;
+    box-shadow: @card-shadow;
+    padding: 16px;
+    margin-bottom: 20px;
+  
+    .card-header {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      margin-bottom: 20px;
+  
+      .goods-count {
+        color: @text-light;
+        font-size: 14px;
+  
+        .highlight {
+          color: @primary-color;
+          font-weight: 500;
+          margin: 0 4px;
+        }
+      }
+  
+      .batch-btn {
+        height: 32px;
+        padding: 0 16px;
+        font-size: 13px;
+        border-radius: 8px;
+      }
+    }
+  }
+  
+  .goods-list {
+    .goods-item {
+      display: flex;
+      align-items: center;
+      padding: 16px 0;
+      border-bottom: 1px solid @border-color;
+      position: relative;
+  
+      &:last-child {
+        border-bottom: none;
+      }
+  
+      &.off-shelf {
+        opacity: 0.8;
+        background-color: fade(@text-lighter, 5%);
+      }
+    }
+  }
+  
+  .goods-image-container {
+    width: 70px;
+    height: 70px;
+    border-radius: 8px;
+    overflow: hidden;
+    margin-right: 15px;
+    flex-shrink: 0;
+  
+    .goods-image {
+      width: 100%;
+      height: 100%;
+      object-fit: cover;
+      background-color: @light-bg;
+    }
+  }
+  
+  .goods-info {
+    flex: 1;
+    min-width: 0;
+    margin-right: 15px;
+  }
+  
+  .name-row {
+    display: flex;
+    align-items: center;
+    gap: 12px;
+    margin-bottom: 10px;
+  
+    .goods-name {
+      font-size: 15px;
+      color: @text-dark;
+      font-weight: 500;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      white-space: nowrap;
+    }
+  
+    .name-input {
+      width: 80%;
+      background: @light-bg;
+      border-radius: 8px;
+      padding: 6px 14px;
+    }
+  
+    .action-icon {
+      color: @primary-color;
+      font-size: 18px;
+      padding: 6px;
+      cursor: pointer;
+    }
+  
+    .name-edit-icon {
+      color: @primary-color;
+      font-size: 18px;
+      flex-shrink: 0;
+      padding: 4px;
+      cursor: pointer;
+    }
+  }
+  
+  .price-row {
+    display: flex;
+    align-items: center;
+    gap: 12px;
+  
+    .price-input {
+      width: 100px;
+      background: @light-bg;
+      border-radius: 8px;
+      padding: 6px 14px;
+    }
+  
+    .price-display {
+      color: #df5e4c;
+      font-size: 15px;
+      font-weight: 500;
+  
+      .price {
+        font-size: 16px;
+      }
+    }
+  
+    .currency-symbol,
+    .currency {
+      color: @primary-color;
+      font-size: 14px;
+      margin-right: 2px;
+    }
+  
+    .action-icon {
+      color: @primary-color;
+      font-size: 18px;
+      padding: 6px;
+      cursor: pointer;
+    }
+  }
+  
+  .shelf-control {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    min-width: 70px;
+  
+    .shelf-status {
+      font-size: 12px;
+      color: @text-light;
+      margin-top: 6px;
+      text-align: center;
+    }
+  }
+  
+  .batch-field {
+    :deep(.van-field__label) {
+      width: 100px;
+    }
+  }
+  
+  .name-edit-dialog {
+    :deep(.van-dialog) {
+      border-radius: 16px;
+      overflow: hidden;
+    }
+  
+    .dialog-content {
+      padding: 20px;
+    }
+  
+    .name-edit-field {
+      background: @light-bg;
+      border-radius: 8px;
+      padding: 12px;
+    }
+  
+    .char-count {
+      text-align: right;
+      font-size: 12px;
+      color: @text-lighter;
+      margin-top: 8px;
+    }
+  }
+  
+  @media (max-width: 480px) {
+    .goods-card {
+      padding: 12px;
+    }
+  
+    .goods-item {
+      padding: 12px 0;
+    }
+  
+    .goods-image-container {
+      width: 60px;
+      height: 60px;
+      margin-right: 10px;
+    }
+  
+    .goods-name {
+      font-size: 14px;
+    }
+  
+    .price-input {
+      width: 90px;
+    }
+  
+    .shelf-control {
+      min-width: 60px;
+  
+      .shelf-status {
+        font-size: 11px;
+      }
+    }
+  }
+  
+  :deep(.van-image__img) {
+    object-fit: contain !important;
+  }
+  </style>
+  

+ 107 - 19
src/views/device/index.vue

@@ -165,7 +165,7 @@
                         }}
                       </span>
                       <span
-                        v-if="item.equimentType != 'P10'"
+                        v-if="item.equimentType === 'P30'"
                         class="temperature"
                       >
                         {{
@@ -183,7 +183,7 @@
                           $t("device.cupQuantity") + ":" + item.furnaceTm
                         }}</span
                       >
-                      <span v-if="item.furnaceSp" class="humidity">
+                      <span v-if="item.equimentType === 'P30'" class="humidity">
                         {{
                           $t("device.bucketWeight") +
                           ":" +
@@ -383,7 +383,11 @@
                       class="detail-section material-usage"
                       v-if="item.machineType === '1'"
                     >
-                      <div class="material-group">
+                      <!-- 爆米花P30物料-->
+                      <div
+                        class="material-group"
+                        v-if="item.equimentType === 'P30'"
+                      >
                         <div class="material-grid">
                           <div
                             v-for="(poporn, index) in popornTypes"
@@ -410,6 +414,71 @@
                           </div>
                         </div>
                       </div>
+
+                      <!-- 爆米花SBM10物料-->
+                      <div
+                        class="material-group"
+                        v-if="item.equimentType === 'SBM10'"
+                      >
+                        <div class="material-grid">
+                          <div
+                            v-for="(poporn, index) in poporn10Types"
+                            :key="index"
+                            class="material-item"
+                          >
+                            <van-icon
+                              :name="poporn.icon"
+                              class="material-icon"
+                              size="25px"
+                              :style="{ color: poporn.color }"
+                            />
+                            <div class="material-info">
+                              <span class="material-label">{{
+                                $t(`device.${poporn.type}`)
+                              }}</span>
+                              <span class="material-value"
+                                >{{
+                                  Format_calcuDecial(item[poporn.code])
+                                }}
+                                g</span
+                              >
+                            </div>
+                          </div>
+                        </div>
+                      </div>
+                    </div>
+                    <!-- 冰淇淋物料 -->
+                    <div
+                      class="detail-section material-usage"
+                      v-if="item.machineType === '2'"
+                    >
+                      <div class="material-group">
+                        <div class="material-grid">
+                          <div
+                            v-for="(ice, index) in iceTypes"
+                            :key="index"
+                            class="material-item"
+                          >
+                            <van-icon
+                              :name="ice.icon"
+                              class="material-icon"
+                              size="25px"
+                              :style="{ color: ice.color }"
+                            />
+                            <div class="material-info">
+                              <span class="material-label">{{
+                                $t(`device.${ice.type}`)
+                              }}</span>
+                              <span class="material-value"
+                                >{{
+                                  Format_calcuDecial(item[ice.code])
+                                }}
+                                %</span
+                              >
+                            </div>
+                          </div>
+                        </div>
+                      </div>
                     </div>
                   </template>
                   <!-- 最近刷新时间 -->
@@ -504,7 +573,11 @@
             </div>
           </div>
         </div>
-        <van-back-top right="20" bottom="80" style="background-color: #2c87c8;"/>
+        <van-back-top
+          right="20"
+          bottom="80"
+          style="background-color: #2c87c8"
+        />
       </van-list>
     </div>
 
@@ -533,12 +606,12 @@ import {
 import sHeader from "../../components/SimpleHeader";
 import { getLoginUser, Format_calcuDecial } from "../../common/js/utils";
 import {
-  getDeviceList,
   eliminate,
   Api_getReplenishment,
   changeSleepDesc,
   setFurnace,
   sleepEquipment,
+  getMachineList,
 } from "../../service/device/index";
 import deviceSearch from "./deviceSearch";
 import deviceOper from "./deviceOper";
@@ -575,7 +648,7 @@ export default {
       { type: "wasteWater", icon: "weapp-nav", color: "#666" },
     ]);
 
-    // 爆米花物料
+    // 爆米花P30物料
     const popornTypes = ref([
       { code: "whiteSugar", type: "chocolate", icon: "stop", color: "#5C3317" },
       { code: "redSugar", type: "cheese", icon: "stop", color: "#fcdd8d" },
@@ -583,6 +656,21 @@ export default {
       { code: "blueSugar", type: "caramel", icon: "stop", color: "#D2691E" },
     ]);
 
+    // 爆米花P10物料
+    const poporn10Types = ref([
+      { code: "redSugar", type: "sweet", icon: "stop", color: "#FFC0CB" },
+      { code: "whiteSugar", type: "salty", icon: "stop", color: "#fcdd8d" },
+    ]);
+
+    // 冰淇淋物料
+    const iceTypes = ref([
+      { code: "whiteSugar", type: "C01", icon: "stop", color: "#5C3317" },
+      { code: "redSugar", type: "C02", icon: "stop", color: "#faad14" },
+      { code: "yellowSugar", type: "J01", icon: "stop", color: "#ff4d4f" },
+      { code: "blueSugar", type: "J02", icon: "stop", color: "#1890ff" },
+      { code: "stick", type: "J03", icon: "stop", color: "#f8ff3b" },
+    ]);
+
     // 创建容器引用
     const scrollContainer = ref(null);
     // 创建响应式滚动位置
@@ -692,7 +780,7 @@ export default {
     // 获取设备列表数据
     const getList = async () => {
       finished.value = false;
-      const { data } = await getDeviceList(Object.assign({}, searchParams));
+      const { data } = await getMachineList(Object.assign({}, searchParams));
       if (data.code === "00000") {
         if (searchParams.current === 0) {
           list.value = [];
@@ -825,7 +913,7 @@ export default {
             longitude: row.longitude,
             fullName: row.fullName,
             name: row.name ? row.name : row.clientId.slice(-6),
-            status: row.eqeStatus
+            status: row.eqeStatus,
           },
         });
       } else {
@@ -935,14 +1023,14 @@ export default {
       })
         .then(async () => {
           const { data } = await sleepEquipment({
-            equipmentId: item.id,
-            eqeStatus: item.isSleep ? "0" : "1",
+            id: item.id,
+            isSleep: item.isSleep ? "0" : "1",
           });
           if (data.code) {
             showSuccessToast(t("device.changeSleepSuccess"));
             setTimeout(() => {
               init();
-            }, 1000);
+            }, 1500);
           } else {
             showFailToast(data.message);
           }
@@ -960,14 +1048,14 @@ export default {
       })
         .then(async () => {
           const { data } = await setFurnace({
-            equipmentId: id,
+            id: id,
             eqeStatus: 1,
           });
           if (data.code) {
             showSuccessToast(t("device.restartSucceeded"));
             setTimeout(() => {
-              router.go(0);
-            }, 1000);
+              init();
+            }, 1500);
           } else {
             showFailToast(data.message);
           }
@@ -978,8 +1066,6 @@ export default {
     };
     // 开启/关闭炉头
     const openCloseHead = (id, status) => {
-      // console.log("id", id);
-      // console.log("status", status);
       showConfirmDialog({
         title: t("user.tips"),
         message:
@@ -989,7 +1075,7 @@ export default {
       })
         .then(async () => {
           const { data } = await setFurnace({
-            equipmentId: id,
+            id: id,
             eqeStatus: status,
           });
           if (data.code) {
@@ -998,8 +1084,8 @@ export default {
                 t("device.success")
             );
             setTimeout(() => {
-              router.go(0);
-            }, 1000);
+              init();
+            }, 1500);
           } else {
             showFailToast(data.message);
           }
@@ -1050,6 +1136,8 @@ export default {
       controlList,
       sugarTypes,
       popornTypes,
+      iceTypes,
+      poporn10Types,
 
       scrollContainer,
       scrollTop,

+ 1 - 1
src/views/device/jam/index.vue

@@ -23,7 +23,7 @@
               fit="cover"
               class="jam-image"
             />
-            <h3 class="jam-title">{{ jam.name }}</h3>
+            <h3 class="jam-title">{{ jam.productName }}</h3>
           </div>
           <!-- 操作按钮组 -->
           <div class="jam-actions">

+ 19 - 17
src/views/device/modulation.vue

@@ -47,9 +47,8 @@ import { onMounted, ref } from "vue";
 import sHeader from "@/components/SimpleHeader";
 import { useRoute, useRouter } from "vue-router";
 import { getDeviceDetal, updateVolume } from "@/service/device";
-import { showFailToast, showDialog } from "vant";
+import { showFailToast, showConfirmDialog, showSuccessToast } from "vant";
 import { useI18n } from "vue-i18n";
-// import { styleUrl } from "../../common/js/utils";
 
 export default {
   setup() {
@@ -79,22 +78,25 @@ export default {
       }
     };
     // 音量调节保存
-    const volumeChange = async () => {
-      const { data } = await updateVolume({
-        id: deviceId,
-        volume: volume.value.toString(),
-      });
-      if (data.code) {
-        showDialog({
-          confirmButtonColor: "#2c87c8",
-          message: t("device.sentSuccessfully"),
-        }).then(() => {
-          //返回上一页
-          router.go(-1);
+    const volumeChange = () => {
+      showConfirmDialog({
+        title: t("device.openRemind"),
+        message: t("device.editCheck"),
+      }).then(async () => {
+        const { data } = await updateVolume({
+          id: deviceId,
+          volume: volume.value.toString(),
         });
-      } else {
-        showFailToast(data.message);
-      }
+        console.log(data);
+        if (data.code === "00000") {
+          showSuccessToast(t("device.sentSuccessfully"));
+          setTimeout(() => {
+            router.go(-1);
+          }, 1500);
+        } else {
+          showFailToast(data.message);
+        }
+      });
     };
     return {
       deviceDetal,

+ 421 - 350
src/views/device/openDoor.vue

@@ -1,360 +1,431 @@
 <template>
-	<div class="door-access-page">
-	  <!-- 顶部导航 -->
-	  <s-header :name="$t('device.remoteDoorOpening')" :noback="false" />
-  
-	  <!-- 设备名称标题 -->
-	  <div class="device-header">
-		<div class="vertical-indicator"></div>
-		<h3 class="device-name">
-		  {{ $t("device.equipmentName") }}:{{
-			deviceDetal ? deviceDetal.name : ""
-		  }}
-		</h3>
-	  </div>
-  
-	  <!-- 门禁控制卡片 -->
-	  <div class="settings-card">
-		<!-- 外部门控制 -->
-		<div class="door-item">
-		  <div class="door-info">
-			<!-- <van-icon name="../assets/device/door.png" class="door-icon" /> -->
-			<div class="door-detail">
-			  <h3 class="door-title">{{ $t("device.outDoor") }}</h3>
-			  <p class="door-status">
-				{{ $t("device.status") }}:
-				<span
-				  :class="
-					deviceDetal.outDoor == '1' ? 'status-open' : 'status-closed'
-				  "
-				>
-				  {{
-					deviceDetal.outDoor != "1"
-					  ? $t("device.closed")
-					  : $t("device.open")
-				  }}
-				</span>
-			  </p>
-			</div>
-		  </div>
-		  <van-switch
-			:model-value="deviceDetal.outDoor"
-			@update:model-value="outDoorChg"
-			size="24px"
-			active-value="1"
-			inactive-value="0"
-			active-color="#2d88c9"
-			inactive-color="#dcdee0"
-		  />
-		</div>
-  
-		<!-- 内部门控制 -->
-		<div class="door-item" v-if="machineType == '0' || machineType == null">
-		  <div class="door-info">
-			<!-- <van-icon name="door" class="door-icon" /> -->
-			<div class="door-detail">
-			  <h3 class="door-title">{{ $t("device.inDoor") }}</h3>
-			  <p class="door-status">
-				{{ $t("device.status") }}:
-				<span
-				  :class="
-					deviceDetal.inDoor == '1' ? 'status-open' : 'status-closed'
-				  "
-				>
-				  {{
-					deviceDetal.inDoor != "1"
-					  ? $t("device.closed")
-					  : $t("device.open")
-				  }}
-				</span>
-			  </p>
-			</div>
-		  </div>
-		  <van-switch
-			:model-value="deviceDetal.inDoor"
-			@update:model-value="inDoorChg"
-			size="24px"
-			active-value="1"
-			inactive-value="0"
-			active-color="#2d88c9"
-			inactive-color="#dcdee0"
-		  />
-		</div>
-  
-		<!-- 纸币器禁能开关 -->
-		<div class="door-item" v-if="(machineType == '0' || machineType == '1') && (user.ifForegin == '1' || user.type == '0')">
-		  <div class="door-info">
-			<div class="door-detail">
-			  <h3 class="door-title">{{ $t("device.banPaper") }}</h3>
-			  <p class="door-status">
-				{{ $t("device.status") }}:
-				<span
-				  :class="deviceDetal.banPaper ? 'status-open' : 'status-closed'"
-				>
-				  {{
-					deviceDetal.banPaper ? $t("device.open") : $t("device.closed")
-				  }}
-				</span>
-			  </p>
-			</div>
-		  </div>
-		  <van-switch
-			:model-value="deviceDetal.banPaper"
-			@update:model-value="banPaperChg"
-			size="24px"
-			active-color="#2d88c9"
-			inactive-color="#dcdee0"
-		  />
-		</div>
-	  </div>
-	</div>
-  </template>
-  
-  <script>
-  import { onMounted, ref } from "vue";
-  import sHeader from "@/components/SimpleHeader";
-  import { useRoute } from "vue-router";
-  import { getDeviceDetal, Api_openDoor, banMoney } from "@/service/device";
-  import { showFailToast, showToast, showConfirmDialog } from "vant";
-  import { useI18n } from "vue-i18n";
-  import { getLoginUser } from "../../common/js/utils";
-  
-  export default {
-	setup() {
-	  const user = getLoginUser();
-	  const route = useRoute();
-	  const deviceId = route.query.deviceId;
-	  const machineType = route.query.machineType;
-	  const deviceDetal = ref({});
-	  const { t } = useI18n();
-  
-	  // 初始化页面获取列表
-	  onMounted(async () => {
-		// 加载样式
-		getDeviceDetalFun();
-	  });
-  
-	  // 获取设备列表数据
-	  const getDeviceDetalFun = async () => {
-		const { data } = await getDeviceDetal({
-		  id: deviceId,
-		});
-		if (data.code === "00000") {
-		  // outDoor如果是null,默认是关闭
-		  if (data.data.outDoor == null) {
-			data.data.outDoor = "0";
-		  }
-		  // inDoor如果是null,默认是关闭
-		  if (data.data.inDoor == null) {
-			data.data.inDoor = "0";
-		  }
-		  deviceDetal.value = data.data;
-		  console.log(deviceDetal.value);
-		} else {
-		  showFailToast(data.message);
-		}
-	  };
-  
-	  // 点击外门开关
-	  const outDoorChg = (outDoor) => {
-		showConfirmDialog({
-		  title: t("device.openRemind"),
-		  message: t("device.openRemindOut"),
-		}).then(() => {
-		  Api_openDoor({
-			equipmentId: deviceDetal.value.id,
-			type: 0,
-			status: outDoor,
-		  }).then((res) => {
-			if (res.data.code == "00000") {
-			  showToast(t("device.sentSuccessfully"));
-			}
-			setTimeout(() => {
-			  getDeviceDetalFun();
-			}, 1500);
-		  });
-		});
-	  };
-  
-	  // 点击内门开关
-	  const inDoorChg = (inDoor) => {
-		showConfirmDialog({
-		  title: t("device.openRemind"),
-		  message: t("device.openRemindIn"),
-		}).then(() => {
-		  Api_openDoor({
-			equipmentId: deviceDetal.value.id,
-			type: 1,
-			status: inDoor,
-		  }).then((res) => {
-			if (res.data.code == "00000") {
-			  showToast(t("device.sentSuccessfully"));
-			}
-			setTimeout(() => {
-			  getDeviceDetalFun();
-			}, 1500);
-		  });
-		});
-	  };
-  
-	  const banPaperChg = (banPaper) => {
-		showConfirmDialog({
-		  title: t("device.openRemind"),
-		  message: t("device.openRemindPaper"),
-		}).then(() => {
-		  banMoney({
-			equipmentId: deviceDetal.value.id,
-			banPaper: banPaper,
-		  }).then((res) => {
-			if (res.data.code == "00000") {
-			  showToast(t("device.sentSuccessfully"));
-			}
-			setTimeout(() => {
-			  getDeviceDetalFun();
-			}, 1500);
-		  });
-		});
-	  };
-  
-	  return {
-		deviceDetal,
-		outDoorChg,
-		inDoorChg,
-		banPaperChg,
-		machineType,
-		user,
-	  };
-	},
-	components: {
-	  sHeader,
-	},
-  };
-  </script>
-  
-  <style lang="less" scoped>
-  @theme-color: #2d88c9;
-  @light-bg: #f5f8ff;
-  @card-bg: #ffffff;
-  @text-dark: #333;
-  @text-light: #666;
-  @text-lighter: #999;
-  @border-radius: 12px;
-  @card-shadow: 0 4px 12px rgba(77, 106, 221, 0.15);
-  @hover-shadow: 0 8px 20px rgba(77, 106, 221, 0.25);
-  @transition: all 0.3s ease;
-  
-  .door-access-page {
-	display: flex;
-	flex-direction: column;
-	height: 100vh;
-	background-color: @light-bg;
-	font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen,
-	  sans-serif;
+  <div class="door-access-page">
+    <!-- 顶部导航 -->
+    <s-header :name="$t('device.remoteDoorOpening')" :noback="false" />
+
+    <!-- 设备名称标题 -->
+    <div class="device-header">
+      <div class="vertical-indicator"></div>
+      <h3 class="device-name">
+        {{ $t("device.equipmentName") }}:{{
+          deviceDetal ? deviceDetal.name : ""
+        }}
+      </h3>
+    </div>
+
+    <!-- 门禁控制卡片 -->
+    <div class="settings-card">
+      <!-- 外部门控制 -->
+      <div class="door-item">
+        <div class="door-info">
+          <!-- <van-icon name="../assets/device/door.png" class="door-icon" /> -->
+          <div class="door-detail">
+            <h3 class="door-title">{{ $t("device.outDoor") }}</h3>
+            <p class="door-status">
+              {{ $t("device.status") }}:
+              <span
+                :class="
+                  deviceDetal.outDoor == '1' ? 'status-open' : 'status-closed'
+                "
+              >
+                {{
+                  deviceDetal.outDoor != "1"
+                    ? $t("device.closed")
+                    : $t("device.open")
+                }}
+              </span>
+            </p>
+          </div>
+        </div>
+        <van-switch
+          :model-value="deviceDetal.outDoor"
+          @update:model-value="outDoorChg"
+          size="24px"
+          active-value="1"
+          inactive-value="0"
+          active-color="#2d88c9"
+          inactive-color="#dcdee0"
+        />
+      </div>
+
+      <!-- 内部门控制 -->
+      <div class="door-item" v-if="machineType == '0' || machineType == null">
+        <div class="door-info">
+          <!-- <van-icon name="door" class="door-icon" /> -->
+          <div class="door-detail">
+            <h3 class="door-title">{{ $t("device.inDoor") }}</h3>
+            <p class="door-status">
+              {{ $t("device.status") }}:
+              <span
+                :class="
+                  deviceDetal.inDoor == '1' ? 'status-open' : 'status-closed'
+                "
+              >
+                {{
+                  deviceDetal.inDoor != "1"
+                    ? $t("device.closed")
+                    : $t("device.open")
+                }}
+              </span>
+            </p>
+          </div>
+        </div>
+        <van-switch
+          :model-value="deviceDetal.inDoor"
+          @update:model-value="inDoorChg"
+          size="24px"
+          active-value="1"
+          inactive-value="0"
+          active-color="#2d88c9"
+          inactive-color="#dcdee0"
+        />
+      </div>
+
+      <!-- 物料监控开关 -->
+      <div class="door-item">
+        <div class="door-info">
+          <div class="door-detail">
+            <h3 class="door-title">{{ $t("device.materialMonitor") }}</h3>
+            <p class="door-status">
+              {{ $t("device.status") }}:
+              <span
+                :class="
+                  deviceDetal.isMaterialUse == '1'
+                    ? 'status-open'
+                    : 'status-closed'
+                "
+              >
+                {{
+                  deviceDetal.isMaterialUse == "1"
+                    ? $t("device.open")
+                    : $t("device.closed")
+                }}
+              </span>
+            </p>
+          </div>
+        </div>
+        <van-switch
+          :model-value="deviceDetal.isMaterialUse"
+          @update:model-value="materialChg"
+          size="24px"
+          active-value="1"
+          inactive-value="0"
+          active-color="#4d6add"
+          inactive-color="#dcdee0"
+        />
+      </div>
+
+      <!-- 纸币器禁能开关 -->
+      <div
+        class="door-item"
+        v-if="
+          (machineType == '0' || machineType == '1') &&
+          (user.ifForegin == '1' || user.type == '0')
+        "
+      >
+        <div class="door-info">
+          <div class="door-detail">
+            <h3 class="door-title">{{ $t("device.banPaper") }}</h3>
+            <p class="door-status">
+              {{ $t("device.status") }}:
+              <span
+                :class="deviceDetal.banPaper ? 'status-open' : 'status-closed'"
+              >
+                {{
+                  deviceDetal.banPaper ? $t("device.open") : $t("device.closed")
+                }}
+              </span>
+            </p>
+          </div>
+        </div>
+        <van-switch
+          :model-value="deviceDetal.banPaper"
+          @update:model-value="banPaperChg"
+          size="24px"
+          active-color="#2d88c9"
+          inactive-color="#dcdee0"
+        />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { onMounted, ref } from "vue";
+import sHeader from "@/components/SimpleHeader";
+import { useRoute, useRouter } from "vue-router";
+import {
+  getDeviceDetal,
+  Api_openDoor,
+  banMoney,
+  changeMaterial,
+} from "@/service/device";
+import { showFailToast, showToast, showConfirmDialog } from "vant";
+import { useI18n } from "vue-i18n";
+import { getLoginUser } from "../../common/js/utils";
+
+export default {
+  setup() {
+    const user = getLoginUser();
+    const route = useRoute();
+    const router = useRouter();
+    const deviceId = route.query.deviceId;
+    const machineType = route.query.machineType;
+    const deviceDetal = ref({});
+    const { t } = useI18n();
+
+    // 初始化页面获取列表
+    onMounted(async () => {
+      // 加载样式
+      getDeviceDetalFun();
+    });
+
+    // 获取设备列表数据
+    const getDeviceDetalFun = async () => {
+      const { data } = await getDeviceDetal({
+        id: deviceId,
+      });
+      if (data.code === "00000") {
+        // outDoor如果是null,默认是关闭
+        if (data.data.outDoor == null) {
+          data.data.outDoor = "0";
+        }
+        // inDoor如果是null,默认是关闭
+        if (data.data.inDoor == null) {
+          data.data.inDoor = "0";
+        }
+        deviceDetal.value = data.data;
+        console.log(deviceDetal.value);
+      } else {
+        showFailToast(data.message);
+      }
+    };
+
+    // 点击外门开关
+    const outDoorChg = (outDoor) => {
+      showConfirmDialog({
+        title: t("device.openRemind"),
+        message: t("device.openRemindOut"),
+      }).then(() => {
+        Api_openDoor({
+          id: deviceDetal.value.id,
+          type: "0",
+          status: outDoor,
+        }).then((res) => {
+          if (res.data.code == "00000") {
+            showToast(t("device.sentSuccessfully"));
+            setTimeout(() => {
+              router.go(-1);
+            }, 1500);
+          } else {
+            showFailToast(res.data.message);
+          }
+        });
+      });
+    };
+
+    // 点击内门开关
+    const inDoorChg = (inDoor) => {
+      showConfirmDialog({
+        title: t("device.openRemind"),
+        message: t("device.openRemindIn"),
+      }).then(() => {
+        Api_openDoor({
+          id: deviceDetal.value.id,
+          type: "1",
+          status: inDoor,
+        }).then((res) => {
+          if (res.data.code == "00000") {
+            showToast(t("device.sentSuccessfully"));
+            setTimeout(() => {
+              router.go(-1);
+            }, 1500);
+          } else {
+            showFailToast(res.data.message);
+          }
+        });
+      });
+    };
+
+    const banPaperChg = (banPaper) => {
+      showConfirmDialog({
+        title: t("device.openRemind"),
+        message: t("device.openRemindPaper"),
+      }).then(() => {
+        banMoney({
+          equipmentId: deviceDetal.value.id,
+          banPaper: banPaper,
+        }).then((res) => {
+          if (res.data.code == "00000") {
+            showToast(t("device.sentSuccessfully"));
+          }
+          setTimeout(() => {
+            getDeviceDetalFun();
+          }, 1500);
+        });
+      });
+    };
+
+    const materialChg = (isMaterialUse) => {
+      console.log(deviceDetal.value.equimentType);
+      showConfirmDialog({
+        title: t("device.openRemind"),
+        message: t("device.openRemindMaterial"),
+      }).then(async () => {
+        const { data } = await changeMaterial({
+          equipmentId: deviceDetal.value.id,
+          isMaterialUse: isMaterialUse ? "1" : "0",
+        });
+        if (data.code === "00000") {
+          showToast(t("device.sentSuccessfully"));
+          setTimeout(() => {
+            router.go(-1);
+          }, 1500);
+        } else {
+          showFailToast(data.message);
+        }
+      });
+    };
+
+    return {
+      deviceDetal,
+      outDoorChg,
+      inDoorChg,
+      banPaperChg,
+      materialChg,
+      machineType,
+      user,
+    };
+  },
+  components: {
+    sHeader,
+  },
+};
+</script>
+
+<style lang="less" scoped>
+@theme-color: #2d88c9;
+@light-bg: #f5f8ff;
+@card-bg: #ffffff;
+@text-dark: #333;
+@text-light: #666;
+@text-lighter: #999;
+@border-radius: 12px;
+@card-shadow: 0 4px 12px rgba(77, 106, 221, 0.15);
+@hover-shadow: 0 8px 20px rgba(77, 106, 221, 0.25);
+@transition: all 0.3s ease;
+
+.door-access-page {
+  display: flex;
+  flex-direction: column;
+  height: 100vh;
+  background-color: @light-bg;
+  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen,
+    sans-serif;
+}
+
+.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, #2d88c9);
+    border-radius: 2px;
+    margin-right: 10px;
   }
-  
-  .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, #2d88c9);
-	  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;
-	}
+
+  .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-color: @card-bg;
-	border-radius: @border-radius;
-	box-shadow: @card-shadow;
-	padding: 16px;
-	margin: 0 16px 24px;
+}
+
+.settings-card {
+  background-color: @card-bg;
+  border-radius: @border-radius;
+  box-shadow: @card-shadow;
+  padding: 16px;
+  margin: 0 16px 24px;
+}
+
+.door-item {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 16px 0;
+  border-bottom: 1px solid rgba(0, 0, 0, 0.05);
+
+  // &:last-child {
+  //   border-bottom: none;
+  //   padding-bottom: 0;
+  // }
+}
+
+.door-info {
+  display: flex;
+  align-items: center;
+}
+
+.door-icon {
+  font-size: 24px;
+  color: @theme-color;
+  margin-right: 16px;
+}
+
+.door-detail {
+  flex: 1;
+}
+
+.door-title {
+  font-size: 16px;
+  font-weight: 600;
+  color: @text-dark;
+  margin: 0 0 4px;
+}
+
+.door-status {
+  font-size: 14px;
+  color: @text-light;
+  margin: 0;
+
+  .status-open {
+    color: #4caf50;
+    font-weight: 500;
   }
-  
-  .door-item {
-	display: flex;
-	justify-content: space-between;
-	align-items: center;
-	padding: 16px 0;
-	border-bottom: 1px solid rgba(0, 0, 0, 0.05);
-  
-	// &:last-child {
-	//   border-bottom: none;
-	//   padding-bottom: 0;
-	// }
+
+  .status-closed {
+    color: #f44336;
+    font-weight: 500;
   }
-  
-  .door-info {
-	display: flex;
-	align-items: center;
+}
+
+// 响应式调整
+@media (max-width: 360px) {
+  .device-header .device-name {
+    font-size: 16px;
   }
-  
-  .door-icon {
-	font-size: 24px;
-	color: @theme-color;
-	margin-right: 16px;
-  }
-  
-  .door-detail {
-	flex: 1;
-  }
-  
+
   .door-title {
-	font-size: 16px;
-	font-weight: 600;
-	color: @text-dark;
-	margin: 0 0 4px;
+    font-size: 15px;
   }
-  
+
   .door-status {
-	font-size: 14px;
-	color: @text-light;
-	margin: 0;
-  
-	.status-open {
-	  color: #4caf50;
-	  font-weight: 500;
-	}
-  
-	.status-closed {
-	  color: #f44336;
-	  font-weight: 500;
-	}
-  }
-  
-  // 响应式调整
-  @media (max-width: 360px) {
-	.device-header .device-name {
-	  font-size: 16px;
-	}
-  
-	.door-title {
-	  font-size: 15px;
-	}
-  
-	.door-status {
-	  font-size: 13px;
-	}
+    font-size: 13px;
   }
-  </style>
-  
+}
+</style>

+ 0 - 486
src/views/joinpayMch/index.vue

@@ -1,486 +0,0 @@
-<template>
-  <!-- 提现账号 -->
-  <div class="shandeMchPage flex-col"
-    :class="{ page1: pageType === '1', page2: pageType === '2', page3: pageType === '3', page4: pageType === '4' }">
-    <s-header :name="$t('joinpayMch.withdrawalAccountNo')" :noback="false"></s-header>
-    <div class="shandeMchBox flex-col">
-      <div class="topSpeed" v-if="pageType !== '4'"
-        :class="{ page1: pageType === '1', page2: pageType === '2', page3: pageType === '3' }"></div>
-      <div v-if="pageType === '1' || pageType === '4'">
-        <van-form @submit="saveJoinPayMchFun">
-          <van-field v-model="altMchName" name="altMchName" :label="$t('joinpayMch.merchantNameLabel')" readonly />
-          <van-field v-model="altMchNo" name="altMchNo" :label="$t('joinpayMch.merchantAccountLabel')" readonly />
-          <van-field v-model="altMchShortName" name="altMchShortName" :label="$t('joinpayMch.merchantAbbreviationLabel')"
-            readonly />
-          <div class="van-cell van-field requiredLeft">
-            <div class="van-cell__title van-field__label"><span>{{ $t('joinpayMch.merchantType') }}:</span></div>
-            <div class="van-cell__value van-field__value radioBox">
-              <van-radio-group v-model="altMerchantType" direction="horizontal" @change="fieldUpdate">
-                <van-radio name="10" icon-size="18px">{{ $t('joinpayMch.personal') }}</van-radio>
-                <van-radio name="11" icon-size="18px">{{ $t('joinpayMch.individualBusinesses') }}</van-radio>
-                <van-radio name="12" icon-size="18px">{{ $t('joinpayMch.enterprise') }}</van-radio>
-              </van-radio-group>
-            </div>
-          </div>
-          <div class="intervalRow"></div>
-          <van-field class="requiredLeft" v-model="busiContactName" name="busiContactName"
-            :label="$t('joinpayMch.contactNameLabel')" :placeholder="$t('joinpayMch.contactNamePlaceholder')"
-            :rules="[{ required: true, message: $t('joinpayMch.contactNamePlaceholder') }]"
-            @update:model-value="fieldUpdate" />
-          <van-field class="requiredLeft" v-model="busiContactMobileNo" name="busiContactMobileNo"
-            :label="$t('joinpayMch.cellPhoneLabel')" :placeholder="$t('joinpayMch.cellPhonePlaceholder')"
-            :rules="[{ required: true, message: $t('joinpayMch.cellPhonePlaceholder') }]"
-            @update:model-value="fieldUpdate" />
-          <van-field class="requiredLeft" v-model="legalPerson" name="legalPerson"
-            :label="$t('joinpayMch.nameOfLegalPerson/IndividualLabel')"
-            :placeholder="$t('joinpayMch.nameOfLegalPerson/IndividualPlaceholder')"
-            :rules="[{ required: true, message: $t('joinpayMch.nameOfLegalPerson/IndividualPlaceholder') }]"
-            @update:model-value="fieldUpdate" />
-          <van-field class="requiredLeft" v-model="phoneNo" name="phoneNo"
-            :label="$t('joinpayMch.phoneNumberOfLegalPerson/IndividualLabel')"
-            :placeholder="$t('joinpayMch.phoneNumberOfLegalPerson/IndividualPlaceholder')"
-            :rules="[{ required: true, message: $t('joinpayMch.phoneNumberOfLegalPerson/IndividualPlaceholder') }]"
-            @update:model-value="fieldUpdate" />
-          <van-field class="requiredLeft" v-model="idCardNo" name="idCardNo" :label="$t('joinpayMch.IDLabel')"
-            :placeholder="$t('joinpayMch.IDPlaceholder')"
-            :rules="[{ required: true, message: $t('joinpayMch.IDPlaceholder') }]" @update:model-value="fieldUpdate" />
-          <van-cell :title="$t('joinpayMch.validityOfIDCard')" :value="idCardExpiry" @click="idCardExpiryShow = true" />
-          <van-calendar v-model:show="idCardExpiryShow" @confirm="idCardExpiryOnConfirm" color="#4d6add" />
-          <div class="van-cell van-field" v-if="pageType === '4'">
-            <div class="van-cell__title van-field__label"><span>{{ $t('joinpayMch.pictureReview') }}:</span></div>
-            <div class="van-cell__value van-field__value radioBox"
-              style="display: flex; justify-content: space-around; align-items: center;">
-              {{ approveStatus }}
-              <van-button span="5" round type="primary" style="height: 2em; padding: 0 2em" @click='updateSentImage()'>
-                {{ $t('joinpayMch.reUpload') }}</van-button>
-            </div>
-          </div>
-          <div class="van-cell van-field" v-if="pageType === '4'">
-            <div class="van-cell__title van-field__label"><span>{{ $t('joinpayMch.signingStatus') }}:</span></div>
-            <div class="van-cell__value van-field__value radioBox"
-              style="display: flex; justify-content: space-around; align-items: center;">
-              {{ signStatus }}
-              <van-button span="5" round type="primary" style="height: 2em; padding: 0 2em" @click='altMchSignFun()'>{{
-                $t('joinpayMch.signAContract') }}
-              </van-button>
-            </div>
-          </div>
-          <div class="intervalRow"></div>
-          <div class="van-cell van-field requiredLeft">
-            <div class="van-cell__title van-field__label"><span>{{ $t('joinpayMch.accountType') }}:</span></div>
-            <div class="van-cell__value van-field__value radioBox">
-              <van-radio-group v-model="bankAccountType" direction="horizontal" @change="fieldUpdate">
-                <van-radio name="1" icon-size="18px">{{ $t('joinpayMch.debitCard') }}</van-radio>
-                <van-radio name="4" icon-size="18px">{{ $t('joinpayMch.corporateAccount') }}</van-radio>
-              </van-radio-group>
-            </div>
-          </div>
-          <van-field class="requiredLeft" v-model="bankAccountName" name="bankAccountName"
-            :label="$t('joinpayMch.bankAccountNameLabel')" :placeholder="$t('joinpayMch.bankAccountNamePlaceholder')"
-            :rules="[{ required: true, message: $t('joinpayMch.bankAccountNamePlaceholder') }]"
-            @update:model-value="fieldUpdate" />
-          <van-field class="requiredLeft" v-model="bankAccountNo" name="bankAccountNo"
-            :label="$t('joinpayMch.bankAccountLabel')" :placeholder="$t('joinpayMch.bankAccountPlaceholder')"
-            :rules="[{ required: true, message: $t('joinpayMch.bankAccountPlaceholder') }]"
-            @update:model-value="fieldUpdate" />
-          <div :class="{ requiredLeft: bankAccountType === '4' }">
-            <van-field v-model="bankChannelNo" name="bankChannelNo" :label="$t('joinpayMch.interBankNoLabel')"
-              :placeholder="$t('joinpayMch.interBankNoPlaceholder')"
-              :rules="[{ required: bankAccountType === '4', message: $t('joinpayMch.interBankNoPlaceholder') }]"
-              @update:model-value="fieldUpdate" />
-            <van-field v-model="licenseNo" name="licenseNo" :label="$t('joinpayMch.businessLicenseNoLabel')"
-              :placeholder="$t('joinpayMch.businessLicenseNoPlaceholder')"
-              :rules="[{ required: bankAccountType === '4', message: $t('joinpayMch.businessLicenseNoPlaceholder') }]"
-              @update:model-value="fieldUpdate" />
-            <van-cell :title="$t('joinpayMch.validityOfBusinessLicenseLabel')" :value="licenseExpiry"
-              @click="licenseExpiryShow = true" />
-            <van-calendar v-model:show="licenseExpiryShow" @confirm="licenseExpiryOnConfirm" color="#4d6add" />
-          </div>
-          <div class="intervalRow"></div>
-          <div class="van-cell van-field">
-            <div class="van-cell__title van-field__label"><span>{{ $t('joinpayMch.settlementMethod') }}:</span></div>
-            <div class="van-cell__value van-field__value radioBox">
-              <van-radio-group v-model="settMode" direction="horizontal" @change="fieldUpdate">
-                <van-radio name="1" icon-size="18px">{{ $t('joinpayMch.autoSettlementByConvergence') }}</van-radio>
-                <van-radio name="2" icon-size="18px">{{ $t('joinpayMch.manuallySettledByMerchantPlatform') }}</van-radio>
-              </van-radio-group>
-            </div>
-          </div>
-          <div class="van-cell van-field">
-            <div class="van-cell__title van-field__label"><span>{{ $t('joinpayMch.settlementCycleType') }}:</span></div>
-            <div class="van-cell__value van-field__value radioBox">
-              <van-radio-group v-model="settDateType" direction="horizontal" @change="fieldUpdate">
-                <van-radio name="1" icon-size="18px">{{ $t('joinpayMch.weekDay') }}</van-radio>
-                <van-radio name="2" icon-size="18px">{{ $t('joinpayMch.naturalDay') }}</van-radio>
-                <van-radio name="3" icon-size="18px">{{ $t('joinpayMch.monthlySettlementDate') }}</van-radio>
-              </van-radio-group>
-            </div>
-          </div>
-          <van-field v-model="riskDay" name="riskDay" :label="$t('joinpayMch.settlementCycleLabel')"
-            :placeholder="$t('joinpayMch.settlementCyclePlaceholder')" @update:model-value="fieldUpdate" />
-          <van-field v-model="manageScope" name="manageScope" :label="$t('joinpayMch.natureOfBusinessLabel')"
-            :placeholder="$t('joinpayMch.natureOfBusinessPlaceholder')" @update:model-value="fieldUpdate" />
-          <van-field v-model="manageAddr" name="manageAddr" :label="$t('joinpayMch.businessAddressLabel')"
-            :placeholder="$t('joinpayMch.businessAddressPlaceholder')" @update:model-value="fieldUpdate" />
-          <!-- 操作 -->
-          <van-row justify="space-around" style="padding: 1em">
-            <van-button span="5" round type="primary" style="height: 2em; padding: 0 2em" native-type="submit">{{
-              $t('joinpayMch.submitDataForReview') }}
-            </van-button>
-          </van-row>
-        </van-form>
-      </div>
-      <div v-if="pageType === '2'" class="joinPayMch2">
-        <img src='../../assets/joinPayMch/center.png' style="width: 50%; margin-top: 3em;" />
-        <div v-if="joinPayMchType === '0'" style="width: 100%;">
-          <div style="width: 100%; text-align: center;">
-            <span style=" font-size: 1.4em; font-weight: bold; line-height: 3;">{{
-              $t('joinpayMch.thePlatformAdministratorIsReviewing') }}</span>
-          </div>
-          <div style="width: 100%; text-align: center;">
-            <span style="line-height: 1.2;">{{ $t('joinpayMch.youCan') }}<span
-                style="color: #4d6add; text-decoration: underline;" @click='updateJoinPay()'>{{
-                  $t('joinpayMch.withdrawAndRevise') }}</span></span>
-          </div>
-        </div>
-        <div v-if="joinPayMchType === '2' || joinPayMchType === '3'" style="width: 100%;">
-          <div style="width: 100%; text-align: center;">
-            <span style=" font-size: 1.4em; font-weight: bold; line-height: 3; color: #ee0a24;">{{
-              $t('joinpayMch.failedToPassTheReview') }}</span>
-          </div>
-          <div style="width: 100%; text-align: center;">
-            <span style="line-height: 1.2;">{{ $t('joinpayMch.failedToPassTheReview') }},<span
-                style="color: #4d6add; text-decoration: underline;" @click='pageType = "1"'>{{
-                  $t('joinpayMch.clickHereToFillInTheInformationAgain') }}</span></span>
-          </div>
-        </div>
-        <div v-if="joinPayMchStep === '0'">
-          <div style="width: 100%; text-align: center;">
-            <span style=" font-size: 1.4em; font-weight: bold; line-height: 3; color: #07c160;">{{
-              $t('joinpayMch.approvalPassed') }}</span>
-          </div>
-          <div style="width: 100%; text-align: center;">
-            <span style="line-height: 1.2;">{{ $t('joinpayMch.approvalPassed') }},{{ $t('joinpayMch.youCan') }}<span
-                style="color: #4d6add; text-decoration: underline;" @click='pageType = "1"'>{{
-                  $t('joinpayMch.clickHereToFillInAgainAndSubmitForReview') }}</span></span>
-          </div>
-          <van-row justify="space-around" style="padding: 1em">
-            <van-button span="5" round type="primary" style="height: 2em; padding: 0 2em" @click='pageType = "3"'>
-              {{ $t('joinpayMch.nextGoToUploadIDPhotos') }}</van-button>
-          </van-row>
-        </div>
-      </div>
-      <div v-if="pageType === '3'">
-        <van-form @submit="sentImageFun">
-          <div class="upLoaderRow">
-            <div class="baseRow flex-row justify-between">
-              <div class="group2 flex-col"></div>
-              <span class="baseText">{{ $t('joinpayMch.uploYourIdCard') }}</span>
-            </div>
-            <div class="cardRow">
-              <div class="cardLi">
-                <van-uploader v-model="cardNegativeList" :max-size="2 * 1024 * 1024" :max-count="1"
-                  :after-read="afterRead" @oversize="onOversize" />
-                <p>{{ $t('joinpayMch.uploPortrait') }}</p>
-              </div>
-              <div class="cardLi">
-                <van-uploader v-model="cardPositiveList" :max-size="2 * 1024 * 1024" :max-count="1"
-                  :after-read="afterRead" @oversize="onOversize" />
-                <p>{{ $t('joinpayMch.uploNatiEmblem') }}</p>
-              </div>
-            </div>
-          </div>
-          <div class="upLoaderRow" v-if="bankAccountType === '4'">
-            <div class="baseRow flex-row justify-between">
-              <div class="group2 flex-col"></div>
-              <span class="baseText">{{ $t('joinpayMch.businessLicensePlace') }}</span>
-            </div>
-            <div class="cardRow">
-              <div class="cardLi">
-                <van-uploader v-model="tradeLicenceList" :max-size="2 * 1024 * 1024" :max-count="1"
-                  :after-read="afterRead" @oversize="onOversize" />
-                <p>{{ $t('joinpayMch.businessLicense') }}</p>
-              </div>
-            </div>
-          </div>
-          <div class="upLoaderRow" v-if="bankAccountType === '4'">
-            <div class="baseRow flex-row justify-between">
-              <div class="group2 flex-col"></div>
-              <span class="baseText">{{ $t('joinpayMch.accountOpeningLicensePlace') }}</span>
-            </div>
-            <div class="cardRow">
-              <div class="cardLi">
-                <van-uploader v-model="openAccountLicenceList" :max-size="2 * 1024 * 1024" :max-count="1"
-                  :after-read="afterRead" @oversize="onOversize" />
-                <p>{{ $t('joinpayMch.accountOpeningLicense') }}</p>
-              </div>
-            </div>
-          </div>
-          <van-row justify="space-around" style="padding: 1em">
-            <van-button span="5" round type="primary" style="height: 2em; padding: 0 2em" native-type="submit">{{
-              $t('joinpayMch.submissions') }}
-            </van-button>
-          </van-row>
-        </van-form>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-import { onMounted, reactive, toRefs, ref } from "vue";
-import sHeader from "../../components/SimpleHeader";
-import { showFailToast, showSuccessToast } from "vant";
-import { getOneJoinPayMch, saveJoinPayMch, updateJoinPayMchCheck, sentImage, altMchSign } from '../../service/joinpayMch';
-import { getLoginUser, styleUrl } from "../../common/js/utils";
-import dateUtil from "../../utils/dateUtil";
-import { useI18n } from "vue-i18n";
-
-export default {
-  components: { sHeader },
-  setup() {
-    // 引入语言
-    const { t } = useI18n();
-    const user = getLoginUser();
-    const idCardExpiryShow = ref(false);
-    const idCardExpiryOnConfirm = (value) => {
-      idCardExpiryShow.value = false;
-      addParams.idCardExpiry = dateUtil.formateDate(value, "yyyy-MM-dd");
-      fieldUpdate();
-    };
-    const licenseExpiryShow = ref(false);
-    const licenseExpiryOnConfirm = (value) => {
-      licenseExpiryShow.value = false;
-      addParams.licenseExpiry = dateUtil.formateDate(value, "yyyy-MM-dd");
-      fieldUpdate();
-    };
-    let addParams = reactive({
-      adminId: user.id, // 当前登录账户的id Long 必填
-      altMchName: '', // 分账方名称; string 必填
-      altMchNo: '', // 分账方账号; string	必填
-      altMchShortName: '', // 分账方商户简称;	string
-      altMerchantType: '10', // 分账方商户类型,10:个人,11:个体工商户,12:企业;	integer(int32)	必填
-
-      busiContactName: '', // 业务联系人姓名;	string	必填
-      busiContactMobileNo: '', // 业务联系人手机;	string	必填
-      legalPerson: '', // 法人;	string	必填
-      phoneNo: '', // 电话;	string	必填
-      idCardNo: '', // 身份证;	string	必填
-      idCardExpiry: '', // 身份证有效期;	string
-
-      bankAccountType: 1, // 账户类型 * 1 借记卡,4 对公账户;	integer(int32)	必填
-      bankAccountName: '', // 银行账户名称,分账方结算银行账户名称;	string	必填
-      bankAccountNo: '', // 银行账号;	string	必填
-      bankChannelNo: '', // 联行号;	string	对公账户;必填
-      licenseNo: '', // 营业执照编号;	string	对公账户;必填
-      licenseExpiry: '', // 营业执照有效期;	string
-
-      settMode: 1, // 结算方式 * 1 由汇聚自动结算 * 2 由商户平台手工结算(结算接口);	integer(int32)	默认填1
-      settDateType: 1, // 结算周期类型 * 1 工作日,2 自然日,3 月结日;	integer(int32)	默认填1
-      riskDay: 1, // 结算周期;	integer(int32)	默认填1
-      manageScope: '', // 经营范围;	string
-      manageAddr: '', // 经营地址;	string
-
-      bizCode: '', // 业务响应码;	string
-      loginName: '', // 分账方登录名,即邮箱;	string
-    });
-    let cardPositiveList = ref([]);
-    let cardNegativeList = ref([]);
-    let tradeLicenceList = ref([]);
-    let openAccountLicenceList = ref([]);
-    let sentImageForm = reactive({
-      cardPositive: '', // 身份证正面	String	必填
-      cardNegative: '', // 	身份证背面	String	必填
-      tradeLicence: '', // 	营业执照图片	String	Type=0时必填
-      openAccountLicence: '', // 	开户许可证	String	Type=0时必填
-      type: '', // 	账户类型	String	必填 0:对公;1,个人
-      status: '0', // 	第几次提交	String	必填 0,第一次提交;1,第n次提交(重新上传)
-    });
-    const pageType = ref('1');
-    const joinPayMchType = ref(null);
-    const joinPayMchStep = ref(null);
-    let joinPayMchID = null;
-    const approveStatus = ref(null);
-    const signStatus = ref(null);
-    let isMemoryFormType = false;
-    onMounted(async () => {
-      styleUrl('joinpayMch');
-      getOneJoinPayMchFun();
-    });
-    // 获取备用提现账号回显
-    const getOneJoinPayMchFun = async () => {
-      const { data } = await getOneJoinPayMch({ adminId: user.id });
-      if (data.code === "00000") {
-        if (data.data.type === '2' || data.data.type === '3' || data.data.type === '0') {
-          joinPayMchType.value = data.data.type;
-          pageType.value = '2';
-        }
-        if ((data.data.type === null || data.data.type === '1') && data.data.step === '0') {
-          pageType.value = '2';
-          joinPayMchStep.value = '0';
-        }
-        if ((data.data.type === null || data.data.type === '1') && data.data.step === '1') {
-          pageType.value = '4';
-        }
-        console.log('pageType', pageType.value);
-
-        joinPayMchID = data.data.id;
-        approveStatus.value = data.data.approveStatus;
-        signStatus.value = data.data.signStatus;
-        addParams.altMchName = data.data.altMchName;
-        addParams.altMchNo = data.data.altMchNo;
-        addParams.altMchShortName = data.data.altMchShortName;
-        addParams.altMerchantType = data.data.altMerchantType ? data.data.altMerchantType.toString() : '';
-
-        addParams.busiContactName = data.data.busiContactName;
-        addParams.busiContactMobileNo = data.data.busiContactMobileNo;
-        addParams.legalPerson = data.data.legalPerson;
-        addParams.phoneNo = data.data.phoneNo;
-        addParams.idCardNo = data.data.idCardNo;
-        if (data.data.idCardExpiry) {
-          addParams.idCardExpiry = dateUtil.formateDate(new Date(data.data.idCardExpiry), "yyyy-MM-dd");
-        }
-
-        addParams.bankAccountType = data.data.bankAccountType ? data.data.bankAccountType.toString() : '';
-        addParams.bankAccountName = data.data.bankAccountName;
-        addParams.bankAccountNo = data.data.bankAccountNo;
-        addParams.bankChannelNo = data.data.bankChannelNo;
-        addParams.licenseNo = data.data.licenseNo;
-        if (data.data.licenseExpiry) {
-          addParams.licenseExpiry = dateUtil.formateDate(new Date(data.data.licenseExpiry), "yyyy-MM-dd");
-        }
-
-        addParams.settMode = data.data.settMode ? data.data.settMode.toString() : '';
-        addParams.settDateType = data.data.settDateType ? data.data.settDateType.toString() : '';
-        addParams.riskDay = data.data.riskDay;
-        addParams.manageScope = data.data.manageScope;
-        addParams.manageAddr = data.data.manageAddr;
-
-        addParams.bizCode = data.data.bizCode;
-        addParams.loginName = data.data.loginName;
-      } else {
-        pageType.value = '1';
-        showFailToast(data.message);
-      }
-      memoryForm();
-      isMemoryFormType = true;
-    };
-    // 记忆表单
-    const memoryForm = () => {
-      const formDataString = localStorage.getItem('joinPayMchForm');
-      if (formDataString) {
-        const formData = JSON.parse(formDataString);
-        Object.keys(formData).forEach(key => {
-          addParams[key] = formData[key];
-        });
-      }
-    };
-    // 提交审批表单
-    const saveJoinPayMchFun = async () => {
-      const params = Object.assign({}, addParams);
-      params.altMerchantType = parseInt(params.altMerchantType);
-      params.bankAccountType = parseInt(params.bankAccountType);
-      params.settMode = parseInt(params.settMode);
-      params.settDateType = parseInt(params.settDateType);
-      const { data } = await saveJoinPayMch(addParams);
-      if (data.code === "00000") {
-        showSuccessToast(t(('joinpayMch.submittedSuccessfully')));
-        // 提交成功后删除记忆的表单
-        localStorage.removeItem('joinPayMchForm');
-        location.reload();
-      } else {
-        showFailToast(`${t('joinpayMch.submitFailed')} ${data.message}`);
-      }
-    };
-    // 撤回
-    const updateJoinPay = async () => {
-      const { data } = await updateJoinPayMchCheck({ id: joinPayMchID });
-      if (data.code === "00000") {
-        showSuccessToast(t('joinpayMch.withdrawalSucceeded'));
-        location.reload();
-      } else { showFailToast(`${data.message}`); }
-    }
-    // 图片上传表单提交
-    const sentImageFun = async () => {
-      const params = {
-        id: joinPayMchID,
-        type: addParams.bankAccountType === '4' ? '0' : '1',
-        status: sentImageForm.status,
-        tradeLicence: null,
-        openAccountLicence: null
-      };
-      if (cardNegativeList.value.length < 1) { showFailToast(t('joinpayMch.uploPortrait')); return; }
-      if (cardPositiveList.value.length < 1) { showFailToast(t('joinpayMch.uploNatiEmblem')); return; }
-      params.cardPositive = cardPositiveList.value[0].content;
-      params.cardNegative = cardNegativeList.value[0].content;
-      if (addParams.bankAccountType === '4') {
-        if (tradeLicenceList.value.length < 1) { showFailToast(t('joinpayMch.businessLicensePlace')); return; }
-        if (openAccountLicenceList.value.length < 1) { showFailToast(t('joinpayMch.accountOpeningLicensePlace')); return; }
-      }
-      if (tradeLicenceList.value.length > 0) { params.tradeLicence = tradeLicenceList.value[0].content; }
-      if (openAccountLicenceList.value.length > 0) { params.openAccountLicence = openAccountLicenceList.value[0].content; }
-      const { data } = await sentImage(params);
-      if (data.code === "00000") {
-        showSuccessToast(t('joinpayMch.uploadSucceeded'));
-        location.reload();
-      } else { showFailToast(`${data.message}`); }
-    }
-    // 图片重新上传触发
-    const updateSentImage = () => {
-      sentImageForm.status = '1';
-      pageType.value = '3';
-    }
-    // 签约触发
-    const altMchSignFun = async () => {
-      const { data } = await altMchSign({ id: joinPayMchID });
-      if (data.code === "00000") {
-        showSuccessToast(t('joinpayMch.signingSuccessfully'));
-        location.reload();
-      } else { showFailToast(`${data.message}`); }
-    }
-    // 记录表单填写
-    const fieldUpdate = () => {
-      console.log('fieldUpdate');
-      if (isMemoryFormType) {
-        localStorage.setItem('joinPayMchForm', JSON.stringify(addParams));
-      }
-    };
-    // 文件上传
-    const afterRead = (file) => {
-      console.log('afterRead', file);
-      console.log('afterRead', file.content);
-      console.log(cardPositiveList);
-    }
-    const onOversize = () => { showFailToast(t('joinpayMch.exceedPictSize')); }
-    return {
-      pageType,
-      joinPayMchType,
-      joinPayMchStep,
-      ...toRefs(addParams),
-      ...toRefs(sentImageForm),
-      cardPositiveList,
-      cardNegativeList,
-      tradeLicenceList,
-      openAccountLicenceList,
-      saveJoinPayMchFun,
-      updateJoinPay,
-      sentImageFun,
-      approveStatus,
-      signStatus,
-      updateSentImage,
-      altMchSignFun,
-      idCardExpiryShow,
-      idCardExpiryOnConfirm,
-      licenseExpiryShow,
-      licenseExpiryOnConfirm,
-      fieldUpdate,
-      afterRead,
-      onOversize
-    };
-  },
-};
-</script>
-
-<style lang="less" scoped>
-@import "../../common/style/common.less";
-</style>

+ 113 - 28
src/views/orderCenter/index.vue

@@ -245,6 +245,13 @@
             :collapse-text="$t('orderCenter.stow')"
           />
         </div>
+        <div
+          v-if="refundObject.memberCode != null"
+          class="orderDetailBox flex-row justify-between"
+        >
+          <span class="title">{{ $t("orderCenter.memberCode") }}</span>
+          <span class="content">{{ refundObject.memberCode }}</span>
+        </div>
         <div class="orderDetailBox flex-row justify-between">
           <span class="title">{{ $t("orderCenter.state") }}</span>
           <span class="content">{{ showStatus(refundObject) }}</span>
@@ -312,19 +319,6 @@
             >更新</van-button
           >
         </div>
-        <van-field
-          v-if="
-            refundObject.status === 1 &&
-            user.ifForeign === '0' &&
-            user.type < 2 &&
-            orderType != '3'
-          "
-          v-model="customerPhone"
-          center
-          label="联系方式"
-          placeholder="消费者联系方式,没有则不填"
-        >
-        </van-field>
         <!-- 发起退款 -->
         <!-- 非已付款订单,线下订单要隐藏按钮 -->
         <div
@@ -346,7 +340,7 @@
               user.type < 2 &&
               orderType != '3'
             "
-            @click="sentRefundMessage(refundObject)"
+            @click="showSendDialog = true"
             round
             type="primary"
             style="padding: 15px 15px; margin-top: 20px"
@@ -374,6 +368,45 @@
           >
             {{ $t("orderCenter.initiateRefund") }}
           </van-button>
+
+          <!-- 短信发送确认弹窗 -->
+          <van-dialog
+            v-model:show="showSendDialog"
+            title="提醒"
+            :showCancelButton="true"
+            class="complaint-dialog"
+            @confirm="sentRefundMessage(refundObject)"
+          >
+            <div class="dialog-content">
+              <!-- 消费者号码输入 -->
+              <div class="input-group">
+                <label class="input-label">消费者号码</label>
+                <van-field
+                  v-model="customerPhone"
+                  class="input-field"
+                  type="tel"
+                  placeholder="没有不填"
+                  clearable
+                />
+              </div>
+
+              <!-- 投诉原因输入 -->
+              <div class="input-group">
+                <label class="input-label required">投诉原因</label>
+                <van-field
+                  v-model="reason"
+                  class="input-field"
+                  rows="3"
+                  type="textarea"
+                  autosize
+                  maxlength="20"
+                  show-word-limit
+                  placeholder="请输入投诉原因"
+                  :border="false"
+                />
+              </div>
+            </div>
+          </van-dialog>
         </div>
       </div>
     </van-popup>
@@ -510,6 +543,8 @@ export default {
     const isInvoice = ref(0);
     // 账户余额
     const balance = ref(0);
+    // 短信确认弹窗
+    const showSendDialog = ref(false);
     // 更新是否开发票
     const updateInvoice = async (id) => {
       const params = {
@@ -660,27 +695,21 @@ export default {
         });
     };
     const customerPhone = ref(""); // 消费者号码
+    const reason = ref(""); // 投诉原因
     // 发送退款提醒短信
     const sentRefundMessage = async (row) => {
       const params = {
         id: row.id,
         customerPhone: customerPhone.value,
         adminId: user.id,
+        reason: reason.value,
       };
-      showConfirmDialog({
-        message: "是否确认发送短信?",
-      })
-        .then(async () => {
-          const { data } = await sentMessage(params);
-          if (data.code === "00000") {
-            showSuccessToast("发送成功");
-          } else {
-            showFailToast(data.message);
-          }
-        })
-        .catch(() => {
-          return;
-        });
+      const { data } = await sentMessage(params);
+      if (data.code === "00000") {
+        showSuccessToast("发送成功");
+      } else {
+        showFailToast(data.message);
+      }
     };
     // 退款操作
     const refundAjax = async () => {
@@ -1243,6 +1272,8 @@ export default {
       total,
       balance,
       statusClass,
+      showSendDialog,
+      reason,
     };
   },
 };
@@ -1680,4 +1711,58 @@ export default {
     background-color: #2c87c8;
   }
 }
+
+.complaint-dialog {
+  :deep(.van-dialog__header) {
+    padding: 20px 20px 10px;
+    font-size: 18px;
+    font-weight: 600;
+    // color: --;
+  }
+
+  :deep(.van-dialog__content) {
+    padding: 0;
+  }
+}
+
+.dialog-content {
+  padding: 0 20px 20px;
+}
+
+.input-group {
+  margin-bottom: 20px;
+
+  &:last-child {
+    margin-bottom: 25px;
+  }
+}
+
+.input-label {
+  display: block;
+  margin-bottom: 8px;
+  font-size: 14px;
+  color: var(--text-primary);
+  font-weight: 500;
+}
+
+.input-field {
+  background-color: #f9fbfe;
+  border-radius: 8px;
+  padding: 10px 15px;
+
+  :deep(.van-field__control) {
+    font-size: 14px;
+    color: var(--text-secondary);
+  }
+}
+
+@media (max-width: 480px) {
+  .dialog-content {
+    padding: 0 15px 15px;
+  }
+
+  .input-group {
+    margin-bottom: 15px;
+  }
+}
 </style>

+ 100 - 102
src/views/register.vue

@@ -261,8 +261,7 @@
               :rules="[
                 { required: true, message: $t('register.emailRequired') },
                 {
-                  pattern:
-                    /^[a-z0-9]+([._\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/,
+                  pattern: /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/,
                   message: $t('register.emailInvalid'),
                 },
               ]"
@@ -313,8 +312,7 @@
               :rules="[
                 { required: true, message: $t('register.emailRequired') },
                 {
-                  pattern:
-                    /^[a-z0-9]+([._\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/,
+                  pattern: /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/,
                   message: $t('register.emailInvalid'),
                 },
               ]"
@@ -361,12 +359,6 @@
             v-model="inviteCode"
             name="inviteCode"
             :placeholder="$t('register.invitationCodePlaceholder')"
-            :rules="[
-              {
-                required: true,
-                message: $t('register.invitationCodePlaceholder'),
-              },
-            ]"
             class="form-field"
           >
             <template #left-icon>
@@ -390,19 +382,18 @@
   </div>
 </template>
 <script>
-import md5 from 'js-md5';
-import { ref, onMounted, reactive, toRefs, watch } from 'vue';
-import { showFailToast, showToast } from 'vant';
-import { sentRegisterCode, tAdminSave } from '@/service/register';
-import sHeader from '@/components/SimpleHeader';
+import md5 from "js-md5";
+import { ref, onMounted, reactive, toRefs, watch } from "vue";
+import { showFailToast, showToast } from "vant";
+import { sentRegisterCode, tAdminSave } from "@/service/register";
+import sHeader from "@/components/SimpleHeader";
 import logiLogoImgUrl from "@/assets/login/logo.png";
-import { useRouter } from 'vue-router';
-import { getLocal, setLocal, styleUrl } from '@/common/js/utils';
+import { useRouter } from "vue-router";
+import { getLocal, setLocal, styleUrl } from "@/common/js/utils";
 import { useI18n } from "vue-i18n";
-import { countriesData } from '@/common/js/countries';
-import { countriesDataEn } from '@/common/js/countries-en';
-import { useCascaderAreaData } from '@vant/area-data';
-
+import { countriesData } from "@/common/js/countries";
+import { countriesDataEn } from "@/common/js/countries-en";
+import { useCascaderAreaData } from "@vant/area-data";
 
 export default {
   setup() {
@@ -410,54 +401,57 @@ export default {
     const languageName = ref(getLocal("curLang"));
     const { t } = useI18n();
     const active = ref(0);
-    const username = ref('');
-    const name = ref('');
-    const password = ref('');
-    const passwordCheck = ref('');
-    const ifForeign = ref('0');
-    const logonMode = ref('10');
-    const phone = ref('');
-    const email = ref('');
-    const code = ref('');
-    const inviteCode = ref('');
+    const username = ref("");
+    const name = ref("");
+    const password = ref("");
+    const passwordCheck = ref("");
+    const ifForeign = ref("0");
+    const logonMode = ref("10");
+    const phone = ref("");
+    const email = ref("");
+    const code = ref("");
+    const inviteCode = ref("");
     const verifyRef = ref(null);
     const verCodeTime = reactive({
-      time: 0
+      time: 0,
     });
 
-    let phoneOrEmailStr = ref('');
+    let phoneOrEmailStr = ref("");
 
     const router = useRouter();
     const reqApi = ref(false);
 
-    const citiesValue = ref('');
+    const citiesValue = ref("");
     const showCountry = ref(false);
-    const cityValue = ref('');
-    const countryOptions = ref(languageName.value == 'zh' ? countriesData : countriesDataEn);
+    const cityValue = ref("");
+    const countryOptions = ref(
+      languageName.value == "zh" ? countriesData : countriesDataEn
+    );
 
-    const { locale } = useI18n()
+    const { locale } = useI18n();
     watch(locale, (newValue) => {
-      if (newValue == 'zh') {
+      if (newValue == "zh") {
         countryOptions.value = countriesData;
       } else {
         countryOptions.value = countriesDataEn;
       }
     });
     const onConfirmCountry = ({ selectedOptions }) => {
-      cityValue.value = selectedOptions.map((option) => option.text).join('/');
+      cityValue.value = selectedOptions.map((option) => option.text).join("/");
       citiesValue.value = selectedOptions[1]?.value;
       showCountry.value = false;
     };
 
     const areaOptions = ref();
-    const areaValue = ref('');
+    const areaValue = ref("");
     const showArea = ref(false);
     const onConfirmArea = ({ selectedOptions }) => {
       if (selectedOptions[0]?.text == selectedOptions[1]?.text) {
         areaValue.value = selectedOptions[0]?.text;
         citiesValue.value = selectedOptions[0]?.text;
       } else {
-        areaValue.value = selectedOptions[0]?.text + "/" + selectedOptions[1]?.text;
+        areaValue.value =
+          selectedOptions[0]?.text + "/" + selectedOptions[1]?.text;
         citiesValue.value = selectedOptions[0]?.text + selectedOptions[1]?.text;
       }
       showArea.value = false;
@@ -466,11 +460,11 @@ export default {
     // 注册点击
     const registerSubmit = async () => {
       if (password.value !== passwordCheck.value) {
-        showFailToast(t('register.twoTypedDiff'));
+        showFailToast(t("register.twoTypedDiff"));
         return false;
       }
-      if (username.value ==='admin') {
-        showFailToast(t('register.A0201'));
+      if (username.value === "admin") {
+        showFailToast(t("register.A0201"));
         return false;
       }
       const { data } = await tAdminSave({
@@ -480,41 +474,41 @@ export default {
         ifForeign: ifForeign.value,
         phoneOrEmail: phone.value || email.value,
         code: code.value,
-        companyType: '1',
+        companyType: "1",
         inviteCode: inviteCode.value,
-        cities: citiesValue.value
+        cities: citiesValue.value,
       });
 
-      if (data.code === '00000') {
-        showToast(t('register.registerSucess'));
-        router.push({ path: '/login' });
-      } else if (data.code === 'R0001') {
-        showFailToast(t('register.R0001'));
-      } else if (data.code === 'R0002') {
-        showFailToast(t('register.R0002'));
-      } else if (data.code === 'R0003') {
-        showFailToast(t('register.R0003'));
-      } else if (data.code === 'R0004') {
-        showFailToast(t('register.R0004'));
-      } else if (data.code === 'R0005') {
-        showFailToast(t('register.R0005'));
-      } else if (data.code === 'R0006') {
-        showFailToast(t('register.R0006'));
-      } else if (data.code === 'A0201') {
-        showFailToast(t('register.A0201'));
-      } else if (data.code === 'A0203') {
-        showFailToast(t('register.A0203'));
+      if (data.code === "00000") {
+        showToast(t("register.registerSucess"));
+        router.push({ path: "/login" });
+      } else if (data.code === "R0001") {
+        showFailToast(t("register.R0001"));
+      } else if (data.code === "R0002") {
+        showFailToast(t("register.R0002"));
+      } else if (data.code === "R0003") {
+        showFailToast(t("register.R0003"));
+      } else if (data.code === "R0004") {
+        showFailToast(t("register.R0004"));
+      } else if (data.code === "R0005") {
+        showFailToast(t("register.R0005"));
+      } else if (data.code === "R0006") {
+        showFailToast(t("register.R0006"));
+      } else if (data.code === "A0201") {
+        showFailToast(t("register.A0201"));
+      } else if (data.code === "A0203") {
+        showFailToast(t("register.A0203"));
       } else {
-        showFailToast(t('register.registerFail'));
+        showFailToast(t("register.registerFail"));
       }
     };
 
     // 发送验证码
     const seedVerCode = async () => {
       reqApi.value = true;
-      if (ifForeign.value === '1') {
+      if (ifForeign.value === "1") {
         phoneOrEmailStr = email.value;
-      } else if (ifForeign.value === '0' && logonMode.value === '10') {
+      } else if (ifForeign.value === "0" && logonMode.value === "10") {
         phoneOrEmailStr = phone.value;
       } else {
         phoneOrEmailStr = email.value;
@@ -524,46 +518,46 @@ export default {
         const { data } = await sentRegisterCode({
           ifForeign: ifForeign.value,
           phoneOrEmail: phoneOrEmailStr,
-          hostName: 'SevenCloud',
+          hostName: "SevenCloud",
         });
         reqApi.value = false;
-        if (data.code === '00000') {
+        if (data.code === "00000") {
           showToast(data.data);
           verCodeTime.time = 1 * 60; // 1分钟定时器,60s后可以更换验证方式
           verCodeTimeInterval();
-        } else if (data.code === 'R0009') {
-          showToast(t('register.R0009'));
-        } else if (data.code === 'R0008') {
-          showToast(t('register.R0008'));
-        } else if (data.code === 'A0202') {
-          showToast(t('register.A0202'));
-        } else if (data.code === 'A0207') {
-          showToast(t('register.A0207'));
-        } else if (data.code === 'R0004') {
-          showToast(t('register.R0004'));
+        } else if (data.code === "R0009") {
+          showToast(t("register.R0009"));
+        } else if (data.code === "R0008") {
+          showToast(t("register.R0008"));
+        } else if (data.code === "A0202") {
+          showToast(t("register.A0202"));
+        } else if (data.code === "A0207") {
+          showToast(t("register.A0207"));
+        } else if (data.code === "R0004") {
+          showToast(t("register.R0004"));
         } else {
           showToast(data.message);
         }
       } catch (error) {
         reqApi.value = false;
       }
-    }
+    };
     // 验证码发送成功开始1分钟倒计时
     const verCodeTimeInterval = () => {
       const intervalId = setInterval(() => {
         verCodeTime.time--;
-        setLocal('registerVerCodeTime', verCodeTime.time);
+        setLocal("registerVerCodeTime", verCodeTime.time);
         if (verCodeTime.time === 0) {
           clearInterval(intervalId); // 清除定时器
         }
       }, 1000);
-    }
+    };
     // 初始化页面获取验证码倒计时
     onMounted(async () => {
       // 加载样式
-      styleUrl('register');
-      verCodeTime.time = getLocal('registerVerCodeTime');
-      if (verCodeTime.time && verCodeTime.time !== '') {
+      styleUrl("register");
+      verCodeTime.time = getLocal("registerVerCodeTime");
+      if (verCodeTime.time && verCodeTime.time !== "") {
         verCodeTime.time = parseInt(verCodeTime.time);
         if (verCodeTime.time > 0) {
           verCodeTimeInterval();
@@ -572,31 +566,35 @@ export default {
         verCodeTime.time = 0;
       }
       const areaData = useCascaderAreaData();
-      areaData.forEach(province => {
-        province.children.forEach(city => {
+      areaData.forEach((province) => {
+        province.children.forEach((city) => {
           // 删除城市中的区级信息
           delete city.children;
         });
       });
       // 删除台湾、澳门和香港
-      const provincesToRemove = ['710000', '810000', '820000'];
-      areaOptions.value = areaData.filter(province => !provincesToRemove.includes(province.value));
+      const provincesToRemove = ["710000", "810000", "820000"];
+      areaOptions.value = areaData.filter(
+        (province) => !provincesToRemove.includes(province.value)
+      );
     });
 
     const signOptions = [
-      { text: '手机注册', value: "mo" },
-      { text: '邮箱注册', value: "ema" }
-    ]
+      { text: "手机注册", value: "mo" },
+      { text: "邮箱注册", value: "ema" },
+    ];
     // 搜索关键词
-    const searchValue = ref('');
-    const countryData = ref(languageName.value == 'zh' ? countriesData : countriesDataEn);
+    const searchValue = ref("");
+    const countryData = ref(
+      languageName.value == "zh" ? countriesData : countriesDataEn
+    );
     // 搜索数据
     const valueChange = (index) => {
       let tempOptions = [];
       if (searchValue.value) {
         if (index === 0) {
           // 国家
-          countryData.value.forEach(item => {
+          countryData.value.forEach((item) => {
             if (item.text.includes(searchValue.value)) {
               tempOptions.push(item);
             }
@@ -626,7 +624,7 @@ export default {
       seedVerCode,
       registerSubmit,
       signOptions,
-      signinModel: 'aaabb',
+      signinModel: "aaabb",
       active,
       logonMode,
       reqApi,
@@ -642,11 +640,11 @@ export default {
       areaValue,
 
       searchValue,
-      valueChange
-    }
+      valueChange,
+    };
   },
-  components: { sHeader }
-}
+  components: { sHeader },
+};
 </script>
 <style lang="less" scoped>
 @theme-color: #2d88c9;
@@ -812,4 +810,4 @@ export default {
     font-size: 16px;
   }
 }
-</style>
+</style>

+ 0 - 9
src/views/user.vue

@@ -912,16 +912,7 @@ export default {
         message: t("user.logOutContent"),
       })
         .then(() => {
-          // 获取缓存的语言
-          // const savedCredentials = localStorage.getItem("savedCredentials");
-          // const curLang = localStorage.getItem("curLang");
-          // 清空缓存
-          // localStorage.clear();
-          // localStorage.setItem("curLang", curLang);
           localStorage.removeItem("loginUser");
-          // if (savedCredentials) {
-          //   localStorage.setItem("savedCredentials", savedCredentials);
-          // }
           if (sys.value) {
             setTimeout(() => {
               router.push({