Pārlūkot izejas kodu

feat:"添加俄语、法语、西班牙语、葡萄牙语"

soobin 5 mēneši atpakaļ
vecāks
revīzija
90b30ba415

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1407 - 1365
src/assets/language/en.json


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1705 - 0
src/assets/language/es.json


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1736 - 0
src/assets/language/fr.json


+ 23 - 9
src/assets/language/ja.json

@@ -1,6 +1,6 @@
 {
     "public": {
-        "sysName": "わたあめ自販機スマートシステム",
+        "sysName": "Sunzee Technology",
         "requestFailed": "リクエストに失敗、再読み込み",
         "noMore": "なし"
     },
@@ -269,7 +269,7 @@
         "messageReceiver1": "デバイスアラーム連絡先1",
         "messageReceiver2": "デバイスアラーム連絡先2",
         "messageReceiver3": "デバイスアラーム連絡先3",
-        "equipmentmessageReceiverPlaceholder": "電話番号を入力",
+        "equipmentmessageReceiverPlaceholder": "Email",
         "repetitionsLabel": "繰り返し回数",
         "repetitionsPlaceholder": "繰り返し回数を入力",
         "alarmTypeLabel": "アラームの種類",
@@ -440,6 +440,9 @@
         "clickToSelectTaste": "クリックして味を選択",
         "pleaseSelectAPattern": "デザイン選択",
         "pleaseSelectTaste": "味を選択",
+        "jam": "ジャム",
+        "nuts​": "砕いたナッツ",
+        "confirmMake": "リモート制作を確定します",
         "todaysSugarList": "今日の綿菓子リスト",
         "todaysMakeList": "今日の製造リスト",
         "goods": "商品:",
@@ -451,7 +454,7 @@
         "machineException": "マシンに異常があり。マシン状態を確認して",
         "netException": "ネットワーク異常",
         "receiveInstruction": "製糖指示受信完了",
-        "dataOverview": "デバイス管理",
+        "dataOverview": "デバイス",
         "search": "検索",
         "totalNumberOfRuns": "総実行数",
         "totalNumberOfEquipment": "総デバイス数",
@@ -1674,10 +1677,21 @@
         "content": "スイッチを切り替えますか?",
         "successfully": "送信成功、数秒後に再度確認してください"
     },
-    "账户操作": "アカウント操作",
-    "优惠码": "プロモーションコード",
-    "报警历史": "アラーム履歴",
-    "广告管理": "広告管理",
-    "订单导出": "注文のエクスポート",
-    "apk管理": "APK管理"
+    "permission": {
+        "M1": "デバイス",
+        "M3": "アカウント",
+        "M4": "注文",
+        "M5": "広告",
+        "M6": "タスク",
+        "M7": "クーポン",
+        "M9": "エクスポート",
+        "M11": "売上",
+        "M14": "分析",
+        "M15": "アラート",
+        "M16": "返金",
+        "M17": "オフライン",
+        "M19": "APK",
+        "M21": "MQTT",
+        "M22": "端末"
+    }
 }

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1705 - 0
src/assets/language/pt.json


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1736 - 0
src/assets/language/ru.json


+ 21 - 54
src/assets/language/zh.json

@@ -446,6 +446,9 @@
     "clickToSelectTaste": "点击选择口味",
     "pleaseSelectAPattern": "请选择花型",
     "pleaseSelectTaste": "请选择口味",
+    "jam": "果酱",
+    "nuts​": "果碎",
+    "confirmMake": "确定远程制作",
     "todaysSugarList": "今日做糖列表",
     "todaysMakeList": "今日制作列表",
     "goods": "商品:",
@@ -785,23 +788,6 @@
       "sun": "周日"
     }
   },
-  "airwallex": {
-    "sunzee": "申泽智能",
-    "checkout": "结算",
-    "airwallex": "空中云汇",
-    "wallet": "空中云汇钱包",
-    "amount": "钱包金额",
-    "payment": "付款转账",
-    "paymentDetail": "付款详情",
-    "payout": "付款单",
-    "beneficiary": "收款人",
-    "payForIt": "立即支付",
-    "cancelOrder": "取消订单",
-    "productName": "商品名称",
-    "productsNum": "商品数量",
-    "totalPrice": "合计金额",
-    "shoppingVoucher": "购物凭证"
-  },
   "joinpayMch": {
     "huifuAuditStatus": "汇付入驻状态",
     "joinpayAuditStatus": "汇聚入驻状态",
@@ -1098,6 +1084,7 @@
     "pleaseSelectAPattern": "请选择花型",
     "deviceManagement": "设备管理",
     "mqtt": "MQTT管理",
+    "terminal": "终端管理",
     "deviceView": "设备查看",
     "distributionSettings": "分销设置",
     "alarmHistory": "报警历史",
@@ -1234,37 +1221,6 @@
     "update": "修改",
     "uploadPage": "重新上传图片"
   },
-  "subLedgerManage": {
-    "exportOfShandeLedgerData": "杉德分账数据导出",
-    "accountType": "账号类型",
-    "corporateAccountNo": "对公账号",
-    "personalAccount": "个人账号",
-    "filterAccounts": "筛选账户",
-    "inTotal": "共2条",
-    "exportToExcel": "导出excel",
-    "account": "账号",
-    "settAmount": "已结算金额",
-    "amouToBeSettled": "待结算金额",
-    "lastSettTime": "上次结算时间",
-    "search": {
-      "title": "根据以下条件筛选商户账户",
-      "screen": "筛选",
-      "business": "商家",
-      "account": "账户",
-      "busiPlaceholder": "请选择商家",
-      "accoPlaceholder": "请输入账号"
-    },
-    "settleProcess": {
-      "settleAmount": "结算金额",
-      "settleAmountPlaceholder": "请输入结算金额",
-      "notAccountNum": "不计算账号",
-      "notAccountNumPlaceholder": "请输入不计算账号",
-      "settleProcess": "结算处理",
-      "title": "请再次确认是否进行结算",
-      "cancelTxt": "再想想",
-      "confrimTxt": "进行结算"
-    }
-  },
   "taskMessage": {
     "equipmentInitializationApproval": "设备初始化审批",
     "total": "共 ",
@@ -1730,10 +1686,21 @@
     "content": "是否切换开关?",
     "successfully": "发送成功,请等待几秒后重新进入查看"
   },
-  "账户操作": "账户操作",
-  "优惠码": "优惠码",
-  "报警历史": "报警历史",
-  "广告管理": "广告管理",
-  "订单分析": "订单分析",
-  "apk管理": "apk管理"
+  "permission": {
+    "M1": "设备管理",
+    "M3": "账户操作",
+    "M4": "订单数据",
+    "M5": "广告管理",
+    "M6": "任务消息",
+    "M7": "优惠码",
+    "M9": "订单导出",
+    "M11": "销售排行",
+    "M14": "数据概览",
+    "M15": "报警历史",
+    "M16": "订单退款",
+    "M17": "系统脱机",
+    "M19": "APK",
+    "M21": "MQTT",
+    "M22": "终端管理"
+  }
 }

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

@@ -1343,6 +1343,19 @@ export const countriesDataEn = [
     ],
   },
   {
+    text: "Romania",
+    value: "RO",
+    children: [
+      { text: "Bucharest", value: "Bucharest" },
+      { text: "Cluj-Napoca", value: "Cluj-Napoca" },
+      { text: "Timișoara", value: "Timișoara" },
+      { text: "Iași", value: "Iași" },
+      { text: "Constanța", value: "Constanța" },
+      { text: "Brașov", value: "Brașov" },
+      { text: "Galați", value: "Galați" }
+    ],
+  },
+  {
     text: "Rwanda",
     value: "RW",
     children: [

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

@@ -1557,6 +1557,19 @@ export const countriesData = [
     ],
   },
   {
+    text: "罗马尼亚",
+    value: "RO",
+    children: [
+      { text: "布加勒斯特", value: "Bucharest" },
+      { text: "克卢日-纳波卡", value: "Cluj-Napoca" },
+      { text: "蒂米什瓦拉", value: "Timișoara" },
+      { text: "雅西", value: "Iași" },
+      { text: "康斯坦察", value: "Constanța" },
+      { text: "布拉索夫", value: "Brașov" },
+      { text: "加拉茨", value: "Galați" }
+    ],
+  },
+  {
     text: "挪威",
     value: "NO",
     children: [

+ 15 - 25
src/common/js/utils.js

@@ -11,31 +11,21 @@ import i18n from '../../utils/i18n';
 const t = i18n.global.t;
 // 菜单标识
 export const $M_Menus = {
-  "M1": t("role.deviceManagement"),//设备管理
-  // "M2":t("role.deviceView"),//设备查看
-  // "M3":t("role.distributionSettings"),//分销设置
-  "M3": t("role.accountOperation"),//账户操作
-  // "M4":t("role.orderData"),//报警历史
-  "M4": t("role.orderData"),//订单数据
-  "M5": t("role.advertisingManagement"),//广告管理
-  "M6": t("role.taskMessage"),//任务消息
-  "M7": t("role.discountCode"),//优惠码
-  // "M8":t("role.accountPermission"),//账号权限
-  "M9": t("role.orderExport"),//订单导出
-  // "M10":t("role.shandeSubLedger"),//杉德分账
-  "M11":t("role.salesRanking"),//销售排行
-  // "M12":t("role.withdrawalAccountNo"),//提现账号
-  // "M13":t("role.standbyWithdrawalAccountNo"),//备用提现账号
-  "M14": t("role.dataOverview"),//数据概览
-  // "M15":t("role.alarmHistory"),//订单数据
-  "M15": t("role.alarmHistory"),//报警历史
-  "M16": t("role.orderRefund"),//订单退款
-  "M17": t("role.systemOffline"),//系统脱机
-  // "M18":t("role.labelMan"),//标签管理
-  "M19": t("role.apkMan"),//apk管理
-  // "M20":t("role.merchantMan"),//商户管理
-  "M21": t("role.mqtt"),//MQTT
-  "M22": '终端管理',//终端管理
+  "M1": t("permission.M1"),//设备管理
+  "M3": t("permission.M3"),//账户操作
+  "M4": t("permission.M4"),//订单数据
+  "M5": t("permission.M5"),//广告管理
+  "M6": t("permission.M6"),//任务消息
+  "M7": t("permission.M7"),//优惠码
+  "M9": t("permission.M9"),//订单导出
+  "M11":t("permission.M11"),//销售排行
+  "M14": t("permission.M14"),//数据概览
+  "M15": t("permission.M15"),//报警历史
+  "M16": t("permission.M16"),//订单退款
+  "M17": t("permission.M17"),//系统脱机
+  "M19": t("permission.M19"),//apk管理
+  "M21": t("permission.M21"),//MQTT
+  "M22": t("permission.M22"),//终端管理
 }
 // 判断值是否是数字 true:数值型的,false:非数值型
 export const $M_IsNaN = (num) => {

+ 230 - 10
src/components/SimpleHeader.vue

@@ -1,19 +1,82 @@
 <template>
-  <!-- <div class="block">
-    <header class="simple-header van-hairline--bottom" :style="{ position: isFixed ? 'fixed' : 'relative' }">
-      <i v-if="!isback" class="nbicon nbfanhui" @click="goBack"></i>
-      <i v-else></i>
-      <div class="simple-header-name">{{ name }}</div>
-      <i class="nbicon nbmore moreIcon"></i>
-    </header>
-  </div> -->
-  <van-nav-bar v-if="!isback" :title="name" :border="isBorder" left-arrow @click-left="onClickLeft" :style="barStyle"/>
-  <van-nav-bar v-else :title="name" />
+  <!-- <van-nav-bar v-if="!isback" :title="name" :border="isBorder" left-arrow @click-left="onClickLeft" :style="barStyle" />
+  <van-nav-bar v-else :title="name" /> -->
+  <van-nav-bar v-if="!isback" :title="name" :border="isBorder" left-arrow @click-left="onClickLeft" :style="barStyle">
+    <!-- 右侧语言切换 -->
+    <template #right>
+      <div class="nav-language">
+        <van-button round size="small" class="lang-trigger" @click="showPopover = true">
+          <div class="current-lang">
+            <img :src="currentLang.flag" class="current-flag" />
+            <span class="lang-code">{{ currentLang.code.toUpperCase() }}</span>
+          </div>
+        </van-button>
+
+        <van-popover v-model:show="showPopover" :offset="[0, 8]" placement="bottom-end" class="lang-popover">
+          <van-cell-group>
+            <van-cell v-for="lang in languages" :key="lang.code"
+              :class="['lang-item', { active: lang.code === currentLang.code }]" @click="handleChangeLanguage(lang)">
+              <template #icon>
+                <img :src="lang.flag" class="flag" :alt="lang.code">
+              </template>
+              <div class="lang-content">
+                <span class="lang-label">{{ lang.label }}</span>
+                <span class="lang-code">{{ lang.code.toUpperCase() }}</span>
+              </div>
+            </van-cell>
+          </van-cell-group>
+        </van-popover>
+      </div>
+    </template>
+  </van-nav-bar>
+  <van-nav-bar v-else :title="name">
+    <!-- 右侧语言切换 -->
+    <template #right>
+      <div class="nav-language">
+        <van-button round size="small" class="lang-trigger" @click="showPopover = true">
+          <div class="current-lang">
+            <img :src="currentLang.flag" class="current-flag" />
+            <span class="lang-code">{{ currentLang.code.toUpperCase() }}</span>
+          </div>
+        </van-button>
+
+        <van-popover v-model:show="showPopover" :offset="[0, 8]" placement="bottom-end" class="lang-popover">
+          <van-cell-group>
+            <van-cell v-for="lang in languages" :key="lang.code"
+              :class="['lang-item', { active: lang.code === currentLang.code }]" @click="handleChangeLanguage(lang)">
+              <template #icon>
+                <img :src="lang.flag" class="flag" :alt="lang.code">
+              </template>
+              <div class="lang-content">
+                <span class="lang-label">{{ lang.label }}</span>
+                <span class="lang-code">{{ lang.code.toUpperCase() }}</span>
+              </div>
+            </van-cell>
+          </van-cell-group>
+        </van-popover>
+      </div>
+    </template>
+  </van-nav-bar>
 </template>
 
 <script>
 import { ref } from 'vue'
 import { useRouter } from 'vue-router'
+import { useI18n } from 'vue-i18n';
+import { Locale } from 'vant';
+// 引入英文语言包
+import enUS from "vant/es/locale/lang/en-US";
+// 引入简体中文语言包
+import zhCN from "vant/es/locale/lang/zh-CN";
+import jaJP from "vant/es/locale/lang/ja-JP";
+// 引入俄语语言包
+import ruRU from "vant/es/locale/lang/ru-RU";
+// 引入法语语言包
+import frFR from "vant/es/locale/lang/fr-FR";
+// 引入西班牙语语言包
+import esES from "vant/es/locale/lang/es-ES";
+// 引入葡萄牙语语言包
+import ptBR from "vant/es/locale/lang/pt-BR";
 export default {
   props: {
     name: {
@@ -63,11 +126,46 @@ export default {
       ctx.emit('callback')
     }
 
+    const { locale } = useI18n();
+    // 可用语言列表
+    const languages = ref([
+      { code: 'zh', label: '简体中文', vant: zhCN, flag: 'https://flagcdn.com/cn.svg' },
+      { code: 'en', label: 'English', vant: enUS, flag: 'https://flagcdn.com/us.svg' },
+      { code: 'ja', label: '日本語', vant: jaJP, flag: 'https://flagcdn.com/jp.svg' },
+      { code: 'ru', label: 'Русский', vant: ruRU, flag: 'https://flagcdn.com/ru.svg' },
+      { code: 'fr', label: 'Français', vant: frFR, flag: 'https://flagcdn.com/fr.svg' },
+      { code: 'es', label: 'Español', vant: esES, flag: 'https://flagcdn.com/es.svg' },
+      { code: 'pt', label: 'Português', vant: ptBR, flag: 'https://flagcdn.com/pt.svg' },
+    ]);
+
+    // 当前语言
+    const currentLang = ref(languages.value.find(l => l.code === locale.value) || languages.value[0]);
+    const showPopover = ref(false);
+
+    // 切换语言
+    const handleChangeLanguage = async (lang) => {
+      currentLang.value = lang;
+      locale.value = lang.code;
+      // 1. 切换应用语言
+      locale.value = lang.code
+
+      // 2. 切换 Vant 语言
+      Locale.use(lang.code, lang.vant)
+      showPopover.value = false;
+
+      // 3. (可选) 持久化存储
+      localStorage.setItem('curLang', lang.code)
+    };
+
     const onClickLeft = () => history.back();
     return {
       goBack,
       isback,
       onClickLeft,
+      handleChangeLanguage,
+      showPopover,
+      languages,
+      currentLang
     }
   }
 }
@@ -105,4 +203,126 @@ export default {
 .moreIcon {
   visibility: hidden;
 }
+
+.current-lang {
+  display: flex;
+  align-items: center;
+  gap: 6px;
+  padding: 2px;
+}
+
+.current-flag {
+  width: 20px;
+  height: 15px;
+  border-radius: 2px;
+  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
+}
+
+.lang-code {
+  font-size: 14px;
+  font-weight: 500;
+  color: #333;
+  margin-top: 1px;
+}
+
+.nav-language {
+  margin-right: -8px;
+}
+
+.lang-trigger {
+  padding: 4px 8px;
+  background: rgba(255, 255, 255, 0.9);
+  border: 1px solid #eee;
+  transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
+  border: 1px solid #eee;
+  /* 边框颜色 */
+  color: #4d6add;
+  /* 文字颜色 */
+
+  &:hover {
+    border-color: #3a52b3;
+    color: #3a52b3;
+    background: rgba(77, 106, 221, 0.05);
+  }
+}
+
+
+/* 点击状态 */
+.lang-trigger:active {
+  border-color: #2e4096;
+  color: #2e4096;
+  background: rgba(77, 106, 221, 0.1);
+}
+
+.globe-icon {
+  font-size: 16px;
+  color: #666;
+  margin-right: 6px;
+}
+
+.lang-text {
+  font-size: 14px;
+  font-weight: 500;
+  color: #333;
+}
+
+.lang-popover {
+  --van-popover-arrow-size: 8px;
+}
+
+.lang-item {
+  padding: 10px 16px;
+
+  &.active {
+    background: #f5f8ff;
+
+    .lang-label {
+      color: var(--van-blue);
+    }
+  }
+}
+
+/* 调整后的样式 */
+.van-cell {
+  --cell-vertical-padding: 12px; /* 统一垂直间距 */
+  display: flex;
+  align-items: center; /* 主轴线居中 */
+}
+
+.flag {
+  width: 22px;
+  height: 16px;
+  border-radius: 2px;
+  margin-right: 12px;
+  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
+  vertical-align: middle; /* 行内元素垂直对齐 */
+  position: relative;
+  top: -1px; /* 微调视觉平衡 */
+}
+
+.lang-content {
+  display: flex;
+  align-items: center;
+  gap: 8px;
+}
+
+.lang-label {
+  line-height: 24px;
+  font-size: 14px;
+  color: #333;
+  gap: 8px;
+}
+
+.lang-code {
+  font-size: 12px;
+  color: #4d6add;
+  font-weight: 600;
+  /* 增加字重提升可读性 */
+  letter-spacing: 0.5px;
+}
+
+/* 国旗悬停动画 */
+.lang-trigger:hover .current-flag {
+  filter: brightness(0.9);
+}
 </style>

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

@@ -210,7 +210,7 @@ export default {
       adminTypeTitle.value = adminList.value.find(adminList => adminList.value === value).text;
       searchParams.adminType = (adminTypeTitle.value === t('typeSelectList.allSuboUsers')) ? 'all' : '';
       searchParams.userName = (adminTypeTitle.value === t('typeSelectList.allSuboUsers')) ? 'all' : (adminTypeTitle.value === t('typeSelectList.thisMerchant')) ? user.username : adminTypeTitle.value;
-      searchParams.adminId = (value ===  ('this' || 'all') ? null : value);
+      searchParams.adminId = (value === ('this' || 'all') ? null : value);
       searchParams.ifForeign = adminList.value.find(adminList => adminList.value === value).ifForeign;
       if (searchParams.ifForeign == "0") {
         payList.value = [

+ 7 - 0
src/router/index.js

@@ -646,6 +646,13 @@ const router = createRouter({
       component: () => import("@/views/terminal/check"),
       meta: { index: 1 },
     },
+    // 钱包
+    {
+      path: "/purse",
+      name: "purse",
+      component: () => import("@/views/purse/index"),
+      meta: { index: 1 },
+    },
   ],
 });
 // 路由守卫处理

+ 3 - 10
src/styles/device/index.less

@@ -5,22 +5,16 @@
 
   .listBox {
     width: 100%;
-    // height: calc(100vh - 100px);
-    // height: auto;
-    // overflow: auto;
-    // overflow-x: hidden;
 
     .deviceBox1 {
       .searchRow {
         padding: 0.5rem 0.5rem;
 
         .bd3 {
-          width: 2.1rem;
-          // height: 16px;
 
           .outer4 {
-            width: 0.4rem;
-            height: 0.4rem;
+            width: 0.45rem;
+            height: 0.45rem;
             background: url("../../assets/home/titleIcon.png") top center no-repeat;
             background-size: 100%;
           }
@@ -28,11 +22,10 @@
           .txt2 {
             overflow-wrap: break-word;
             color: rgba(64, 77, 116, 1);
-            font-size: 0.4rem;
+            font-size: 15px;
             font-family: PingFangSC-Semibold;
             text-align: left;
             white-space: nowrap;
-            line-height: 0.4rem;
             display: block;
           }
         }

+ 0 - 17
src/styles/login/index.less

@@ -1,8 +1,4 @@
 .login {
-    // display: flex;
-    // flex-wrap: wrap;
-    // flex-direction: row;
-    // align-content: flex-start;
 
     .loginLogoBox {
         width: 100%;
@@ -11,26 +7,13 @@
         position: relative;
 
         .loginLogo {
-            width: 5rem;
-            height: 2rem;
             position: absolute;
             top: 1.5rem;
             left: 50%;
             transform: translateX(-50%);
-            // background: url("../../assets/login/logo.png");
             background-size: 100%;
         }
 
-        .languageCon {
-            width: 2rem;
-            right: 0.5rem;
-            top: 0.3rem;
-            border: 1px solid #4d6add;
-            padding: 0.1rem 0.2rem;
-            border-radius: 10px;
-            color: #4d6add;
-
-        }
     }
 
     .loginTitleBox {

+ 78 - 22
src/utils/i18n.js

@@ -1,13 +1,24 @@
-import { createI18n } from 'vue-i18n';
-import { navigatorLanguage } from '../common/js/utils';
+import { createI18n } from "vue-i18n";
+import { navigatorLanguage } from "../common/js/utils";
+import { Locale } from "vant";
 // 引入英文语言包
-import enUS from 'vant/es/locale/lang/en-US';
+import enUS from "vant/es/locale/lang/en-US";
 // 引入简体中文语言包
-import zhCN from 'vant/es/locale/lang/zh-CN';
-import jaJP from 'vant/es/locale/lang/ja-JP';
+import zhCN from "vant/es/locale/lang/zh-CN";
+import jaJP from "vant/es/locale/lang/ja-JP";
+// 引入俄语语言包
+import ruRU from "vant/es/locale/lang/ru-RU";
+// 引入法语语言包
+import frFR from "vant/es/locale/lang/fr-FR";
+// 引入西班牙语语言包
+import esES from "vant/es/locale/lang/es-ES";
+// 引入葡萄牙语语言包
+import ptBR from "vant/es/locale/lang/pt-BR";
+
+const curLang = localStorage.getItem('curLang');
 let language = 'en';
 // 储存语言,方便中英切换
-const curLang = localStorage.getItem('curLang');
+
 if (curLang) {
     language = curLang;
     localStorage.setItem('curLang', curLang);
@@ -15,27 +26,72 @@ if (curLang) {
     language = navigatorLanguage();
     localStorage.setItem('curLang', navigatorLanguage());
 }
-// vant组件的中英文切换
-import { Locale } from 'vant';
+
+const i18n = createI18n({
+    //多语言实例
+    legacy: false,
+    globalInjection: true,
+    // 默认语言
+    locale: localStorage.getItem("curLang")
+      ? localStorage.getItem("curLang")
+      : "en",
+    // 关闭控制台警告
+    silentFallbackWarn: true,
+    messages: {
+      en: require("../assets/language/en.json"), //英文包
+      zh: require("../assets/language/zh.json"), //中文包
+      ja: require("../assets/language/ja.json"), //日文包
+      ru: require("../assets/language/ru.json"), //俄语包
+      fr: require("../assets/language/fr.json"), //法语包
+      es: require("../assets/language/es.json"), //西班牙语包
+      pt: require("../assets/language/pt.json"), //葡萄牙语包
+    },
+  });
+
 // 判断中英文,切换vant语言包
 if (language === 'en') {
     Locale.use('en-US', enUS);
 } else if (language === 'ja') {
     Locale.use('ja-JP', jaJP);
+} else if (language === 'ru') {
+    Locale.use('ru-RU', ruRU);
+} else if (language === 'fr') {
+    Locale.use('fr-FR', frFR);
+} else if (language === 'es') {
+    Locale.use('es-ES', esES);
+} else if (language === 'pt') {
+    Locale.use('pt-BR', ptBR);
 } else {
     Locale.use('zh-CN', zhCN);
 }
-export default createI18n({
-    //多语言实例
-    legacy: false,
-    globalInjection: true,
-    // 默认语言
-    locale: localStorage.getItem('curLang') ? localStorage.getItem('curLang') : 'en',
-    // 关闭控制台警告
-    silentFallbackWarn: true,
-    messages: {
-        'en': require('../assets/language/en.json'), //英文包
-        'zh': require('../assets/language/zh.json'), //中文包
-        'ja': require('../assets/language/ja.json'), //日文包
-    }
-});
+
+// 监听语言切换
+i18n.global.onBeforeLanguageSwitch = (lang) => {
+  // 同步更新 Vant 语言
+  switch (lang) {
+    case "en-US":
+      Locale.use("en-US", enUS);
+      break;
+    case "zh-CN":
+      Locale.use("zh-CN", zhCN);
+      break;
+    case "ja-JP":
+      Locale.use("ja-JP", jaJP);
+      break;
+    case "fr-FR":
+      Locale.use("fr-FR", frFR);
+      break;
+    case "ru-RU":
+      Locale.use("ru-RU", ruRU);
+      break;
+    case "es-ES":
+      Locale.use("es-ES", esES);
+      break;
+    case "pt-BR":
+      Locale.use("pt-BR", ptBR);
+      break;
+  }
+};
+
+export default i18n;
+

+ 234 - 0
src/views/bindBankCard/index copy.vue

@@ -0,0 +1,234 @@
+<template>
+  <!-- 提现账号 -->  <div class="shandeMchPage flex-col">
+    <s-header :name="$t('joinpayMch.settlementAccount')" :noback="false" :isBorder="false"></s-header>
+    <van-steps :active="currentSwipeItem">
+      <van-step v-for="(item, index) in stepItem" :key="index">
+        <template #active-icon>
+          <div class="steps-active-icon">
+            <span>
+              {{ item.value }}
+            </span>
+          </div>
+        </template>
+        <template #inactive-icon>
+          <div class="steps-inactive-icon">
+            <span>
+              {{ item.value }}
+            </span>
+          </div>
+        </template>
+        <template #finish-icon>
+          <div class="steps-finish-icon">
+            <van-icon name="success" size="10px" color="#ffffff" />
+          </div>
+        </template>
+        <span>{{ item.title }}</span>
+      </van-step>
+    </van-steps>
+    <div class="tabsContainer">
+      <div class="element"></div>
+      <van-tabs v-model:active="active" swipeable>
+        <van-tab title="个人">
+          <div class="cardAll">
+            <div style="padding: 10px 15px;">
+              <van-icon name="friends-o" size="15px" style="margin-right: 5px;" />
+              <span style="font-size: 15px; font-weight: 1000;">收款人证件(大陆)</span>
+            </div>
+            <div class="cardRow" style="margin-bottom: 0px;">
+              <div class="cardLi">
+                <van-uploader v-model="cardNegativeList" :max-size="2 * 1024 * 1024" :max-count="1"
+                  :after-read="afterRead" :preview-size="[300, 160]" :before-delete="deleteCertFront"
+                  @oversize="onOversize" upload-text="身份证人像面" />
+              </div>
+              <div class="cardLi">
+                <van-uploader v-model="cardPositiveList" :max-size="2 * 1024 * 1024" :max-count="1"
+                  :after-read="afterRead" :preview-size="[300, 160]" :before-delete="deleteCertBack"
+                  @oversize="onOversize" upload-text="身份证国徽面" />
+              </div>
+            </div>
+          </div>
+        </van-tab>
+        <van-tab title="企业商户">
+          <div class="cardAll">
+            <div style="padding: 10px 15px;">
+              <van-icon name="friends-o" size="15px" style="margin-right: 5px;" />
+              <span style="font-size: 15px; font-weight: 1000;">法人证件信息(大陆)</span>
+            </div>
+            <div class="cardRow" style="margin-bottom: 0px;">
+              <div class="cardLi">
+                <van-uploader v-model="cardNegativeList" :max-size="2 * 1024 * 1024" :max-count="1"
+                  :after-read="afterRead" :preview-size="[300, 160]" :before-delete="deleteCertFront"
+                  @oversize="onOversize" upload-text="身份证人像面" />
+              </div>
+              <div class="cardLi">
+                <van-uploader v-model="cardPositiveList" :max-size="2 * 1024 * 1024" :max-count="1"
+                  :after-read="afterRead" :preview-size="[300, 160]" :before-delete="deleteCertBack"
+                  @oversize="onOversize" upload-text="身份证国徽面" />
+              </div>
+            </div>
+            <div style="padding: 10px 15px;">
+              <van-icon name="friends-o" size="15px" style="margin-right: 5px;" />
+              <span style="font-size: 15px; font-weight: 1000;">营业执照信息</span>
+            </div>
+            <div class="cardRow" style="margin-bottom: 0px;">
+              <div class="cardLi">
+                <van-uploader v-model="cardNegativeList" :max-size="2 * 1024 * 1024" :max-count="1"
+                  :after-read="afterRead" :preview-size="[300, 160]" :before-delete="deleteCertFront"
+                  @oversize="onOversize" upload-text="营业执照" />
+              </div>
+            </div>
+          </div>
+        </van-tab>
+      </van-tabs>
+    </div>
+    <div class="fixed-bottom-btn">
+      <van-button type="primary" size="large" class="fixed-bottom-btn-content"
+        color="linear-gradient(to right, #7185d6, #4d6add)">下一步</van-button>
+    </div>
+  </div>
+</template>
+
+<script>
+import { onMounted, ref } from "vue";
+import sHeader from "../../components/SimpleHeader";
+
+export default {
+  components: { sHeader },
+  setup() {
+    const currentSwipeItem = ref(0);
+    const stepItem = ref([
+      {
+        title: "证件信息",
+        value: "1",
+      },
+      {
+        title: "结算卡信息",
+        value: "2",
+      },
+      {
+        title: "信息审核",
+        value: "3",
+      },
+      {
+        title: "签约",
+        value: "4",
+      },
+    ])
+    onMounted(async () => {
+    });
+
+    return {
+      currentSwipeItem,
+      stepItem
+    };
+  },
+};
+</script>
+
+<style lang="less" scoped>
+@import "../../common/style/common.less";
+
+.cardAll {
+
+  .cardRow {
+    width: 100%;
+
+    .cardLi {
+      text-align: center;
+      padding: 0.5em;
+    }
+
+  }
+}
+
+:deep(.van-tabs__content) {
+  max-height: calc(100vh - 230px); /* 根据实际高度调整 */
+  overflow-y: auto;
+  -webkit-overflow-scrolling: touch;
+}
+
+.van-steps {
+  background: transparent; // 如果背景是白色就不需要了,默认是白色的
+  padding: 0 30px 20px 30px;
+  background-color: #4d6add;
+
+  .steps-active-icon {
+    color: #ffffff;
+  }
+
+  :deep(.van-step__circle-container) {
+    background-color: #7185d6; // 如果背景是白色就不需要了,默认是白色的
+    width: 10px;
+    align-items: center;
+    text-align: center;
+    padding: 4px 8px;
+    border-radius: 50%;
+  }
+
+  :deep(.van-step__title--active) {
+    color: #ffffff;
+  }
+
+  :deep(.van-step--horizontal .van-step__line) {
+    height: 2px; // 自定义调整进度条的粗细
+    top: 28px; // 自定义调整进度条的位置
+    background-color: #7185d6;
+  }
+
+  :deep(.van-step--finish .van-step__line) {
+    background-color: #ffffff; //自定义激活时进度条的颜色
+  }
+
+  :deep(.van-step--finish .van-step__title) {
+    color: #ffffff; //自定义激活时进度条的颜色
+  }
+
+}
+
+.tabsContainer {
+  .element {
+    position: absolute;
+    top: 105px;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    height: 10px;
+    background-color: #ffffff;
+    /* 设置背景颜色 */
+    border-radius: 20px 20px 0 0;
+    /* 左上和右上角圆角 */
+    background-clip: content-box;
+    /* 只应用于内容区域,不包括圆角 */
+  }
+}
+
+
+:deep(.van-nav-bar) {
+  background-color: #4d6add;
+}
+
+:deep(.van-nav-bar__title) {
+  color: #ffffff !important;
+}
+
+:deep(.van-nav-bar .van-icon) {
+  color: #ffffff !important;
+}
+
+.fixed-bottom-btn {
+  position: fixed;
+  bottom: 0; /* 距离底部的距离,可以根据需要调整 */
+  left: 0;
+  width: 100%;
+  z-index: 100;
+  background-color: #ffffff;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+
+:deep(.van-button) {
+  border-radius: 15px;
+  margin: 20px 10px 10px 10px;
+}
+</style>

+ 182 - 154
src/views/bindBankCard/index.vue

@@ -1,201 +1,229 @@
 <template>
-  <!-- 提现账号 -->
-  <div class="shandeMchPage flex-col" style="background-color: #f5f5f5;">
-    <s-header :name="$t('joinpayMch.settlementAccount')" :noback="false" :isBorder="false"></s-header>
-    <van-steps :active="currentSwipeItem">
-      <van-step v-for="(item, index) in stepItem" :key="index">
-        <template #active-icon>
-          <div class="steps-active-icon">
-            <span>
-              {{ item.value }}
-            </span>
-          </div>
-        </template>
-        <template #inactive-icon>
-          <div class="steps-inactive-icon">
-            <span>
-              {{ item.value }}
-            </span>
-          </div>
-        </template>
-        <template #finish-icon>
-          <div class="steps-finish-icon">
-            <van-icon name="success" size="10px" color="#ffffff" />
-          </div>
-        </template>
-        <span>{{ item.title }}</span>
-      </van-step>
-    </van-steps>
-    <div class="tabsContainer">
-      <div class="element"></div>
-      <van-tabs v-model:active="active" swipeable>
-        <van-tab title="个人">
-          <div style="border-radius: 0 0 20px 20px; background-color: #ffffff; min-height: auto">
-            <div style="padding: 10px 15px;">
-              <van-icon name="friends-o" size="15px" style="margin-right: 5px;" />
-              <span style="font-size: 15px; font-weight: 1000;">收款人证件(大陆)</span>
+  <div class="bind-page">
+    <s-header title="绑定银行卡" :noback="false" :isBorder="false"></s-header>
+
+    <!-- 步骤条 -->
+    <div class="step-container">
+      <van-steps :active="currentStep" active-color="#4d6add">
+        <van-step>证件信息</van-step>
+        <van-step>结算卡信息</van-step>
+        <van-step>信息审核</van-step>
+        <van-step>签约</van-step>
+      </van-steps>
+    </div>
+
+    <!-- 证件信息 -->
+    <div v-show="currentStep === 0" class="card-section">
+      <van-tabs v-model:active="merchantType" title-active-color="#4d6add">
+        <!-- 个人商户 -->
+        <van-tab title="个人商户">
+          <div class="upload-card">
+            <h3 class="upload-title">收款人证件(大陆)</h3>
+            <div class="upload-group">
+              <van-uploader v-model="idCardFront" :max-count="1">
+                <template #default>
+                  <div class="upload-item">
+                    <van-icon name="photo" size="32" color="#4d6add" />
+                    <p>上传人像面</p>
+                  </div>
+                </template>
+              </van-uploader>
+              <van-uploader v-model="idCardBack" :max-count="1">
+                <template #default>
+                  <div class="upload-item">
+                    <van-icon name="photo" size="32" color="#4d6add" />
+                    <p>上传国徽面</p>
+                  </div>
+                </template>
+              </van-uploader>
             </div>
-            <div class="cardRow" style="margin-bottom: 0px;">
-              <div class="cardLi">
-                <van-uploader v-model="cardNegativeList" :max-size="2 * 1024 * 1024" :max-count="1"
-                  :after-read="afterRead" :preview-size="[300, 160]" :before-delete="deleteCertFront"
-                  @oversize="onOversize" upload-text="身份证人像面" />
-              </div>
-              <div class="cardLi">
-                <van-uploader v-model="cardPositiveList" :max-size="2 * 1024 * 1024" :max-count="1"
-                  :after-read="afterRead" :preview-size="[300, 160]" :before-delete="deleteCertBack"
-                  @oversize="onOversize" upload-text="身份证国徽面" />
-              </div>
+          </div>
+        </van-tab>
+
+        <!-- 企业商户 -->
+        <van-tab title="企业商户">
+          <div class="upload-card">
+            <h3 class="upload-title">法人证件信息(大陆)</h3>
+            <div class="upload-group">
+              <van-uploader v-model="idCardFront" :max-count="1">
+                <template #default>
+                  <div class="upload-item">
+                    <van-icon name="photo" size="32" color="#4d6add" />
+                    <p>上传人像面</p>
+                  </div>
+                </template>
+              </van-uploader>
+              <van-uploader v-model="idCardBack" :max-count="1">
+                <template #default>
+                  <div class="upload-item">
+                    <van-icon name="photo" size="32" color="#4d6add" />
+                    <p>上传国徽面</p>
+                  </div>
+                </template>
+              </van-uploader>
             </div>
+
+            <h3 class="upload-title" style="margin-top: 20px;">营业执照</h3>
+            <van-uploader v-model="businessLicense" :max-count="1" >
+              <template #default>
+                <div class="upload-item single">
+                  <van-icon name="description" size="32" color="#4d6add" />
+                  <p>上传营业执照</p>
+                </div>
+              </template>
+            </van-uploader>
           </div>
         </van-tab>
-        <van-tab title="企业商户">结算卡信息</van-tab>
       </van-tabs>
     </div>
-    <div class="fixed-bottom-btn">
-      <van-button type="primary" size="large" class="fixed-bottom-btn-content" color="linear-gradient(to right, #7185d6, #4d6add)" >下一步</van-button>
+
+    <!-- 其他步骤内容 -->
+
+    <!-- 操作按钮 -->
+    <div class="action-buttons">
+      <van-button v-if="currentStep > 0" round class="prev-btn" @click="currentStep--">
+        上一步
+      </van-button>
+      <van-button round type="primary" class="next-btn" @click="handleNextStep">
+        {{ currentStep === 3 ? '完成' : '下一步' }}
+      </van-button>
     </div>
-    <!-- 
-    <div style="height: 10px;">
-    </div> -->
   </div>
 </template>
 
 <script>
-import { onMounted, ref } from "vue";
 import sHeader from "../../components/SimpleHeader";
+import { ref } from 'vue';
 
 export default {
   components: { sHeader },
   setup() {
-    const currentSwipeItem = ref(0);
-    const stepItem = ref([
-      {
-        title: "证件信息",
-        value: "1",
-      },
-      {
-        title: "结算卡信息",
-        value: "2",
-      },
-      {
-        title: "信息审核",
-        value: "3",
-      },
-      {
-        title: "签约",
-        value: "4",
-      },
-    ])
-    onMounted(async () => {
-    });
+    const currentStep = ref(0);
+    const merchantType = ref(0);
+    const idCardFront = ref([]);
+    const idCardBack = ref([]);
+    const businessLicense = ref([]);
+
+    const handleNextStep = () => {
+      if (currentStep.value < 3) currentStep.value++;
+    };
+
+    const handlePrevStep = () => {
+      if (currentStep.value > 0) currentStep.value--;
+    };
 
     return {
-      currentSwipeItem,
-      stepItem
+      // 响应式数据
+      currentStep,
+      merchantType,
+      idCardFront,
+      idCardBack,
+      businessLicense,
+
+      // 方法
+      handleNextStep,
+      handlePrevStep
     };
-  },
+  }
 };
 </script>
 
 <style lang="less" scoped>
-@import "../../common/style/common.less";
-
-.cardRow {
-  width: 100%;
-  // display: flex;
-
-  .cardLi {
-    // width: 50%;
-    text-align: center;
-    padding: 0.5em;
-  }
+.bind-page {
+  background: #f8f9ff;
+  min-height: 100vh;
+}
 
+.step-container {
+  background: white;
+  padding: 15px;
+  margin: 10px;
+  border-radius: 12px;
+  box-shadow: 0 2px 8px rgba(77, 106, 221, 0.05);
 }
 
-.van-steps {
-  background: transparent; // 如果背景是白色就不需要了,默认是白色的
-  padding: 0 30px 20px 30px;
-  // margin: 80px auto;
-  // overflow: visible; //如果不需要文字,或者不需要调整位置,可以不设置
-  background-color: #4d6add;
+.card-section {
+  margin: 10px;
+}
 
-  .steps-active-icon {
-    color: #ffffff;
-  }
+.upload-card {
+  background: white;
+  border-radius: 0 0 12px 12px;
+  padding: 20px;
+  box-shadow: 0 4px 12px rgba(77, 106, 221, 0.08);
 
-  :deep(.van-step__circle-container) {
-    background-color: #7185d6; // 如果背景是白色就不需要了,默认是白色的
-    width: 10px;
-    align-items: center;
-    text-align: center;
-    padding: 4px 8px;
-    border-radius: 50%;
+  .upload-title {
+    color: #4d6add;
+    font-size: 16px;
+    margin-bottom: 15px;
   }
+}
 
-  :deep(.van-step__title--active) {
-    color: #ffffff;
-  }
+.upload-group {
+  display: grid;
+  grid-template-columns: 1.2fr 1fr;
+  gap: 10px;
+  margin-bottom: 20px;
+}
 
-  :deep(.van-step--horizontal .van-step__line) {
-    height: 2px; // 自定义调整进度条的粗细
-    top: 28px; // 自定义调整进度条的位置
-    background-color: #7185d6;
-  }
+.upload-item {
+  border: 2px dashed #e0e3ff;
+  border-radius: 12px;
+  padding: 20px;
+  text-align: center;
+  transition: all 0.3s;
+  width: 100%;
 
-  :deep(.van-step--finish .van-step__line) {
-    background-color: #ffffff; //自定义激活时进度条的颜色
+  p {
+    color: #666;
+    margin-top: 8px;
+    font-size: 12px;
   }
 
-  :deep(.van-step--finish .van-step__title) {
-    color: #ffffff; //自定义激活时进度条的颜色
+  &.single {
+    grid-column: span 2;
   }
 
-}
-
-.tabsContainer {
-  .element {
-    position: absolute;
-    top: 105px;
-    left: 0;
-    right: 0;
-    bottom: 0;
-    height: 10px;
-    background-color: #ffffff;
-    /* 设置背景颜色 */
-    border-radius: 20px 20px 0 0;
-    /* 左上和右上角圆角 */
-    background-clip: content-box;
-    /* 只应用于内容区域,不包括圆角 */
+  &:active {
+    border-color: #4d6add;
+    background: rgba(77, 106, 221, 0.05);
   }
 }
 
 
-:deep(.van-nav-bar) {
-  background-color: #4d6add;
-}
-
-:deep(.van-nav-bar__title) {
-  color: #ffffff !important;
-}
-
-:deep(.van-nav-bar .van-icon ) {
-  color: #ffffff !important;
-}
-
-.fixed-bottom-btn {
+.action-buttons {
   position: fixed;
-  bottom: 0; /* 距离底部的距离,可以根据需要调整 */
+  bottom: 0;
   left: 0;
   width: 100%;
-  z-index: 100;
-  background-color: #ffffff;
+  background: white;
   display: flex;
-  justify-content: center;
-  align-items: center;
+  gap: 10px;
+  box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.05);
+
+
+  .prev-btn {
+    flex: 2;
+    border-color: #4d6add;
+    color: #4d6add;
+    margin: 15px;
+  }
+
+  .next-btn {
+    flex: 2;
+    background: #4d6add;
+    margin: 15px;
+  }
 }
-:deep(.van-button) {
-  border-radius: 15px;
-  margin: 10px;
+
+/* 适配移动端 */
+@media (max-width: 480px) {
+  .upload-item {
+    padding: 15px;
+  }
+
+  .upload-group {
+    gap: 8px;
+  }
 }
-</style>
+</style>

+ 1 - 1
src/views/commonTools/index.vue

@@ -9,7 +9,7 @@
                     <img class="mod7 flex-col" :src="showLogo(item.value)" />
                     <div class="TextGroup14 flex-col">
                         <!-- <span class="info15" v-html="item.label"></span> -->
-                        <span class="info15">{{ $t(item.label) }}</span>
+                        <span class="info15">{{ $t("permission."+ item.value) }}</span>
                     </div>
                 </div>
             </div>

+ 146 - 74
src/views/device/doSugar.vue

@@ -48,30 +48,42 @@
         </div>
         <div v-if="!doSugartData" class="block5 flex-col" @click="submitDoSugar"><span class="txt3">{{
       $t('device.submitToMakeSugar') }}</span></div>
-        <van-button v-if="doSugartData" round type="primary" class="volumeChangeButton" :disabled="doSugartType"
-          @click="checkData()">{{ $t('device.viewResults') }}</van-button>
+        <van-button v-if="doSugartData" style="padding: 1em;" round type="primary" class="block5 flex-col"
+          :disabled="doSugartType" @click="checkData()">{{ $t('device.viewResults') }}</van-button>
       </div>
       <div v-if="machineType === '2'">
-        <van-field v-model="fieldValue" is-link readonly :label="$t('device.clickToSelectTaste')"
-          :placeholder="$t('device.pleaseSelectTaste')" @click="show = true" />
-        <van-popup v-model:show="show" round position="bottom">
-          <van-cascader v-model="cascaderValue" :title="$t('device.pleaseSelectTaste')" :options="options"
-            @close="show = false" @finish="onFinish">
-            <template #option="{ option }">
-              <div class="cascader-item">
-                <van-image :src="option.imgUrl" width="55px" height="55px"></van-image>
-                <div class="cascader-label">{{ option.value }}</div>
-              </div>
-            </template>
-          </van-cascader>
-        </van-popup> -->
+        <van-collapse v-model="activeNames">
+          <van-collapse-item :title="$t('device.jam')" name="1" size="large" title-style="color: #404d74;">
+            <van-row class="goods">
+              <van-col v-for="(item, index) in jamData" :key="index" class="goodsCon o-mlr-5 o-mb-20" span="11">
+                <div class="l-flex-RC">
+                  <van-image width="50" height="50" fit="contain" :src="showPopPhoto(item)" />
+                  <span class="o-ml-10" style="color: #000;word-wrap: break-word; width: 50px;">{{ item.name }}</span>
+                  <van-checkbox class="o-ml-10" shape="square" v-model="item.checked" />
+                </div>
+              </van-col>
+            </van-row>
+          </van-collapse-item>
+          <van-collapse-item :title="$t('device.nuts​')" name="2" size="large" title-style="color: #404d74;">
+            <van-row class="goods">
+              <van-col v-for="(item, index) in crushData" :key="index" class="goodsCon o-mlr-5 o-mb-20" span="11">
+                <div class="l-flex-RC">
+                  <van-image width="50" height="50" fit="contain" :src="showPopPhoto(item)" />
+                  <span class="o-ml-10" style="color: #000;word-wrap: break-word; width: 50px;">{{ item.name }}</span>
+                  <van-checkbox class="o-ml-10" shape="square" v-model="item.checked" />
+                </div>
+              </van-col>
+            </van-row>
+          </van-collapse-item>
+        </van-collapse>
+        <br>
         <div class="textRow o-pr-20">
           <span @click="pushToDaySugarList">{{ $t('device.todaysMakeList') }}>></span>
         </div>
         <div v-if="!doSugartData" class="block5 flex-col" @click="submitDoSugar"><span class="txt3">{{
       $t('device.submitToMakeSugar') }}</span></div>
-        <van-button v-if="doSugartData" round type="primary" class="volumeChangeButton" :disabled="doSugartType"
-          @click="checkData()">{{ $t('device.viewResults') }}</van-button>
+        <van-button v-if="doSugartData" style="padding: 1em;" round type="primary" class="block5 flex-col"
+          :disabled="doSugartType" @click="checkData()">{{ $t('device.viewResults') }}</van-button>
       </div>
     </div>
   </div>
@@ -80,8 +92,12 @@
 import { onMounted, ref } from 'vue';
 import sHeader from "@/components/SimpleHeader";
 import { useRoute, useRouter } from 'vue-router';
-import { getDeviceDetal, selectProducts, doSugar, selectSugarStatus } from '@/service/device'
-import { showFailToast, showSuccessToast, showToast } from 'vant';
+import {
+  getDeviceDetal, selectProducts,
+  doSugar,
+  selectSugarStatus
+} from '@/service/device'
+import { showConfirmDialog, showFailToast, showSuccessToast, showToast } from 'vant';
 import { useI18n } from 'vue-i18n';
 import { styleUrl } from "../../common/js/utils";
 
@@ -97,6 +113,21 @@ export default {
     const fieldValue = ref('');
     const cascaderValue = ref('');
     const options = ref([]);
+    const activeNames = ref(['1', '2']);
+
+    // 果酱数据
+    const iceName = ref();
+    const jamData = ref([]);
+    const crushData = ref([]);
+
+    // 商品图片
+    const showPopPhoto = (row) => {
+      let imgId = row.no;
+      if (imgId) {
+        return require(`../../assets/order/spunSugar/goods/${imgId}.png`);
+      }
+      return imgId;
+    };
     const onFinish = ({ selectedOptions }) => {
       console.log('onFinish', selectedOptions);
       show.value = false;
@@ -136,70 +167,107 @@ export default {
             };
           })
         } else {
-          // data.data.map(item => {
-          //   console.log("编号", item.no);
-          //   if (item.no == 'I01') {
-          //     return {
-          //       text: item.productName,
-          //       value: item.productName,
-          //       imgUrl: showSugarPhoto(item.no),
-          //     };
-          //   }
-          // })
-          data.data.forEach(item => {
-            if (item.no == 'I01') {
-              options.value.push(
-                {
-                  text: item.productName,
-                  value: item.productName,
-                  imgUrl: showSugarPhoto(item.no),
-                  children: []
-                }
-              )
-            }
-          })
-
-          data.data.forEach(item => {
-            if (item.no.includes('J')) {
-              options.value[0].children.push(
-                {
-                  text: item.productName,
-                  value: item.productName,
-                  imgUrl: showSugarPhoto(item.no),
-                  children: [],
-                }
-              )
-            }
-          })
-
           data.data.forEach(item => {
-            if (item.no.includes('C')) {
-              options.value[0].children.forEach(item1 => {
-                item1.children.push(
-                  {
-                    text: item.productName,
-                    value: item.productName,
-                    imgUrl: showSugarPhoto(item.no),
-                  }
-                )
-              })
+            if (item.no.includes('J01')) {
+              // 果酱1
+              jamData.value.push({
+                name: item.productName,
+                no: item.no,
+                value: 1,
+                checked: false
+              });
+            } else if (item.no.includes('J02')) {
+              // 果酱2
+              jamData.value.push({
+                name: item.productName,
+                no: item.no,
+                value: 2,
+                checked: false
+              });
+            } else if (item.no.includes('J03')) {
+              // 果酱3
+              jamData.value.push({
+                name: item.productName,
+                no: item.no,
+                value: 3,
+                checked: false
+              });
+            } else if (item.no.includes('C01')) {
+              // 果碎1
+              crushData.value.push({
+                name: item.productName,
+                no: item.no,
+                value: 1,
+                checked: false
+              });
+            } else if (item.no.includes('C02')) {
+              // 果碎2
+              crushData.value.push({
+                name: item.productName,
+                no: item.no,
+                value: 2,
+                checked: false
+              });
+            } else if (item.no.includes('I01')) {
+              // 雪糕
+              iceName.value = item.productName;
             }
           })
         }
       } else { showFailToast(data.message); }
-      // console.log(options.value);
     }
     const submitDoSugar = async () => {
+      const makeCodes = ref([1, 0, 0]);
       doSugartData.value = null;
       doSugartType.value = true;
+
+      if (machineType == '2') {
+        fieldValue.value = '';
+        let jamCount = 0;
+        let crushCount = 0;
+        // 如果是冰淇淋机器
+        jamData.value.forEach(item => {
+          if (item.checked) {
+            fieldValue.value += item.name + ',';
+            makeCodes.value[1] += item.value;
+            jamCount++;
+          }
+        });
+        crushData.value.forEach(item => {
+          if (item.checked) {
+            fieldValue.value += item.name + ',';
+            makeCodes.value[2] += item.value;
+            crushCount++;
+          }
+        });
+        if (jamCount > 1) {
+          makeCodes.value[1] += 1;
+        }
+        if (crushCount > 1) {
+          makeCodes.value[2] += 1;
+        }
+        if (fieldValue.value === '') {
+          fieldValue.value = iceName.value;
+        } else {
+          fieldValue.value = fieldValue.value.substring(0, fieldValue.value.length - 1);
+          fieldValue.value = iceName.value + "(" + fieldValue.value + ")";
+        }
+      }
       if (fieldValue.value === '') { showFailToast(t('device.pleaseSelectAPattern')); return; }
-      const { data } = await doSugar({ equipmentId: deviceId, productName: fieldValue.value });
-      if (data.code) {
-        doSugartData.value = data.data;
-        setTimeout(() => {
-          doSugartType.value = false;
-        }, 5000);
-      } else { showFailToast(data.message); }
+      showConfirmDialog({
+        title: t('user.tips'),
+        message: t('device.confirmMake')+ fieldValue.value +'?',
+      }).then(async() => {
+        const { data } = await doSugar({ equipmentId: deviceId, productName: fieldValue.value, makeCodes: makeCodes.value });
+        if (data.code) {
+          doSugartData.value = data.data;
+          setTimeout(() => {
+            doSugartType.value = false;
+          }, 5000);
+        } else { showFailToast(data.message); }
+      }).catch((error) => {
+        console.error(error);
+      })
     }
     const checkData = async () => {
       const { data } = await selectSugarStatus({ no: doSugartData.value.no });
@@ -241,7 +309,11 @@ export default {
       checkData,
       pushToDaySugarList,
       showSugarPhoto,
-      machineType
+      machineType,
+      activeNames,
+      jamData,
+      crushData,
+      showPopPhoto
     };
   },
   components: { sHeader },

+ 6 - 73
src/views/home/index.vue

@@ -2,7 +2,7 @@
   <!-- 主页 -->
   <div class="homePage flex-col">
     <div class="homeBox">
-      <s-header :name="sys ? sys.title : sysTitle" :noback="true" :isFixed="false"></s-header>
+      <s-header :name="sys ? sys.title : (sysTitle == 'AETI GLOBAL' ? sysTitle : $t('public.sysName'))" :noback="true" :isFixed="false"></s-header>
       <!-- 留言滚动条 -->
       <template v-if="noticeContent.title">
         <van-notice-bar @click="noticeClk" mode="link" :scrollable="true" color="rgba(64,77,116,1)" background="#fff"
@@ -20,22 +20,12 @@
       </div>
       <!-- 没有数据概览M14权限的人看不到数据概览和ECharts -->
       <!-- 数据概览 -->
-      <!-- <div v-if="showDataDiv" class="titleBox flex-col">
-        <div class="layer2 flex-row justify-between">
-          <div class="section5 flex-col"></div>
-          <div class="TextGroup2 flex-col">
-            <span class="txt4">{{ $t("home.dataOverview") }}</span>
-          </div>
-        </div>
-      </div> -->
       <!-- 时间选择 -->
       <dateSelectList v-if="showDataDiv" @update="update($event)"></dateSelectList>
-      <!-- <typeSelectList v-if="showDataDiv" :isHome="true" @upselectdata="upselectdata($event)"></typeSelectList> -->
       <typeDownMenu v-if="showDataDiv" :isHome="true" @upselectdata="upselectdata($event)"></typeDownMenu>
       <!-- 订单数据 -->
       <div v-if="showDataDiv" class="o-plr-8 o-pt-10">
         <div class="salesData flex-col" @click="pushOrderCenter">
-          <!-- <div class="block5 flex-col"> -->
           <div class="topTitle flex-row justify-end" v-if="isOrderData">
             <span class="txt10">{{ $t("home.orderData") }}</span>
             <div class="layer4 flex-col"></div>
@@ -44,7 +34,6 @@
             <div class="dataGroup flex-col">
               <div class="dataGroupBox l-flex-RC justify-center">
                 <!-- 首页 - 订单数据 - 收入总额¥ -->
-                <!-- <span class="word8">&yen;</span> -->
                 <span class="currencySymbol o-pr-2">{{ currencySymbol }}</span>
                 <span class="dataNum">{{ salesVolume.toFixed(2) }}</span>
               </div>
@@ -64,25 +53,15 @@
             </div>
           </div>
         </div>
-        <!-- </div> -->
       </div>
       <!-- 时间 -->
       <div v-if="showDataDiv" class="c-text-c" style="font-size: 18px; margin-top: 5px;">
         {{ Format_time(dateSelect.startDate, 'YYYY/MM/DD') }}-{{ Format_time(dateSelect.endDate, 'YYYY/MM/DD') }}
       </div>
-      <!-- ECharts
-      <template v-if="showDataDiv && !noData(salesVolume, salesNumber)">
-        <div ref="chartBox" class="Chart1 flex-col"></div>
-      </template>
-      <template v-else>
-        <kNoData v-if="showDataDiv"></kNoData>
-      </template> -->
-      <!-- <div> -->
       <div v-if="showDataDiv && !noData(salesVolume, salesNumber)">
         <div ref="chartBox" class="Chart1 flex-col"></div>
       </div>
       <kNoData v-else></kNoData>
-      <!-- </div> -->
       <!-- 常用工具 -->
       <div v-if="user.type === 0 || user.type === 4">
         <div class="outer9 flex-col justify-center">
@@ -102,8 +81,7 @@
             @click="pushToolPage(item.value)">
             <img class="mod7 flex-col" :src="showLogo(item.value)" />
             <div class="TextGroup14 flex-col">
-              <!-- <span class="info15" v-html="item.label"></span> -->
-              <span class="info15">{{ $t(item.label) }}</span>
+              <span class="info15">{{ $t("permission."+ item.value) }}</span>
             </div>
           </div>
         </div>
@@ -131,16 +109,7 @@
                 <!-- 设备名称 -->
                 <div class="contentWord kBordBott">{{ item.machineName }}
                 </div>
-                <!-- <van-row class="layer5" justify="space-between">
-            <van-col span="12">总销售额: {{ item.totalSales }}</van-col>
-            <van-col span="12">总现金: {{ item.totalCash }}</van-col>
-          </van-row> -->
                 <van-row class="layer5" justify="space-between">
-                  <!-- 硬币 -->
-                  <!-- <van-col span="8">{{ $t("home.coins") }}: {{ item.coins }}</van-col> -->
-                  <!-- 纸币 -->
-                  <!-- <van-col span="8">{{ $t("home.bills") }}: {{ item.bills }}</van-col> -->
-                  <!-- 硬币+纸币 -->
                   <van-col span="12">{{ $t("home.coinsBills") }}: {{ item.coinsBills !== undefined ? item.coinsBills :
         '0'
                     }}</van-col>
@@ -148,9 +117,6 @@
                   <van-col span="12">{{ $t("home.creditCard") }}: {{ item.creditCard !== undefined ? item.creditCard :
         '0'
                     }}</van-col>
-                  <!-- 电子支付 -->
-                  <!-- <van-col span="8">{{ $t("home.electronicPayment") }}: {{ item.electronicPayment }}</van-col> -->
-                  <!-- 所有支付方式合计 -->
                   <van-col span="12">{{ $t("home.allPayTypeTotal") }}: {{ calculateTotal(item) }}</van-col>
                 </van-row>
               </van-cell-group>
@@ -175,7 +141,7 @@
         </div>
       </div>
     </van-dialog>
-    <template v-if="isShowRobot">
+    <!-- <template v-if="isShowRobot">
       <van-floating-bubble v-model:offset="offset" axis="xy" :icon="robotIcon" magnetic="x"
         @offset-change="onOffsetChange" @click="onClickBot">
       </van-floating-bubble>
@@ -183,7 +149,7 @@
         <iframe :src="aiUrl" sandbox="allow-same-origin allow-scripts allow-popups allow-forms"
           style="width: 100%; height: 100%;"></iframe>
       </van-popup>
-    </template>
+    </template> -->
 
   </div>
 </template>
@@ -582,11 +548,7 @@ export default {
 
     const getTitleFunc = async () => {
       const currentDomain = window.location.href;
-      // const currentDomain = window.location.hostname;
       switch (true) {
-        // case currentDomain.includes('/shenze/'):
-        //   sysTitle.value = 'AETI GLOBAL';
-        //   break;
         case currentDomain.includes('/aeti/'):
           sysTitle.value = 'AETI GLOBAL';
           break;
@@ -655,12 +617,6 @@ export default {
         return item === "M4";
       })
 
-
-      // 查询是否有订单导出权限
-      // const isOrderExport = user.menuCodeList.some((item) => {
-      //   return item === "M9";
-      // })
-
       // 查询是否有数据概览权限
       const isDataOverview = user.menuCodeList.some((item) => {
         return item === "M14";
@@ -680,11 +636,11 @@ export default {
       if (user.type === 0) {
         pushToolList.value.push(
           {
-            label: t("role.mqtt"),
+            label: t("permission.M21"),
             value: "M21"
           },
           {
-            label: "终端管理",
+            label: t("permission.M22"),
             value: "M22"
           }
         );
@@ -790,15 +746,6 @@ export default {
     const offset = ref({ x: Math.floor(window.innerWidth * 0.8), y: Math.floor(window.innerHeight * 0.75) });
 
     const popupVisible = ref(false);
-    // const token = getLocal("token");
-    // const openid = "f45sdFu2eXPtjeyzhUmcJ9wZiOSfPr";
-    // const avatar = "用户头像";
-
-    // 构建带有动态 token 和 openid 的 AI URL
-    // const aiUrl = `https://chatbot.weixin.qq.com/webapp/auth/${token.value}?openid=${userName.value}&nickname=${userName.value}&avatar=${userName.value}&robotName=${"显示在页面顶部的title信息"}`;
-
-    // const aiUrl = "https://chatbot.weixin.qq.com/webapp/f45sdFu2eXPtjeyzhUmcJ9wZiOSfPr?robotName=Ritchie"; // 微信对话-test
-    // const aiUrl = "https://chatbot.aliyuncs.com/intl/index.htm?locale=zh-CN&from=0x0R41zuRE"; // 阿里云智能对话机器人
     const aiUrl = "https://chatbot.weixin.qq.com/webapp/c3thmydLGYWDugrgtfAj5I0Ng3sniv?robotName=Cotton%20Candy%20Robot"; // 阿里云智能对话机器人-ccbot
 
     // AI小助手
@@ -813,12 +760,6 @@ export default {
     const onClose = () => {
       popupVisible.value = false;
     }
-    // const onClickOverlay = () => {
-    //   popupVisible.value = false;
-    // };
-    // const onClickCloseIcon = () => {
-    //   popupVisible.value = false;
-    // };
 
     return {
       user,
@@ -853,8 +794,6 @@ export default {
       robotIcon: RobotIcon,
       aiUrl,
       popupVisible,
-      // onClickOverlay,
-      // onClickCloseIcon,
       onClose,
       onClickBot,
       offset,
@@ -862,12 +801,6 @@ export default {
       sysTitle,
       finished,
       loading,
-      // machineName,
-      // coins,
-      // bills,
-      // coinsBills,
-      // creditCard,
-      // electronicPayment,
       combinedList,
       isOrderData,
       calculateTotal

+ 5 - 101
src/views/login.vue

@@ -2,24 +2,11 @@
   <!-- 登录 -->
   <div class="login">
     <!-- <s-header :name="sys ? sys.title : $t('public.sysName')" :noback="true"></s-header> -->
-    <s-header :name="sys ? sys.title : sysTitle" :noback="true"></s-header>
-    <div class="loginLogoBox l-re">
+    <s-header :name="sys ? sys.title : (sysTitle == 'AETI GLOBAL' ? sysTitle : $t('public.sysName'))" :noback="true"></s-header>
+    <div class="loginLogoBox">
       <div class="loginLogo">
         <img :src="logoName" alt="Logo">
       </div>
-      <div class="l-ab pointer languageCon">
-        <!-- <div class="c-text-b">
-          {{ compLang }}
-        </div> -->
-        <van-popover :offset="[0, 8]" theme="dark" v-model:show="showPopover" :actions="actions" @select="onSelect">
-          <template #reference>
-            <van-button style="height: auto; color: #4d6add;" type="primary">{{ currentLan }}</van-button>
-          </template>
-        </van-popover>
-      </div>
-    </div>
-    <div class="loginTitleBox l-flex-center">
-      <span class="loginTitle">{{ $t("login.title") }}</span>
     </div>
     <div class="loginFormBox">
       <van-form @submit="onSubmit">
@@ -66,44 +53,13 @@ import { setLocal, getLocal, navigatorLanguage, styleUrl } from "../common/js/ut
 import sHeader from "../components/SimpleHeader";
 import { useRoute, useRouter } from "vue-router";
 import { useI18n } from "vue-i18n";
-// vant 组件的中英文切换
-import { Locale } from "vant";
-// 引入英文语言包
-import enUS from "vant/es/locale/lang/en-US";
-// 引入简体中文语言包
-import zhCN from "vant/es/locale/lang/zh-CN";
-// 引入日文语言包
-import jaJP from 'vant/es/locale/lang/ja-JP';
 import defaultLogo from '../assets/login/logo.png';
 import aetiLogo from '../assets/login/aetiLogo.png';
 
 export default {
   setup() {
     let languageName = ref(getLocal("curLang"));
-    const { locale, t } = useI18n();
-    // 语言点击
-    // const languageClk = () => {
-    //   if (languageName.value === "zh") {
-    //     locale.value = "en";
-    //     languageName.value = "en";
-    //     setLocal("curLang", "en");
-    //     // 切换vant语言包
-    //     Locale.use("en-US", enUS);
-    //   } else {
-    //     locale.value = "zh";
-    //     languageName.value = "zh";
-    //     setLocal("curLang", "zh");
-    //     // 切换vant语言包
-    //     Locale.use("zh-CN", zhCN);
-    //   }
-    // };
-    // const compLang = computed(() => {
-    //   if (languageName.value === "en") {
-    //     return "中文";
-    //   } else {
-    //     return "English";
-    //   }
-    // });
+    const { t } = useI18n();
     const checked = ref(false); // 是否记住密码状态
     const userName = ref("");
     const userPwd = ref("");
@@ -118,14 +74,12 @@ export default {
     onMounted(() => {
       // 加载样式
       styleUrl('login');
-      // localStorage.clear();
       // 如果没有语言缓存
       if (!getLocal("curLang")) {
         //  根据浏览器语言重新缓存到localstorage
         setLocal("curLang", navigatorLanguage());
         languageName.value = getLocal("curLang");
       }
-      // console.log("route.query.relation_admin_id >>>", route.query.relation_admin_id);
       if (route.query.relation_admin_id) {
         getSysFun();
       }
@@ -136,26 +90,14 @@ export default {
         userName.value = savedUsername;
         userPwd.value = savedPassword;
       }
-      if (languageName.value === "zh") {
-        currentLan.value = "中文";
-      } else if (languageName.value === "ja") {
-        currentLan.value = "日本語";
-      } else {
-        currentLan.value = "English";
-      }
       getDomainFunc();
     });
 
     const getDomainFunc = async () => {
       const currentDomain = window.location.href;
-      console.log("href >>>", currentDomain);
-      console.log("hostname >>>", window.location.hostname);
+      // console.log("href >>>", currentDomain);
+      // console.log("hostname >>>", window.location.hostname);
       switch (true) {
-        // case currentDomain.includes('/shenze/'):
-        //   logoName.value = aetiLogo;
-        //   sysTitle.value = 'AETI GLOBAL';
-
-        //   break;
         case currentDomain.includes('/aeti/'): // aeti是美国孙总portalmcc.com.cn
           logoName.value = aetiLogo;
           sysTitle.value = 'AETI GLOBAL';
@@ -178,38 +120,6 @@ export default {
       }
     };
 
-    const showPopover = ref(false);
-
-    // 通过 actions 属性来定义菜单选项
-    const actions = [
-      { text: '中文' },
-      { text: 'English' },
-      { text: '日本語' },
-    ];
-    // 切换语言
-    const onSelect = (action) => {
-      // showToast(action.text);
-      currentLan.value = action.text;
-      if (action.text === "中文") {
-        locale.value = "zh";
-        languageName.value = "zh";
-        setLocal("curLang", "zh");
-        // 切换vant语言包
-        Locale.use("zh-CN", zhCN);
-      } else if (action.text === "English") {
-        locale.value = "en";
-        languageName.value = "en";
-        setLocal("curLang", "en");
-        // 切换vant语言包
-        Locale.use("en-US", enUS);
-      } else if (action.text === "日本語") {
-        locale.value = "ja";
-        languageName.value = "ja";
-        setLocal("curLang", "ja");
-        // 切换vant语言包
-        Locale.use("ja-JP", jaJP);
-      }
-    }
     // 登录
     const onSubmit = async (values) => {
       const { data } = await login({
@@ -294,18 +204,12 @@ export default {
       registerClick,
       forgetPassword,
       sys,
-      // compLang,
-      // languageClk,
       isInWeChat,
       state,
       wxLoginHandler,
       getOpenid,
-      actions,
-      onSelect,
-      showPopover,
       currentLan,
       logoName,
-      // getImageUrl
       sysTitle,
     };
   },

+ 567 - 0
src/views/purse/index.vue

@@ -0,0 +1,567 @@
+<template>
+    <div class="wallet-page">
+        <!-- 导航栏 -->
+        <s-header name="我的钱包" :noback="false" :isBorder="false"></s-header>
+
+        <!-- 新版余额卡片 -->
+        <!-- <div class="new-balance-card">
+            <div class="card-bg">
+                <div class="wave"></div>
+                <div class="deco-circle"></div>
+            </div>
+
+            <div class="balance-content">
+                <div class="balance-header">
+                    <van-icon name="balance-pay" color="rgba(255,255,255,0.9)" size="20" />
+                    <span class="balance-label">可用余额(元)</span>
+                </div>
+
+                <div class="balance-main">
+                    <span class="currency">¥</span>
+                    <span class="amount">8,888.00</span>
+                </div>
+
+                <div class="action-buttons">
+                    <van-button round class="recharge-btn" @click="handleRecharge">
+                        <van-icon name="cash-back-record" size="16" />
+                        <span>立即充值</span>
+                    </van-button>
+
+                    <van-button round plain class="withdraw-btn" @click="handleWithdraw">
+                        <van-icon name="cash-on-deliver" size="16" />
+                        <span>申请提现</span>
+                    </van-button>
+                </div>
+            </div>
+        </div> -->
+
+        <!-- 余额概览 -->
+        <div class="balance-section">
+            <div class="section-title">
+                <van-icon name="balance-list" color="#4d6add" size="18" />
+                <span>资金账户</span>
+            </div>
+
+            <div class="balance-cards">
+                <!-- 今日收款卡片 -->
+                <div class="balance-card today-card">
+                    <div class="card-header">
+                        <van-icon name="cash-back-record" color="white" size="18" />
+                        <div class="card-title">
+                            <h3>今日收款余额(元)</h3>
+                        </div>
+                    </div>
+                    <div class="amount">8,888.00</div>
+                    <van-button icon="cash-back-record" @click="handleRecharge">
+                        立即充值
+                    </van-button>
+                    <!-- <div class="hint-text">
+                        <van-icon name="info" size="12" />
+                        <span>T+1自动转入可提现余额</span>
+                    </div> -->
+                </div>
+
+                <!-- 可提现卡片 -->
+                <div class="balance-card withdraw-card">
+                    <div class="card-header">
+                        <van-icon name="cash-on-deliver" color="white" size="18" />
+                        <div class="card-title">
+                            <h3>可提现余额(元)</h3>
+                        </div>
+                    </div>
+                    <div class="amount">6,666.00</div>
+                    <van-button icon="cash-on-deliver" @click="handleWithdraw">
+                        立即提现
+                    </van-button>
+                </div>
+            </div>
+        </div>
+
+        <!-- 记录入口 -->
+        <div class="record-section">
+            <div class="section-title">
+                <van-icon name="records" color="#4d6add" size="18" />
+                <span>交易记录</span>
+            </div>
+            <div class="record-cards">
+                <div class="record-card" @click="goToAutoRecord">
+                    <div class="card-icon auto">
+                        <van-icon name="passed" size="24" />
+                    </div>
+                    <div class="card-content">
+                        <h3>自动结算</h3>
+                        <p>查看系统自动结算记录</p>
+                    </div>
+                    <van-icon name="arrow" size="16" color="#ccc" />
+                </div>
+
+                <div class="record-card" @click="goToManualRecord">
+                    <div class="card-icon manual">
+                        <van-icon name="cash-on-deliver" size="24" />
+                    </div>
+                    <div class="card-content">
+                        <h3>手动提现</h3>
+                        <p>查看手动提现操作记录</p>
+                    </div>
+                    <van-icon name="arrow" size="16" color="#ccc" />
+                </div>
+            </div>
+        </div>
+
+        <!-- 银行卡管理 -->
+        <div class="bank-section">
+            <div class="section-title">
+                <van-icon name="credit-pay" color="#4d6add" size="18" />
+                <span>银行卡管理</span>
+            </div>
+
+            <div class="bank-cards">
+                <!-- 已绑卡状态 -->
+                <div class="bank-card" v-if="hasBankCard">
+                    <div class="card-header">
+                        <van-icon name="card" size="20" />
+                        <span>储蓄卡</span>
+                    </div>
+                    <div class="card-number">****​ ​****​ ​****​ 1234</div>
+                    <div class="card-footer">
+                        <span>中国工商银行</span>
+                        <van-icon name="ellipsis" size="16" />
+                    </div>
+                    <div class="auto-settle-hint" v-if="autoSettle">
+                        <van-icon name="checked" color="#4d6add" size="18" />
+                        <span>本卡已启用自动结算</span>
+                    </div>
+                    <div class="auto-settle-hint" v-if="!autoSettle">
+                        <van-icon name="circle" color="#4d6add" size="18" />
+                        <span>本卡已关闭自动结算</span>
+                    </div>
+                </div>
+
+                <!-- 未绑卡状态 -->
+                <div class="bank-card empty-state" v-else>
+                    <div class="empty-content">
+                        <p class="empty-title">尚未绑定银行卡</p>
+                        <p class="empty-desc">绑定后可享受快捷支付服务</p>
+                        <van-button type="primary" round size="small" @click="handleBindCard" class="bind-btn">
+                            <van-icon name="plus" size="16" />
+                            立即绑卡
+                        </van-button>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <div class="bottom-spacer"></div>
+    </div>
+</template>
+
+<script>
+import sHeader from "../../components/SimpleHeader";
+
+export default {
+    components: { sHeader },
+    setup() {
+
+
+        const handleRecharge = () => {
+            console.log('handleRecharge');
+        };
+
+        const handleWithdraw = () => {
+            console.log('handleWithdraw');
+        };
+
+        const goToAutoRecord = () => {
+            console.log('goToAutoRecord');
+        };
+
+        const goToManualRecord = () => {
+            console.log('goToManualRecord');
+        }
+
+        return {
+            handleRecharge,
+            handleWithdraw,
+            goToAutoRecord,
+            goToManualRecord
+        };
+    }
+};
+</script>
+
+<style lang="less" scoped>
+/* 公共样式 */
+.wallet-page {
+    background: #f8f9ff;
+}
+
+.section-title {
+    display: flex;
+    align-items: center;
+    gap: 4px;
+    padding: 10px 10px;
+    font-size: 18px;
+    color: #4d6add;
+    font-weight: 700;
+}
+
+/**
+余额卡片
+ */
+.balance-section {
+    margin: 10px 0px;
+}
+
+.balance-cards {
+    display: grid;
+    gap: 15px;
+    padding: 0 12px;
+}
+
+/* 基础卡片样式 */
+.balance-card {
+    border-radius: 16px;
+    padding: 15px;
+    position: relative;
+    overflow: hidden;
+    box-shadow: 0 8px 24px -6px rgba(0, 0, 0, 0.12);
+    transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+    min-height: 180px;
+}
+
+/* 卡片悬停动效 */
+.balance-card:hover {
+    transform: translateY(-5px);
+}
+
+/* 今日收款卡片 */
+.today-card {
+    background: linear-gradient(135deg,
+            #4f6cdf 0%,
+            #6b8cff 100%);
+    color: white;
+    border: 1px solid rgba(255, 255, 255, 0.15);
+    --start-color: #4f6cdf;
+    --end-color: #6b8cff;
+}
+
+/* 可提现卡片 */
+.withdraw-card {
+    background: linear-gradient(135deg,
+            #38b48d 0%,
+            #5cd4b0 100%);
+    color: white;
+    border: 1px solid rgba(255, 255, 255, 0.15);
+    --start-color: #38b48d;
+    --end-color: #5cd4b0;
+}
+
+/* 装饰性光斑 */
+.balance-card::after {
+    content: "";
+    position: absolute;
+    width: 200px;
+    height: 200px;
+    background: radial-gradient(circle,
+            rgba(255, 255, 255, 0.15) 0%,
+            rgba(255, 255, 255, 0) 70%);
+    top: -50px;
+    right: -50px;
+}
+
+/* 卡片内容样式 */
+.card-header {
+    display: flex;
+    align-items: center;
+    gap: 12px;
+    margin-bottom: 10px;
+    position: relative;
+    z-index: 1;
+}
+
+.card-header .van-icon {
+    background: rgba(255, 255, 255, 0.15);
+    padding: 8px;
+    border-radius: 10px;
+}
+
+.card-title h3 {
+    margin: 0;
+    font-size: 15px;
+    font-weight: 500;
+    letter-spacing: 0.5px;
+}
+
+.amount {
+    font-size: 30px;
+    font-weight: 600;
+    margin: 10px 0;
+    text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+    position: relative;
+    z-index: 1;
+}
+
+/* 按钮样式 */
+/* 限定在卡片内的按钮 */
+.balance-card .van-button {
+    backdrop-filter: blur(8px);
+    background: rgba(255, 255, 255, 0.15) !important;
+    border: 1px solid rgba(255, 255, 255, 0.3) !important;
+    color: white !important;
+    border-radius: 20px;
+    transition: all 0.3s ease;
+    width: auto
+}
+
+/* 仅影响卡片内的按钮悬停状态 */
+.balance-card .van-button:hover {
+    background: rgba(255, 255, 255, 0.25) !important;
+    transform: scale(1.05);
+}
+
+
+/* 提示文字 */
+.hint-text {
+    font-size: 12px;
+    opacity: 0.9;
+    margin-top: 12px;
+    display: flex;
+    align-items: center;
+    gap: 6px;
+}
+
+/* 响应式调整 */
+@media (max-width: 480px) {
+    .amount {
+        font-size: 28px;
+    }
+
+    .balance-card {
+        min-height: 140px;
+        padding: 16px;
+    }
+}
+
+/* 动态光效增强 */
+@keyframes glow {
+    0% {
+        opacity: 0.5;
+    }
+
+    50% {
+        opacity: 0.8;
+    }
+
+    100% {
+        opacity: 0.5;
+    }
+}
+
+.balance-card::before {
+    content: "";
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    background: linear-gradient(45deg,
+            transparent 40%,
+            rgba(255, 255, 255, 0.1) 50%,
+            transparent 60%);
+    animation: glow 3s infinite;
+    pointer-events: none;
+}
+
+
+
+/* 记录入口 */
+.record-section {
+    margin-top: 5px;
+}
+
+.record-cards {
+    display: grid;
+    gap: 12px;
+}
+
+.record-card {
+    background: white;
+    border-radius: 12px;
+    padding: 0 10px;
+    margin: 0 10px;
+    display: flex;
+    align-items: center;
+    gap: 12px;
+    box-shadow: 0 2px 8px rgba(77, 106, 221, 0.05);
+    transition: transform 0.2s ease;
+
+    &:active {
+        transform: scale(0.98);
+    }
+}
+
+.card-icon {
+    width: 44px;
+    height: 44px;
+    border-radius: 10px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+
+    &.auto {
+        background: rgba(77, 106, 221, 0.1);
+        color: #4d6add;
+    }
+
+    &.manual {
+        background: rgba(255, 152, 0, 0.1);
+        color: #ff9500;
+    }
+}
+
+.card-content {
+    flex: 1;
+
+    h3 {
+        font-size: 15px;
+        color: #333;
+        margin-bottom: 4px;
+    }
+
+    p {
+        font-size: 12px;
+        color: #999;
+    }
+}
+
+/* 银行卡管理 */
+.bank-section {
+    margin-top: 5px;
+}
+
+.bank-cards {
+    display: grid;
+    gap: 12px;
+}
+
+.bank-card {
+    background: white;
+    border-radius: 12px;
+    padding: 10px 5px;
+    margin: 0 10px;
+    // box-shadow: 0 2px 8px rgba(77, 106, 221, 0.05);
+    box-shadow: 0 4px 12px rgba(77, 106, 221, 0.08);
+    position: relative;
+    overflow: hidden;
+
+    &::before {
+        content: '';
+        position: absolute;
+        left: 0;
+        top: 0;
+        bottom: 0;
+        width: 4px;
+        background: #4d6add;
+    }
+
+    &.backup::before {
+        background: #6a82ee;
+    }
+}
+
+.card-header {
+    display: flex;
+    align-items: center;
+    gap: 8px;
+    margin-bottom: 12px;
+
+    span {
+        font-size: 14px;
+        color: #666;
+    }
+
+    .van-tag {
+        transform: scale(0.9);
+    }
+}
+
+.card-number {
+    font-family: monospace;
+    font-size: 18px;
+    color: #333;
+    letter-spacing: 2px;
+    margin: 16px 0;
+}
+
+.card-footer {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    color: #999;
+    font-size: 12px;
+}
+
+/* 统一按钮样式 */
+:deep(.van-button) {
+    font-weight: 500;
+    letter-spacing: 0.5px;
+}
+
+.auto-settle-hint {
+    margin-top: 12px;
+    padding-top: 12px;
+    border-top: 1px dashed #eee;
+    display: flex;
+    align-items: center;
+    gap: 8px;
+    color: #666;
+    font-size: 13px;
+}
+
+/* 未绑卡状态样式 */
+.bank-card.empty-state {
+    background: linear-gradient(135deg, #ffffff 0%, #f6f7fc 100%);
+    display: flex;
+    align-items: center;
+    justify-content: center;
+}
+
+.empty-content {
+    text-align: center;
+    padding: 10px;
+}
+
+.empty-icon {
+    margin-bottom: 12px;
+    filter: drop-shadow(0 2px 4px rgba(77, 106, 221, 0.1));
+}
+
+.empty-title {
+    color: #2d3447;
+    font-size: 16px;
+    margin-bottom: 8px;
+}
+
+.empty-desc {
+    color: #a3aac7;
+    font-size: 12px;
+    margin-bottom: 16px;
+}
+
+.bind-btn {
+    background: #4d6add;
+    padding: 8px 24px;
+    box-shadow: 0 3px 8px rgba(77, 106, 221, 0.2);
+}
+
+.bind-btn .van-icon {
+    margin-right: 6px;
+    vertical-align: -2px;
+}
+
+/* 占位元素样式 */
+.bottom-spacer {
+  height: 50px;
+  height: calc(60px + env(safe-area-inset-bottom));
+  pointer-events: none; /* 防止遮挡点击 */
+}
+</style>

+ 12 - 5
src/views/register.vue

@@ -142,7 +142,7 @@
 </template>
 <script>
 import md5 from 'js-md5';
-import { ref, onMounted, reactive, toRefs } from 'vue';
+import { ref, onMounted, reactive, toRefs, watch } from 'vue';
 import { showFailToast, showToast } from 'vant';
 // import { sentRegisterCode, tAdminSave, getLastSendTime } from '@/service/register';
 import { sentRegisterCode, tAdminSave } from '@/service/register';
@@ -160,7 +160,7 @@ import { useCascaderAreaData } from '@vant/area-data';
 export default {
   setup() {
     // 引入语言
-    let languageName = ref(getLocal("curLang"));
+    const languageName = ref(getLocal("curLang"));
     const { t } = useI18n();
     const active = ref(0);
     const username = ref('');
@@ -178,7 +178,7 @@ export default {
       time: 0
     });
     let phoneOrEmailStr = ref('');
-
+    
     const router = useRouter();
     const reqApi = ref(false);
     const hostName = ref('');
@@ -187,7 +187,15 @@ export default {
     const showCountry = ref(false);
     const cityValue = ref('');
     const countryOptions = ref(languageName.value == 'zh' ? countriesData : countriesDataEn);
-
+    
+    const { locale } = useI18n()
+    watch(locale, (newValue) => {
+      if (newValue == 'zh') {
+        countryOptions.value = countriesData;
+      } else {
+        countryOptions.value = countriesDataEn;
+      }
+    });
     const onConfirmCountry = ({ selectedOptions }) => {
       cityValue.value = selectedOptions.map((option) => option.text).join('/');
       citiesValue.value = selectedOptions[1]?.value;
@@ -345,7 +353,6 @@ export default {
         default:
           hostName.value = 'Sunzee';
       }
-      console.log("hostName.value >>>", hostName.value);
     }
 
     const signOptions = [

+ 1 - 1
src/views/robotRanking.vue

@@ -62,7 +62,7 @@
       </div>
     </div>
     <!-- 筛选弹窗 -->
-    <kDialog :dialogTitle="$t('subLedgerManage.search.title')" :confirmBtnTxt="$t('subLedgerManage.search.screen')"
+    <kDialog :dialogTitle="$t('orderExport.searchPop.title')" :confirmBtnTxt="$t('orderExport.searchPop.filter')"
       ref="kDialogRef" @confirmclk="confirmClk">
       <template #content>
         <div class="cust_vantBorder">

+ 1 - 1
src/views/terminal/check/index.vue

@@ -178,8 +178,8 @@ export default {
         onMounted(async () => {
             if (user && user.type > 1 && user.type < 4) {
                 searchParams.adminId = user.id;
-                getProportionCheckListFun();
             }
+            getProportionCheckListFun();
         });
         return {
             loading,

+ 9 - 2
src/views/user.vue

@@ -249,6 +249,14 @@
               <div class="taskTitle">绑定银行卡</div>
             </div>
           </div>
+          
+          <!-- 提现帐号 -->
+          <div v-if="user.type == 0" class="taskListRow l-flex-RC" @click="pushPageList('/purse')">
+            <div class="taskIcon joinPayMchIcon"></div>
+            <div class="taskRight">
+              <div class="taskTitle">钱包</div>
+            </div>
+          </div>
 
           <!-- 公告编辑 -->
           <div v-if="user.type == '0'" class="taskListRow l-flex-RC" @click="pushPageList('/announcement')">
@@ -646,7 +654,6 @@ export default {
         if (res.data.data.payPlatform == '1') {
           sevencloudPay.value = true;
         }
-        console.log("sevencloudPay", sevencloudPay.value)
       });
     };
     // 退出登录弹窗
@@ -859,7 +866,7 @@ export default {
     const name = ref("");
     // 国内省市
     const getArea = async () => {
-      try {        
+      try {
         const { data } = await getAreaById({
           areaId: areaId.value,
         });