浏览代码

fix:"优化部分页面UI"

soobin 2 月之前
父节点
当前提交
13cf78f652

+ 7 - 2
src/assets/language/zh.json

@@ -229,7 +229,12 @@
     "equipmentName": "设备名称",
     "creationTime": "报警时间",
     "alarmContent": "报警内容",
-    "allDevices": "所有设备"
+    "allDevices": "所有设备",
+    "level1": "提示",
+    "level2": "轻微",
+    "level3": "中等",
+    "level4": "严重",
+    "level5": "紧急"
   },
   "apkManage": {
     "apkManagement": "apk管理",
@@ -1288,7 +1293,7 @@
     "cancel": "撤销",
     "operationSucceeded": "操作成功",
     "taskMessage": "任务消息",
-    "toViewAppro": "查看待审批的申请",
+    "toViewAppro": "待审批",
     "whole": "全部",
     "unapproved": "未审核",
     "equipmentInit": {

+ 271 - 49
src/views/accountOperation/index.vue

@@ -1,79 +1,301 @@
 <template>
-  <!-- 任务消息列表 -->
-  <div class="taskMessagePage flex-col">
-    <s-header :name="$t('accountOperation.title')" :noback="false"></s-header>
-    <div class="taskMessageBox flex-col">
-      <!-- 账户权限 -->
-      <div class="taskListRow flex-col" @click="pushPageList('/accountPer')">
-        <div class="taskIcon deviceIcon"></div>
-        <div class="taskRight">
-          <div class="taskTitle">{{ $t('accountOperation.accountAuthority') }}</div>
-        </div>
-      </div>
-      <!-- 分销设置 -->
-      <div v-if="user.ifForeign != '1'" class="taskListRow flex-col" @click="pushPageList('/distributionSet')">
-        <div class="taskIcon retailIcon"></div>
-        <div class="taskRight">
-          <div class="taskTitle">{{ $t('accountOperation.distributionSettings') }}</div>
-        </div>
-      </div>
-      <!-- <div class="taskListRow flex-col" @click="pushPageList('/joinpayMch')">
-        <div class="taskIcon withIcon"></div>
-        <div class="taskRight">
-          <div class="taskTitle">{{ $t('accountOperation.withdrawalAccountNo') }}</div>
-        </div>
-      </div> -->
-      <!-- <div class="taskListRow flex-col" @click="pushPageList('/shandeMch')">
-	    <div class="taskIcon withIcon"></div>
-	    <div class="taskRight">
-	      <div class="taskTitle">{{$t('accountOperation.standbyWithdrawalAccountNo')}}</div>
-	    </div>
-	  </div> -->
-    <!-- 商户管理 -->
-      <div class="taskListRow flex-col" @click="pushPageList('/merchantManage')">
-        <div class="taskIcon merIcon"></div>
-        <div class="taskRight">
-          <div class="taskTitle">{{ $t('accountOperation.merchantManagement') }}</div>
-        </div>
-      </div>
-      <!-- 标签管理 -->
-      <!-- <div class="taskListRow flex-col" @click="pushPageList('/labelMan')">
-        <div class="taskIcon labelIcon"></div>
-        <div class="taskRight">
-          <div class="taskTitle">{{ $t('accountOperation.labelMan') }}</div>
+  <div class="task-message-page">
+    <s-header :name="$t('taskMessage.taskMessage')" :noback="false"></s-header>
+
+    <div class="task-message-container">
+      <div class="task-list">
+        <!-- 设备初始化审批 -->
+        <div
+          class="task-card"
+          :class="{ 'glow-effect': hoverIndex === 0 }"
+          @mouseover="hoverIndex = 0"
+          @mouseleave="hoverIndex = -1"
+          @click="pushPageList('/accountPer')"
+        >
+          <div class="card-content">
+            <div
+              class="icon-container"
+              :style="{ backgroundColor: lightenColor('#4d6add', 80) }"
+            >
+              <van-icon name="manager" class="task-icon" color="#4d6add" />
+            </div>
+            <div class="task-info">
+              <div class="task-title">
+                {{ $t("accountOperation.accountAuthority") }}
+              </div>
+            </div>
+            <div class="badge-icon">
+              <van-icon name="arrow" color="#4d6add" size="18" />
+            </div>
+          </div>
+          <div class="task-progress" :style="{ width: '100%' }"></div>
         </div>
-      </div> -->
 
+        <!-- 分销设置 -->
+        <!-- <div 
+          v-if="user.ifForeign != '1'" 
+          class="task-card" 
+          :class="{'glow-effect': hoverIndex === 1}"
+          @mouseover="hoverIndex = 1"
+          @mouseleave="hoverIndex = -1"
+          @click="pushPageList('/distributionSet')"
+        >
+          <div class="card-content">
+            <div class="icon-container" :style="{ backgroundColor: lightenColor('#4d6add', 80) }">
+              <van-icon name="cluster" class="task-icon" color="#4d6add" />
+            </div>
+            <div class="task-info">
+              <div class="task-title">{{ $t('accountOperation.distributionSettings') }}</div>
+            </div>
+            <div class="badge-icon">
+              <van-icon name="arrow" color="#4d6add" size="18" />
+            </div>
+          </div>
+          <div class="task-progress" :style="{ width: '100%' }"></div>
+        </div> -->
 
+        <!-- 商户管理 -->
+        <div
+          class="task-card"
+          :class="{ 'glow-effect': hoverIndex === 2 }"
+          @mouseover="hoverIndex = 2"
+          @mouseleave="hoverIndex = -1"
+          @click="pushPageList('/merchantManage')"
+        >
+          <div class="card-content">
+            <div
+              class="icon-container"
+              :style="{ backgroundColor: lightenColor('#4d6add', 80) }"
+            >
+              <van-icon name="shop" class="task-icon" color="#4d6add" />
+            </div>
+            <div class="task-info">
+              <div class="task-title">
+                {{ $t("accountOperation.merchantManagement") }}
+              </div>
+            </div>
+            <div class="badge-icon">
+              <van-icon name="arrow" color="#4d6add" size="18" />
+            </div>
+          </div>
+          <div class="task-progress" :style="{ width: '100%' }"></div>
+        </div>
+      </div>
     </div>
   </div>
 </template>
 
 <script>
-import { onMounted } from 'vue';
+import { onMounted, ref } from "vue";
 import sHeader from "../../components/SimpleHeader";
 import { useRouter } from "vue-router";
-import { getLoginUser, styleUrl } from "../../common/js/utils";
+import { getLoginUser } from "../../common/js/utils";
 
 export default {
   components: { sHeader },
   setup() {
     const router = useRouter();
-    styleUrl('accountOperation');
     const user = getLoginUser();
+    // 状态控制
+    const hoverIndex = ref(-1);
+    const lightenColor = (hex, percent) => {
+      console.log(hex, percent);
+      return "#e6f0ff";
+    };
     // 初始化页面获取列表
-    onMounted(async () => { });
+    onMounted(async () => {});
     const pushPageList = (url) => {
       router.push(url);
     };
     return {
       pushPageList,
       user,
+      hoverIndex,
+      lightenColor,
     };
-  }
+  },
 };
 </script>
 
 <style lang="less" scoped>
-@import "../../common/style/common.less";
+@theme-color: #4d6add;
+@light-bg: #f5f8ff;
+@card-shadow: 0 4px 12px rgba(77, 106, 221, 0.15);
+@hover-shadow: 0 8px 24px rgba(77, 106, 221, 0.25);
+@transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
+@text-dark: #333;
+@text-light: #666;
+@card-radius: 16px;
+
+.task-message-page {
+  display: flex;
+  flex-direction: column;
+  height: 100vh;
+  background-color: @light-bg;
+  font-family: "PingFang SC", "Helvetica Neue", Arial, sans-serif;
+
+  .task-message-container {
+    flex: 1;
+    display: flex;
+    flex-direction: column;
+    padding: 16px;
+    overflow-y: auto;
+
+    .task-list {
+      flex: 1;
+      display: flex;
+      flex-direction: column;
+      gap: 16px;
+      margin-bottom: 20px;
+    }
+  }
+}
+
+/* 任务卡片样式 */
+.task-card {
+  background: white;
+  border-radius: @card-radius;
+  box-shadow: @card-shadow;
+  padding: 18px 16px;
+  position: relative;
+  overflow: hidden;
+  transition: @transition;
+  cursor: pointer;
+  border: 1px solid rgba(77, 106, 221, 0.1);
+
+  &:hover {
+    transform: translateY(-4px);
+    box-shadow: @hover-shadow;
+    border-color: rgba(77, 106, 221, 0.3);
+
+    .badge-icon {
+      transform: translateX(5px);
+    }
+  }
+
+  &.glow-effect {
+    border-color: rgba(77, 106, 221, 0.5);
+    background-color: rgba(77, 106, 221, 0.03);
+  }
+
+  .card-content {
+    display: flex;
+    align-items: center;
+    position: relative;
+    z-index: 2;
+  }
+
+  .icon-container {
+    width: 54px;
+    height: 54px;
+    border-radius: 14px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    flex-shrink: 0;
+    transition: @transition;
+
+    .task-icon {
+      font-size: 24px;
+    }
+  }
+
+  .task-info {
+    flex: 1;
+    margin-left: 16px;
+    margin-right: 10px;
+    overflow: hidden;
+
+    .task-title {
+      font-size: 17px;
+      font-weight: 600;
+      color: @text-dark;
+      margin-bottom: 5px;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      white-space: nowrap;
+    }
+  }
+
+  .badge-icon {
+    width: 30px;
+    height: 30px;
+    background-color: fade(@theme-color, 10%);
+    border-radius: 50%;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    transition: @transition;
+  }
+
+  .task-progress {
+    position: absolute;
+    bottom: 0;
+    left: 0;
+    height: 3px;
+    background: linear-gradient(
+      90deg,
+      @theme-color,
+      lighten(@theme-color, 20%)
+    );
+    border-bottom-left-radius: @card-radius;
+    transition: all 0.8s cubic-bezier(0.22, 0.61, 0.36, 1);
+  }
+}
+
+/* 动画效果 */
+@keyframes cardEntry {
+  0% {
+    transform: translateY(20px);
+    opacity: 0;
+  }
+  100% {
+    transform: translateY(0);
+    opacity: 1;
+  }
+}
+
+.task-card {
+  animation: cardEntry 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards;
+  opacity: 0;
+
+  &:nth-child(1) {
+    animation-delay: 0.1s;
+  }
+  &:nth-child(2) {
+    animation-delay: 0.2s;
+  }
+  &:nth-child(3) {
+    animation-delay: 0.3s;
+  }
+  &:nth-child(4) {
+    animation-delay: 0.4s;
+  }
+}
+
+/* 响应式设计 */
+@media (max-width: 480px) {
+  .task-message-container {
+    padding: 12px;
+  }
+
+  .task-card {
+    padding: 16px 14px;
+
+    .icon-container {
+      width: 50px;
+      height: 50px;
+
+      .task-icon {
+        font-size: 22px;
+      }
+    }
+
+    .task-info {
+      .task-title {
+        font-size: 16px;
+      }
+    }
+  }
+}
 </style>

+ 2 - 2
src/views/accountPer/add.vue

@@ -16,9 +16,9 @@
           left-icon="contact" class="modern-field"
           :rules="[{ required: true, message: $t('accountPer.namePlaceholder') }]" />
 
-        <van-field v-model="phone" :label="$t('accountPer.phoneLabel')" :placeholder="$t('accountPer.phonePlaceholder')"
+        <!-- <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') }]" />
+          :rules="[{ required: true, message: $t('accountPer.phonePlaceholder') }]" /> -->
 
         <!-- 类型选择 -->
         <van-field name="radio" v-if="user.type === 0" class="radio-field">

+ 479 - 51
src/views/alarmHistory/index.vue

@@ -1,68 +1,113 @@
 <template>
-  <!-- 报警历史 -->
-  <div class="alarmHistoryPage flex-col">
-    <s-header :name="$t('alarmHistory.alarmHistory')" :noback="false"></s-header>
-    <div class="alarmHistoryBox flex-col">
-      <van-list v-model:loading="loading" v-model:error="error" error-text="{{$t('alarmHistory.requestFailed')}}"
-        :finished="finished" :finished-text="$t('alarmHistory.noMore')" offset="300" :immediate-check="false"
-        @load="onLoad">
-        <div class="searchRow flex-row justify-between">
-          <div class="flex-col">
-            <div class="flex-row justify-between bd3">
-              <div class="flex-col outer4"></div>
-              <span class="flex-col txt2">{{ $t('alarmHistory.common') }}<span class="discountNumber">{{ alarmHistoryTotal
-              }}</span>{{ $t('alarmHistory.recordsTotal') }}</span>
-            </div>
+  <div class="alarm-history-container">
+    <!-- 系统头部 -->
+    <s-header :name="$t('alarmHistory.alarmHistory')" :noback="false" />
+
+    <!-- 主要内容区域 -->
+    <div class="alarm-history-content">
+      <!-- 顶部筛选和统计区(优化版) -->
+      <div class="stats-filter-card">
+        <!-- 统计信息区 -->
+        <div class="stats-area">
+          <div class="stats-icon-box">
+            <van-icon name="bell" size="20" color="#ff6d59" />
           </div>
-          <div class="flex-col">
-            <div class="main5 flex-row justify-between" @click="searchClick">
-              <img class="label2 o-mr-5" src="../../assets/device/searchIcon.png" />
-              <!-- <div class="TextGroup2 flex-col">
-                <span class="txt3">{{ $t('alarmHistory.search') }}</span>
-              </div> -->
+          <div class="stats-content">
+            <div class="stats-value">
+              <span class="highlight-number"
+                >{{ alarmHistoryTotal
+                }}{{ $t("alarmHistory.recordsTotal") }}</span
+              >
             </div>
           </div>
         </div>
-        <div class="listBox">
-          <div v-for="(item, index) in alarmHistoryList" :key="index" class="listItem">
-            <div class="itemBox">
-              <div class="itemRow">
-                <span class="itemTitle">{{ $t('alarmHistory.affiliatedMerchants') }}:&nbsp;</span>{{ item.adminUserName }}
+
+        <!-- 搜索功能区 -->
+        <div class="filter-area">
+          <div class="filter-btn" @click="searchClick">
+            <van-icon name="search" size="18" color="#ffffff" />
+            <span class="btn-text">{{ $t("alarmHistory.search") }}</span>
+          </div>
+        </div>
+      </div>
+
+      <!-- 报警历史列表 -->
+      <van-list
+        v-model:loading="loading"
+        v-model:error="error"
+        :error-text="$t('alarmHistory.requestFailed')"
+        :finished="finished"
+        :finished-text="$t('alarmHistory.noMore')"
+        offset="100"
+        :immediate-check="false"
+        @load="onLoad"
+      >
+        <!-- 列表项(卡片式设计) -->
+        <div class="history-list">
+          <div
+            v-for="(item, index) in alarmHistoryList"
+            :key="index"
+            class="history-card"
+            :class="[getAlarmLevelClass(item.level)]"
+          >
+            <div class="card-header flex-row justify-between align-center">
+              <div class="card-title">
+                {{ showDeviceName(item.equipmentId) }}
               </div>
-              <div class="itemRow">
-                <span class="itemTitle">{{ $t('alarmHistory.equipmentNo') }}:&nbsp;</span>{{ item.clientId }}
+              <div class="card-time">
+                {{ showDateTime(item.occurrenceTime) }}
               </div>
-              <div class="itemRow">
-                <span class="itemTitle">{{ $t('alarmHistory.equipmentName') }}:&nbsp;</span>{{
-                  showDeviceName(item.equipmentId)
-                }}
+            </div>
+
+            <!-- 卡片内容 -->
+            <div class="card-body">
+              <div class="info-row">
+                <div class="info-label">
+                  {{ $t("alarmHistory.affiliatedMerchants") }}:
+                </div>
+                <div class="info-value">{{ item.adminUserName }}</div>
               </div>
-              <div class="itemRow">
-                <span class="itemTitle">{{ $t('alarmHistory.creationTime') }}:&nbsp;</span>{{
-                  showDateTime(item.occurrenceTime)
-                }}
+
+              <div class="info-row">
+                <div class="info-label">
+                  {{ $t("alarmHistory.equipmentNo") }}:
+                </div>
+                <div class="info-value badge-id">{{ item.clientId }}</div>
               </div>
-              <div class="itemRow">
-                <span class="itemTitle">{{ $t('alarmHistory.alarmContent') }}:&nbsp;</span>{{ item.alarmContent }}
+
+              <div class="info-row">
+                <div class="info-label">
+                  {{ $t("alarmHistory.alarmContent") }}:
+                </div>
+                <div class="info-value alarm-content">
+                  {{ item.alarmContent }}
+                </div>
               </div>
             </div>
+
+            <!-- 报警级别标识 -->
+            <div class="alarm-level">
+              {{ $t(`alarmHistory.level${item.level}`) }}
+            </div>
           </div>
         </div>
       </van-list>
     </div>
-    <historySearch ref="searchRef" @search="search($event)"></historySearch>
+
+    <!-- 历史搜索组件 -->
+    <history-search ref="searchRef" @search="search($event)" />
   </div>
 </template>
 
 <script>
 import { onMounted, reactive, ref } from "vue";
 import sHeader from "@/components/SimpleHeader";
-import historySearch from './historySearch.vue';
+import historySearch from "./historySearch.vue";
 import { getAlarmHistoryList, getEquipmentList } from "@/service/alarmHistory";
 import { getLoginUser } from "@/common/js/utils";
 import dateUtil from "@/utils/dateUtil";
 import { showFailToast } from "vant";
-import { useI18n } from 'vue-i18n';
+import { useI18n } from "vue-i18n";
 import { styleUrl } from "../../common/js/utils";
 
 export default {
@@ -89,7 +134,7 @@ export default {
     // 初始化页面获取列表
     onMounted(async () => {
       // 加载样式
-      styleUrl('alarmHistory');
+      styleUrl("alarmHistory");
       getDeviceListFun();
       if (user) {
         searchParams.adminId = user.id;
@@ -100,12 +145,11 @@ export default {
     const getDeviceListFun = async () => {
       const { data } = await getEquipmentList({ adminId: user.id });
       if (data.code === "00000") {
-        // deviceList.value = data.data.map(item => {
-        //   return item.name
-        // });
-        // deviceList.value.unshift('所有设备');
         equipmentSourceList.value = data.data;
-        equipmentSourceList.value.unshift({ name: t('alarmHistory.allDevices'), id: null });
+        equipmentSourceList.value.unshift({
+          name: t("alarmHistory.allDevices"),
+          id: null,
+        });
         console.log(equipmentSourceList);
       }
     };
@@ -147,13 +191,12 @@ export default {
       }
     };
     const showDateTime = (date) => {
-      // return date
-      //   ? dateUtil.formateDate(new Date(date), "yyyy-MM-dd hh:mm:ss")
-      //   : "";
       if (!date) {
         return "";
       }
-      const currentDate = new Date(dateUtil.formateDate(new Date(date), "yyyy/MM/dd hh:mm:ss"));
+      const currentDate = new Date(
+        dateUtil.formateDate(new Date(date), "yyyy/MM/dd hh:mm:ss")
+      );
       return dateUtil.timeZoneDate(currentDate);
     };
     const showDeviceName = (id) => {
@@ -167,6 +210,10 @@ export default {
     const searchClick = () => {
       searchRef.value.showSearch();
     };
+
+    const getAlarmLevelClass = (level) => {
+      return `level-${level}`;
+    };
     return {
       search,
       searchRef,
@@ -179,11 +226,392 @@ export default {
       alarmHistoryTotal,
       showDateTime,
       showDeviceName,
+      getAlarmLevelClass,
     };
   },
 };
 </script>
 
 <style lang="less" scoped>
-@import "../../common/style/common.less";
+@theme-color: #4d6add;
+@light-theme: lighten(@theme-color, 20%);
+@text-color: #333;
+@light-text: #666;
+@border-color: #e6e8f0;
+@card-shadow: 0 4px 16px rgba(77, 106, 221, 0.1);
+@highlight-shadow: 0 4px 20px rgba(77, 106, 221, 0.25);
+
+.alarm-history-container {
+  display: flex;
+  flex-direction: column;
+  height: 100vh;
+  background-color: #f5f8ff;
+}
+
+.alarm-history-content {
+  flex: 1;
+  padding: 16px;
+  overflow-y: auto;
+}
+
+/* 顶部筛选统计卡片(优化版) */
+.stats-filter-card {
+  display: flex;
+  justify-content: space-between;
+  background: linear-gradient(135deg, @theme-color, #6878eb);
+  border-radius: 16px;
+  padding: 16px;
+  box-shadow: @highlight-shadow;
+  margin-bottom: 16px;
+  color: white;
+}
+
+.stats-area {
+  display: flex;
+  align-items: center;
+  flex: 1;
+
+  .stats-icon-box {
+    width: 35px;
+    height: 35px;
+    background: rgba(255, 255, 255, 0.2);
+    border-radius: 12px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    margin-right: 10px;
+  }
+
+  .stats-content {
+    .stats-title {
+      font-size: 14px;
+      opacity: 0.9;
+      margin-bottom: 4px;
+    }
+
+    .stats-value {
+      font-size: 20px;
+      font-weight: bold;
+      display: flex;
+      align-items: flex-end;
+
+      .highlight-number {
+        font-size: 18px;
+        margin: 0 4px;
+      }
+    }
+  }
+}
+
+.filter-area {
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+
+.filter-btn {
+  display: flex;
+  align-items: center;
+  background: rgba(255, 255, 255, 0.2);
+  border-radius: 18px;
+  padding: 6px 15px 6px 12px;
+  font-size: 13px;
+  cursor: pointer;
+  transition: all 0.3s;
+  margin-bottom: 10px;
+
+  &:last-child {
+    margin-bottom: 0;
+  }
+
+  .van-icon {
+    margin-right: 8px;
+  }
+
+  &:hover {
+    background: rgba(255, 255, 255, 0.3);
+    transform: translateY(-2px);
+  }
+
+  &:active {
+    transform: translateY(0);
+  }
+}
+
+/* 报警历史卡片 */
+.history-list {
+  display: grid;
+  grid-template-columns: 1fr;
+  gap: 16px;
+}
+
+.history-card {
+  background-color: #fff;
+  border-radius: 12px;
+  padding: 16px;
+  box-shadow: @card-shadow;
+  position: relative;
+  overflow: hidden;
+
+  &.level-5 {
+    border-left: 4px solid #ff5252;
+
+    .alarm-level {
+      background: linear-gradient(to right, #ff5252, #ff7b7b);
+    }
+  }
+
+  &.level-4 {
+    border-left: 4px solid #ff9800;
+
+    .alarm-level {
+      background: linear-gradient(to right, #ff9800, #ffb74d);
+    }
+  }
+
+  &.level-3 {
+    border-left: 4px solid #F1C40F;
+
+    .alarm-level {
+      background: linear-gradient(to right, #F1C40F, #e7d488);
+    }
+  }
+
+  &.level-2 {
+    border-left: 4px solid #4caf50;
+
+    .alarm-level {
+      background: linear-gradient(to right, #4caf50, #81c784);
+    }
+  }
+
+  &.level-1 {
+    border-left: 4px solid #3498DB;
+
+    .alarm-level {
+      background: linear-gradient(to right, #3498DB, #84b3d3);
+    }
+  }
+}
+
+.card-header {
+  padding-bottom: 12px;
+  border-bottom: 1px solid @border-color;
+  margin-bottom: 12px;
+}
+
+.card-title {
+  font-weight: bold;
+  font-size: 16px;
+  color: @text-color;
+  max-width: 70%;
+}
+
+.card-time {
+  font-size: 12px;
+  color: @light-text;
+}
+
+.info-row {
+  display: flex;
+  margin-bottom: 10px;
+  font-size: 14px;
+
+  &:last-child {
+    margin-bottom: 0;
+  }
+}
+
+.info-label {
+  color: @light-text;
+  min-width: 100px;
+}
+
+.info-value {
+  color: @text-color;
+  flex: 1;
+}
+
+.badge-id {
+  background-color: lighten(@theme-color, 45%);
+  color: darken(@theme-color, 10%);
+  border-radius: 4px;
+  display: inline-block;
+  font-weight: bold;
+  font-size: 13px;
+}
+
+.alarm-content {
+  font-weight: 500;
+}
+
+.alarm-level {
+  position: absolute;
+  top: 0;
+  right: 0;
+  background: @theme-color;
+  color: white;
+  font-size: 12px;
+  padding: 4px 12px;
+  border-bottom-left-radius: 8px;
+  font-weight: 500;
+}
+
+.empty-state {
+  text-align: center;
+  padding: 40px 20px;
+
+  .empty-icon {
+    font-size: 60px;
+    color: #d1d8f0;
+    margin-bottom: 15px;
+  }
+
+  p {
+    font-size: 16px;
+    color: @light-text;
+  }
+}
+
+/* 筛选菜单弹出框 */
+.filter-popup {
+  max-height: 80vh;
+  padding: 20px;
+
+  .popup-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding-bottom: 15px;
+    border-bottom: 1px solid #f0f0f0;
+    margin-bottom: 20px;
+
+    h3 {
+      font-size: 18px;
+      font-weight: 600;
+      color: @text-color;
+      margin: 0;
+    }
+
+    .van-icon {
+      font-size: 20px;
+      color: #999;
+    }
+  }
+
+  .filter-group {
+    margin-bottom: 20px;
+
+    h4 {
+      font-size: 15px;
+      color: @text-color;
+      font-weight: 500;
+      margin-bottom: 12px;
+    }
+
+    .van-checkbox {
+      margin-bottom: 12px;
+
+      &:last-child {
+        margin-bottom: 0;
+      }
+    }
+  }
+
+  .date-range {
+    display: flex;
+    align-items: center;
+
+    .van-field {
+      flex: 1;
+      background: #f9f9f9;
+      border-radius: 8px;
+      padding: 10px 15px;
+    }
+
+    .date-divider {
+      margin: 0 10px;
+      color: #999;
+    }
+  }
+
+  .filter-actions {
+    display: flex;
+    justify-content: space-between;
+    margin-top: 20px;
+
+    .van-button {
+      flex: 1;
+      border-radius: 20px;
+      height: 44px;
+      font-weight: 500;
+
+      &:first-child {
+        margin-right: 15px;
+      }
+    }
+  }
+}
+
+/* 动画效果 */
+@keyframes fadeIn {
+  from {
+    opacity: 0;
+    transform: translateY(10px);
+  }
+  to {
+    opacity: 1;
+    transform: translateY(0);
+  }
+}
+
+.history-card {
+  animation: fadeIn 0.3s ease-out;
+  animation-fill-mode: both;
+
+  @delay: 0.1s;
+  @delay-increment: 0.05s;
+
+  &:nth-child(1) {
+    animation-delay: 0.05s;
+  }
+  &:nth-child(2) {
+    animation-delay: 0.1s;
+  }
+  &:nth-child(3) {
+    animation-delay: 0.15s;
+  }
+  &:nth-child(4) {
+    animation-delay: 0.2s;
+  }
+  &:nth-child(5) {
+    animation-delay: 0.25s;
+  }
+  &:nth-child(6) {
+    animation-delay: 0.3s;
+  }
+}
+
+/* 响应式布局 */
+@media (max-width: 480px) {
+  .stats-filter-card {
+    flex-direction: column;
+    gap: 12px;
+  }
+
+  .filter-area {
+    flex-direction: row;
+    justify-content: flex-end;
+    gap: 10px;
+
+    .filter-btn {
+      margin-bottom: 0;
+    }
+  }
+
+  .time-filter-group .van-button {
+    padding: 0 16px;
+    height: 30px;
+  }
+}
 </style>

+ 54 - 1
src/views/bindBankCard/index.vue

@@ -950,7 +950,13 @@ export default {
     const afterRead = async (file, type) => {
       try {
         const fileData = new FormData();
-        fileData.append("file", file.file);
+        if (file.file.size > 1000 * 1024) {
+          // 压缩文件
+          const compressedFile = await createCompressedImage(file);
+          fileData.append("file", compressedFile)
+        } else {
+          fileData.append("file", file.file);
+        }
         fileData.append("adminId", user.id);
         fileData.append("imageType", type.name);
         const { data } = await idCardRecognition(fileData);
@@ -999,6 +1005,53 @@ export default {
       }
     };
 
+    // 压缩图片
+    const createCompressedImage = (file) => {
+      return new Promise((resolve, reject) => {
+        const img = new Image();
+        img.src = file.content;
+        
+        img.onload = () => {
+          // 计算新尺寸(保持宽高比)
+          const maxSize = 1920;
+          let width = img.width;
+          let height = img.height;
+          
+          if (width > maxSize || height > maxSize) {
+            const ratio = Math.min(maxSize / width, maxSize / height);
+            width = Math.floor(width * ratio);
+            height = Math.floor(height * ratio);
+          }
+
+          // 创建Canvas进行压缩
+          const canvas = document.createElement('canvas');
+          canvas.width = width;
+          canvas.height = height;
+          
+          const ctx = canvas.getContext('2d');
+          ctx.drawImage(img, 0, 0, width, height);
+
+          // 调整压缩质量(大图用0.7,中等图用0.8)
+          const quality = 0.95;
+
+          
+          canvas.toBlob(
+            blob => {
+              const compressedFile = new File([blob], file.file.name, {
+                type: 'image/jpeg',
+                lastModified: Date.now()
+              });
+              resolve(compressedFile);
+            },
+            'image/jpeg',
+            quality
+          );
+        };
+
+        img.onerror = reject;
+      });
+    }
+
     // 确认日期选择
     const idDateConfirm = () => {
       formData.value.validDate = validDate.value.join("-");

+ 331 - 183
src/views/device/deviceSearch.vue

@@ -1,26 +1,54 @@
 <template>
   <!-- 设备列表 - 搜索弹窗 -->
   <div class="deviceSearch flex-col">
-    <van-action-sheet v-model:show="sheetShow" :closeable='false' :title="$t('device.enterAnyInformationToSearch')">
+    <van-action-sheet
+      v-model:show="sheetShow"
+      :closeable="false"
+      :title="$t('device.enterAnyInformationToSearch')"
+    >
       <div class="content">
         <van-form @submit="onSubmit">
           <!-- 设备编号 -->
-          <van-field v-model="clientId" name="clientId" :label="$t('device.equipmentNoLabel')"
-            :placeholder="$t('device.equipmentNoPlaceholder')" />
+          <van-field
+            v-model="clientId"
+            name="clientId"
+            :label="$t('device.equipmentNoLabel')"
+            :placeholder="$t('device.equipmentNoPlaceholder')"
+          />
           <!-- 设备名称 -->
-          <van-field v-model="equipmentName" name="equipmentName" :label="$t('device.equipmentNameLabel')"
-            :placeholder="$t('device.equipmentNamePlaceholder')" />
+          <van-field
+            v-model="equipmentName"
+            name="equipmentName"
+            :label="$t('device.equipmentNameLabel')"
+            :placeholder="$t('device.equipmentNamePlaceholder')"
+          />
           <!-- 商家名 -->
-          <van-field v-model="adminName" name="adminName" :label="$t('device.merchantNameLabel')"
-            :placeholder="$t('device.merchantNamePlaceholder')" />
+          <van-field
+            v-model="adminName"
+            name="adminName"
+            :label="$t('device.merchantNameLabel')"
+            :placeholder="$t('device.merchantNamePlaceholder')"
+          />
           <!-- 公司平台 -->
           <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-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-cascader
+                v-model="companyType"
+                :title="$t('device.companyTypePlaceholder')"
+                :options="companyTypeOptions"
+                @close="companyTypeShow = false"
+                @finish="companyTypeFinish"
+              />
             </van-popup>
           </div>
           <!-- <van-field
@@ -32,103 +60,118 @@
           <!-- 设备类型、设备机型 -->
           <van-row>
             <van-col span="12">
-              <van-field label-width="66" v-model="machineTypeText" is-link readonly
-                :label="$t('device.equipmentTypeLabel')" :placeholder="$t('device.equipmentTypePlaceholder')"
-                @click="machineTypeShow = true" class="field" />
+              <van-field
+                label-width="66"
+                v-model="machineTypeText"
+                is-link
+                readonly
+                :label="$t('device.equipmentTypeLabel')"
+                :placeholder="$t('device.equipmentTypePlaceholder')"
+                @click="machineTypeShow = true"
+                class="field"
+              />
               <van-popup v-model:show="machineTypeShow" round position="bottom">
-                <van-cascader v-model="machineType" :title="$t('device.equipmentTypePlaceholder')"
-                  :options="machineTypeOptions" @close="machineTypeShow = false" @finish="machineTypeFinish" />
+                <van-cascader
+                  v-model="machineType"
+                  :title="$t('device.equipmentTypePlaceholder')"
+                  :options="machineTypeOptions"
+                  @close="machineTypeShow = false"
+                  @finish="machineTypeFinish"
+                />
               </van-popup>
             </van-col>
             <van-col span="12">
-              <van-field label-width="66" v-model="equimentTypeText" is-link readonly
-                :label="$t('device.equipmentModelLabel')" :placeholder="$t('device.equipmentModelPlaceholder')"
-                @click="equimentTypeShow = true" class="field" />
-              <van-popup v-model:show="equimentTypeShow" round position="bottom">
-                <van-cascader v-model="equimentType" :title="$t('device.equipmentModelPlaceholder')"
-                  :options="equimentTypeOptions" @close="equimentTypeShow = false" @finish="equimentTypeFinish" />
+              <van-field
+                label-width="66"
+                v-model="equimentTypeText"
+                is-link
+                readonly
+                :label="$t('device.equipmentModelLabel')"
+                :placeholder="$t('device.equipmentModelPlaceholder')"
+                @click="equimentTypeShow = true"
+                class="field"
+              />
+              <van-popup
+                v-model:show="equimentTypeShow"
+                round
+                position="bottom"
+              >
+                <van-cascader
+                  v-model="equimentType"
+                  :title="$t('device.equipmentModelPlaceholder')"
+                  :options="equimentTypeOptions"
+                  @close="equimentTypeShow = false"
+                  @finish="equimentTypeFinish"
+                />
               </van-popup>
             </van-col>
           </van-row>
           <!-- 开机状态、设备状态 -->
           <van-row>
             <van-col span="12">
-              <van-field label-width="66" v-model="eqeStatusText" is-link readonly :label="$t('device.powerOnStatus')"
-                :placeholder="$t('device.pleaseSelectThePowerOnStatus')" @click="eqeStatusShow = true" class="field" />
-              <van-popup v-model:show="eqeStatusShow" round position="bottom">
-                <van-cascader v-model="eqeStatus" :title="$t('device.pleaseSelectThePowerOnStatus')"
-                  :options="eqeStatusOptions" @close="eqeStatusShow = false" @finish="eqeStatusFinish" />
-              </van-popup>
-            </van-col>
-            <van-col span="12">
-              <van-field label-width="66" v-model="isUsingText" is-link readonly :label="$t('device.equipmentStatus')"
-                :placeholder="$t('device.pleaseSelectTheDeviceStatus')" @click="isUsingShow = true" class="field" />
-              <van-popup v-model:show="isUsingShow" round position="bottom">
-                <van-cascader v-model="isUsing" :title="$t('device.pleaseSelectTheDeviceStatus')"
-                  :options="isUsingOptions" @close="isUsingShow = false" @finish="isUsingFinish" />
-              </van-popup>
-            </van-col>
-          </van-row>
-
-          <!-- 设备标签分组 -->
-          <!-- <div>
-            <van-field label-width="86" v-model="deviceGroupText" is-link readonly :label="$t('device.deviceGrouping')"
-              :placeholder="$t('device.plzSelectDeviceGroup')" @click="deviceGroupShow = true" class="field" />
-            <van-popup v-model:show="deviceGroupShow" round position="bottom">
-              <van-cascader v-model="deviceGroup" :title="$t('device.deviceGroupPlaceholder')"
-                :options="deviceGroupOptions" @close="deviceGroupShow = false" @finish="deviceGroupFinish" />
-            </van-popup>
-          </div> -->
-
-          <!-- 支付方式、信道 -->
-          <van-row>
-            <!-- <van-col span="12">
               <van-field
-                v-model="payTypeText"
+                label-width="66"
+                v-model="eqeStatusText"
                 is-link
                 readonly
-                label="支付方式"
-                placeholder="请选择支付方式"
-                @click="payTypeShow = true"
+                :label="$t('device.powerOnStatus')"
+                :placeholder="$t('device.pleaseSelectThePowerOnStatus')"
+                @click="eqeStatusShow = true"
                 class="field"
               />
-              <van-popup v-model:show="payTypeShow" round position="bottom">
+              <van-popup v-model:show="eqeStatusShow" round position="bottom">
                 <van-cascader
-                  v-model="payType"
-                  title="请选择支付方式"
-                  :options="payTypeOptions"
-                  @close="payTypeShow = false"
-                  @finish="payTypeFinish"
+                  v-model="eqeStatus"
+                  :title="$t('device.pleaseSelectThePowerOnStatus')"
+                  :options="eqeStatusOptions"
+                  @close="eqeStatusShow = false"
+                  @finish="eqeStatusFinish"
                 />
               </van-popup>
-            </van-col> -->
-            <!-- <van-col span="12">
+            </van-col>
+            <van-col span="12">
               <van-field
-                v-model="channelText"
+                label-width="66"
+                v-model="isUsingText"
                 is-link
                 readonly
-                label="信道"
-                placeholder="请选择信道"
-                @click="channelShow = true"
+                :label="$t('device.equipmentStatus')"
+                :placeholder="$t('device.pleaseSelectTheDeviceStatus')"
+                @click="isUsingShow = true"
                 class="field"
               />
-              <van-popup v-model:show="channelShow" round position="bottom">
+              <van-popup v-model:show="isUsingShow" round position="bottom">
                 <van-cascader
-                  v-model="channel"
-                  title="请选择信道"
-                  :options="channelOptions"
-                  @close="channelShow = false"
-                  @finish="channelFinish"
+                  v-model="isUsing"
+                  :title="$t('device.pleaseSelectTheDeviceStatus')"
+                  :options="isUsingOptions"
+                  @close="isUsingShow = false"
+                  @finish="isUsingFinish"
                 />
               </van-popup>
-            </van-col> -->
+            </van-col>
           </van-row>
           <!-- 操作 -->
-          <van-row justify="space-around" style="padding: 2em;">
-            <van-button class="clearBtn" span="5" round plain type="primary" style="height: 2em; padding: 0 2em;"
-              @click="registerClick">{{ $t('device.emptyingConditions') }}</van-button>
-            <van-button class="selectBtn" span="5" round type="primary" style="height: 2em; padding: 0 2em;"
-              native-type="submit">{{ $t('device.clickSearch') }}</van-button>
+          <van-row justify="space-around" style="padding: 2em">
+            <van-button
+              class="clearBtn"
+              span="5"
+              round
+              plain
+              type="primary"
+              style="height: 2em; padding: 0 2em"
+              @click="registerClick"
+              >{{ $t("device.emptyingConditions") }}</van-button
+            >
+            <van-button
+              class="selectBtn"
+              span="5"
+              round
+              type="primary"
+              style="height: 2em; padding: 0 2em"
+              native-type="submit"
+              >{{ $t("device.clickSearch") }}</van-button
+            >
           </van-row>
         </van-form>
       </div>
@@ -137,8 +180,8 @@
 </template>
 
 <script>
-import { ref, onMounted } from 'vue';
-import { useI18n } from 'vue-i18n';
+import { ref, onMounted } from "vue";
+import { useI18n } from "vue-i18n";
 import { getLoginUser, styleUrl } from "../../common/js/utils";
 import { Api_getLabelList } from "../../service/labelMan";
 
@@ -146,17 +189,17 @@ export default {
   setup(prop, context) {
     const { t } = useI18n();
     const sheetShow = ref(false);
-    const clientId = ref(''); // 设备唯一码_设备编号
-    const equipmentName = ref(''); // 设备名称_机器名
-    const adminName = ref(''); // 商家名
-    const areaName = ref(''); // 设备所在地_地址名
-    const machineType = ref(''); // 设备类型
-    const machineTypeText = ref(''); // 设备类型 - 页面显示
+    const clientId = ref(""); // 设备唯一码_设备编号
+    const equipmentName = ref(""); // 设备名称_机器名
+    const adminName = ref(""); // 商家名
+    const areaName = ref(""); // 设备所在地_地址名
+    const machineType = ref(""); // 设备类型
+    const machineTypeText = ref(""); // 设备类型 - 页面显示
     const machineTypeShow = ref(false); // 设备类型级联状态
-    const companyType = ref(''); // 公司平台
-    const deviceGroup = ref(''); // 设备分组
-    const companyTypeText = ref(''); // 公司平台 - 页面显示
-    const deviceGroupText = ref(''); // 设备分组 - 页面显示
+    const companyType = ref(""); // 公司平台
+    const deviceGroup = ref(""); // 设备分组
+    const companyTypeText = ref(""); // 公司平台 - 页面显示
+    const deviceGroupText = ref(""); // 设备分组 - 页面显示
     const companyTypeShow = ref(false); // 公司平台级联状态
     const deviceGroupShow = ref(false); // 设备分组级联状态
     const user = getLoginUser(); // 获取登录用户
@@ -164,40 +207,90 @@ export default {
 
     const machineTypeOptions = ref([
       {
-        text: t('device.spunSugar'),
-        value: '0',
+        text: t("device.spunSugar"),
+        value: "0",
       },
       {
-        text: t('device.popcorn'),
-        value: '1',
+        text: t("device.popcorn"),
+        value: "1",
       },
       {
-        text: t('device.iceCream'),
-        value: '2',
-      }
+        text: t("device.iceCream"),
+        value: "2",
+      },
     ]); // 设备类型级联选项
     const companyTypeOptions = ref([
       {
-        text: t('device.sz'),
-        value: '0',
+        text: t("device.sz"),
+        value: "0",
       },
       {
-        text: t('device.sc'),
-        value: '1',
-      }
+        text: t("device.sc"),
+        value: "1",
+      },
     ]);
 
-
     const deviceGroupOptions = ref([]);
 
     const machineTypeFinish = ({ selectedOptions }) => {
       machineTypeShow.value = false;
-      machineTypeText.value = selectedOptions.map((option) => option.text).join('/');
+      machineTypeText.value = selectedOptions
+        .map((option) => option.text)
+        .join("/");
+      // console.log("machineType >>>", machineType.value);
+      if (machineType.value === "0") {
+        equimentTypeOptions.value = [
+          {
+            text: "MG330",
+            value: "MG330",
+          },
+          {
+            text: "MG320",
+            value: "MG320",
+          },
+          {
+            text: "MG301",
+            value: "MG301",
+          },
+          {
+            text: "MG280",
+            value: "MG280",
+          },
+        ];
+      } else if (machineType.value === "1") {
+        equimentTypeOptions.value = [
+          {
+            text: "P10",
+            value: "P10",
+          },
+          {
+            text: "P20",
+            value: "P20",
+          },
+          {
+            text: "P30",
+            value: "P30",
+          },
+          {
+            text: "SBM10",
+            value: "SBM10",
+          },
+        ];
+      } else if (machineType.value === "2") {
+        equimentTypeOptions.value = [
+          {
+            text: "SI320",
+            value: "SI320",
+          },
+        ];
+      }
     }; // 设备类型级联选择
 
     const companyTypeFinish = ({ selectedOptions }) => {
       companyTypeShow.value = false;
-      companyTypeText.value = selectedOptions.map((option) => option.text).join('/');
+      companyTypeText.value = selectedOptions
+        .map((option) => option.text)
+        .join("/");
     }; // 公司平台级联选择
 
     // const deviceGroupFinish = async ({ selectedOptions }) => {
@@ -208,25 +301,25 @@ export default {
     //   deviceGroupText.value = selectedOptions.map((option) => option.text).join('/');
     // }; // 设备分组级联选择
 
-    const equimentType = ref(''); // 设备机型
-    const equimentTypeText = ref(''); // 设备机型 - 页面显示
+    const equimentType = ref(""); // 设备机型
+    const equimentTypeText = ref(""); // 设备机型 - 页面显示
     const equimentTypeShow = ref(false); // 设备机型级联状态
     const equimentTypeOptions = ref([
       {
-        text: 'MG330',
-        value: 'MG330',
+        text: "MG330",
+        value: "MG330",
       },
       {
-        text: 'MG320',
-        value: 'MG320',
+        text: "MG320",
+        value: "MG320",
       },
       {
-        text: 'MG301',
-        value: 'MG301',
+        text: "MG301",
+        value: "MG301",
       },
       {
-        text: 'MG280',
-        value: 'MG280',
+        text: "MG280",
+        value: "MG280",
       },
       {
         text: "P10",
@@ -237,94 +330,110 @@ export default {
         value: "P20",
       },
       {
-        text: 'P30',
-        value: 'P30',
+        text: "P30",
+        value: "P30",
       },
       {
-        text: 'SI320',
-        value: 'SI320',
-      }
+        text: "SI320",
+        value: "SI320",
+      },
+      {
+        text: "SBM10",
+        value: "SBM10",
+      },
     ]); // 设备机型级联选项
     const equimentTypeFinish = ({ selectedOptions }) => {
       equimentTypeShow.value = false;
-      equimentTypeText.value = selectedOptions.map((option) => option.text).join('/');
+      equimentTypeText.value = selectedOptions
+        .map((option) => option.text)
+        .join("/");
     }; // 设备机型级联选择
 
-    const eqeStatus = ref(''); // 开机状态
-    const eqeStatusText = ref(''); // 开机状态 - 页面显示
+    const eqeStatus = ref(""); // 开机状态
+    const eqeStatusText = ref(""); // 开机状态 - 页面显示
     const eqeStatusShow = ref(false); // 开机状态级联状态
     const eqeStatusOptions = ref([
       {
-        text: t('device.startUp'),
-        value: '1',
+        text: t("device.startUp"),
+        value: "1",
       },
       {
-        text: t('device.shutdown'),
-        value: '0',
-      }
+        text: t("device.shutdown"),
+        value: "0",
+      },
     ]); // 开机状态级联选项
     const eqeStatusFinish = ({ selectedOptions }) => {
       eqeStatusShow.value = false;
-      eqeStatusText.value = selectedOptions.map((option) => option.text).join('/');
+      eqeStatusText.value = selectedOptions
+        .map((option) => option.text)
+        .join("/");
     }; // 开机状态级联选择
 
-    const isUsing = ref(''); // 设备状态
-    const isUsingText = ref(''); // 设备状态 - 页面显示
+    const isUsing = ref(""); // 设备状态
+    const isUsingText = ref(""); // 设备状态 - 页面显示
     const isUsingShow = ref(false); // 设备状态级联状态
     const isUsingOptions = ref([
       {
-        text: t('device.enable'),
+        text: t("device.enable"),
         value: true,
       },
       {
-        text: t('device.deactivate'),
+        text: t("device.deactivate"),
         value: false,
-      }
+      },
     ]); // 设备状态级联选项
     const isUsingFinish = ({ selectedOptions }) => {
       isUsingShow.value = false;
-      isUsingText.value = selectedOptions.map((option) => option.text).join('/');
+      isUsingText.value = selectedOptions
+        .map((option) => option.text)
+        .join("/");
     }; // 设备状态级联选择
 
-    const payType = ref(''); // 支付方式
-    const payTypeText = ref(''); // 支付方式 - 页面显示
+    const payType = ref(""); // 支付方式
+    const payTypeText = ref(""); // 支付方式 - 页面显示
     const payTypeShow = ref(false); // 支付方式级联状态
     const payTypeOptions = ref([
       {
-        text: '支付方式1',
-        value: '0',
+        text: "支付方式1",
+        value: "0",
       },
       {
-        text: '支付方式2',
-        value: '1',
-      }
+        text: "支付方式2",
+        value: "1",
+      },
     ]); // 支付方式级联选项
     const payTypeFinish = ({ selectedOptions }) => {
       payTypeShow.value = false;
-      payTypeText.value = selectedOptions.map((option) => option.text).join('/');
+      payTypeText.value = selectedOptions
+        .map((option) => option.text)
+        .join("/");
     }; // 支付方式级联选择
 
-    const channel = ref(''); // 信道
-    const channelText = ref(''); // 信道 - 页面显示
+    const channel = ref(""); // 信道
+    const channelText = ref(""); // 信道 - 页面显示
     const channelShow = ref(false); // 信道级联状态
     const channelOptions = ref([
       {
-        text: '个推',
-        value: '1',
+        text: "个推",
+        value: "1",
       },
       {
-        text: 'Mq',
-        value: '2',
-      }
+        text: "Mq",
+        value: "2",
+      },
     ]); // 信道级联选项
     const channelFinish = ({ selectedOptions }) => {
       channelShow.value = false;
-      channelText.value = selectedOptions.map((option) => option.text).join('/');
+      channelText.value = selectedOptions
+        .map((option) => option.text)
+        .join("/");
     }; // 信道级联选择
 
     // channel 信道
     // 父组件页面触发展示及初始化
-    const showSearch = () => { sheetShow.value = true; };
+    const showSearch = () => {
+      sheetShow.value = true;
+    };
     // 提交搜索表单触发搜索
     const onSubmit = () => {
       const searchParam = {
@@ -341,31 +450,69 @@ export default {
         channel: channel.value,
         // labelId: labelId.value,
       };
-      context.emit('search', searchParam);
+      context.emit("search", searchParam);
       sheetShow.value = false;
-    }
+    };
     // 清空条件
     const registerClick = () => {
-      clientId.value = '';
-      equipmentName.value = '';
-      adminName.value = '';
-      areaName.value = '';
-      machineType.value = '';
-      machineTypeText.value = '';
-      companyType.value = '';
-      companyTypeText.value = '';
-      deviceGroup.value = '';
-      deviceGroupText.value = '';
-      equimentType.value = '';
-      equimentTypeText.value = '';
-      eqeStatus.value = '';
-      eqeStatusText.value = '';
-      isUsing.value = '';
-      isUsingText.value = '';
-      payType.value = '';
-      payTypeText.value = '';
-      channel.value = '';
-      channelText.value = '';
+      clientId.value = "";
+      equipmentName.value = "";
+      adminName.value = "";
+      areaName.value = "";
+      machineType.value = "";
+      machineTypeText.value = "";
+      companyType.value = "";
+      companyTypeText.value = "";
+      deviceGroup.value = "";
+      deviceGroupText.value = "";
+      equimentType.value = "";
+      equimentTypeText.value = "";
+      eqeStatus.value = "";
+      eqeStatusText.value = "";
+      isUsing.value = "";
+      isUsingText.value = "";
+      payType.value = "";
+      payTypeText.value = "";
+      channel.value = "";
+      channelText.value = "";
+      equimentTypeOptions.value = [
+        {
+          text: "MG330",
+          value: "MG330",
+        },
+        {
+          text: "MG320",
+          value: "MG320",
+        },
+        {
+          text: "MG301",
+          value: "MG301",
+        },
+        {
+          text: "MG280",
+          value: "MG280",
+        },
+        {
+          text: "P10",
+          value: "P10",
+        },
+        {
+          text: "P20",
+          value: "P20",
+        },
+        {
+          text: "P30",
+          value: "P30",
+        },
+        {
+          text: "SI320",
+          value: "SI320",
+        },
+        {
+          text: "SBM10",
+          value: "SBM10",
+        },
+      ];
     };
 
     onMounted(() => {
@@ -374,24 +521,25 @@ export default {
     });
     // 获取设备标签
     const getLabelList = async () => {
-      // console.log("adminId>>>>", user.id);
       Api_getLabelList({
         adminId: user.id,
-        type: "1"
+        type: "1",
       }).then((res) => {
         const { data } = res.data;
         deviceGroupOptions.value = data.map((label) => ({
           text: label.name,
           value: label.id,
         }));
-      })
-    }
+      });
+    };
 
     // 加载样式
-    styleUrl('deviceSearch');
+    styleUrl("deviceSearch");
 
     // 是否管理员
-    const isShowCompany = () => { return (user && user.type === 0); }
+    const isShowCompany = () => {
+      return user && user.type === 0;
+    };
 
     return {
       sheetShow,

+ 1 - 0
src/views/discountCode/payCode.vue

@@ -568,6 +568,7 @@ export default {
 
   .type-text {
     flex: 1;
+    width: 200px;
   }
 
   .type-title {

+ 467 - 102
src/views/taskMessage/equipment/index.vue

@@ -1,127 +1,220 @@
+复制
 <template>
-  <!-- 设备初始化审批 -->
-  <div class="taskMessagePage flex-col">
+  <div class="task-page">
+    <!-- 顶部导航 -->
     <s-header :name="$t('taskMessage.taskMessage')" :noback="false"></s-header>
-    <div class="taskMessageBox flex-col">
-      <van-list v-model:loading="loading" v-model:error="error" :error-text="$t('common.reqFailClkReload')"
-        :finished="finished" :finished-text="$t('common.noMoreTxt')" offset="300" :immediate-check="false"
-        @load="onLoad">
-        <div class="searchRow flex-row justify-between">
-          <div class="flex-col">
-            <div class="flex-row justify-between bd3">
-              <div class="flex-col outer4 equipmentIcon"></div>
-              <span class="flex-col txt2">{{ $t("taskMessage.total")
-                }}<span class="discountNumber">{{ alarmHistoryTotal }}</span>{{ $t("taskMessage.recordsInTotal")
-                }}</span>
+
+    <div class="task-container">
+      <van-list
+        v-model:loading="loading"
+        v-model:error="error"
+        :error-text="$t('common.reqFailClkReload')"
+        :finished="finished"
+        :finished-text="$t('common.noMoreTxt')"
+        offset="300"
+        :immediate-check="false"
+        @load="onLoad"
+      >
+        <!-- 顶部筛选和信息区域 -->
+        <div class="header-info">
+          <div class="total-card">
+            <div class="icon-box">
+              <van-icon name="todo-list" class="equipment-icon" />
+            </div>
+            <div class="total-info">
+              {{ $t("taskMessage.total") }}
+              <span class="highlight">{{ alarmHistoryTotal }}</span>
+              {{ $t("taskMessage.recordsInTotal") }}
             </div>
           </div>
 
-          <div class="l-flex-RC">
-            <!-- 查看待审批的申请 -->
-            <div @click="reviewedClk" class="label3 o-mr-30">
+          <div class="actions">
+            <van-button
+              round
+              size="small"
+              plain
+              class="action-btn"
+              @click="reviewedClk"
+            >
               {{ $t("taskMessage.toViewAppro") }}
-            </div>
-            <!-- 搜索图片 -->
-            <div @click="noticeClk" class="main5 l-flex-RC">
-              <img class="label2 o-mr-5" src="../../../assets/device/searchIcon.png" />
-            </div>
+            </van-button>
+            <van-button
+              round
+              size="small"
+              plain
+              class="action-btn"
+              @click="noticeClk"
+            >
+              <van-icon name="search" size="20" />
+            </van-button>
           </div>
-          
         </div>
-        <div class="listBox">
-          <div v-for="(item, index) in alarmHistoryList" :key="index" class="listItem">
-            <div class="itemBox">
-              <div class="itemRow">
-                <span class="itemTitle">{{ $t("taskMessage.affiliatedMerchants") }}:&nbsp;</span>{{ item.adminUserName
-                }}
-              </div>
-              <div class="itemRow">
-                <span class="itemTitle">{{ $t("taskMessage.equipmentNo") }}:&nbsp;</span>{{ item.clientId }}
-              </div>
-              <div class="itemRow">
-                <span class="itemTitle">{{ $t("taskMessage.managementSystemID") }}:&nbsp;</span>{{ item.managerId }}
-              </div>
-              <div class="itemRow" v-if="item.statusType === 1">
-                <span class="itemTitle">{{ $t("taskMessage.state") }}:&nbsp;</span><span style="color: red">{{
-                  showItemType(item.statusType)
-                }}</span>
+
+        <!-- 设备申请列表 -->
+        <div class="list-container">
+          <div
+            v-for="(item, index) in alarmHistoryList"
+            :key="index"
+            class="list-card"
+            :class="{
+              pending: item.statusType === 1,
+              rejected: item.statusType === 2,
+              approved: item.statusType === 3,
+            }"
+          >
+            <div class="card-header">
+              <div class="status-tag">
+                {{ showItemType(item.statusType) }}
               </div>
-              <div class="itemRow">
-                <span class="itemTitle">{{ $t("taskMessage.applicationTime") }}:&nbsp;</span>{{
-                  showDateTime(item.createDate) }}
+              <div class="time-label">
+                {{ $t("taskMessage.applicationTime") }}:
+                {{ showDateTime(item.createDate) }}
               </div>
-              <div class="itemRow" v-if="item.statusType !== 1">
-                <span class="itemTitle">{{ $t("taskMessage.approvalTime") }}:&nbsp;</span>{{
-                  showDateTime(item.modifyDate)
-                }}
+            </div>
+
+            <div class="card-content">
+              <div class="info-row">
+                <van-icon name="shop-o" class="row-icon" />
+                <div class="row-content">
+                  <span class="label"
+                    >{{ $t("taskMessage.affiliatedMerchants") }}:&nbsp;</span
+                  >
+                  <span class="value">{{ item.adminUserName }}</span>
+                </div>
               </div>
-              <div v-if="item.statusType === 1 && isOper" class="itemRow"
-                style="display: flex; justify-content: flex-end">
-                <van-button span="5" round type="primary" style="
-                      height: 2em;
-                      padding: 0 2em;
-                      margin: 0 1em;
-                      background: rgb(255 0 0 / 20%);
-                      color: #ff0000;
-                      border-color: #ff0000;
-                    " @click="changeStatusFun(item, 'unAgreed')">
-                  {{ $t("taskMessage.refuse") }}
-                </van-button>
-                <van-button span="5" round type="primary" style="
-                      height: 2em;
-                      padding: 0 2em;
-                      margin: 0 1em;
-                      background: rgb(25 137 250 / 20%);
-                      color: #1989fa;
-                    " @click="changeStatusFun(item, 'agreed')">
-                  {{ $t("taskMessage.agree") }}
-                </van-button>
+
+              <div class="info-row">
+                <van-icon name="setting-o" class="row-icon" />
+                <div class="row-content">
+                  <span class="label"
+                    >{{ $t("taskMessage.equipmentNo") }}:&nbsp;</span
+                  >
+                  <span class="value">{{ item.clientId }}</span>
+                </div>
               </div>
-              <div class="itemRow" style="display: flex; justify-content: flex-end">
-                <span v-if="item.statusType === 2" style="color: #ff0000">{{
-                  showItemType(item.statusType)
-                }}</span>
-                <span v-if="item.statusType === 3" style="color: #4fc08d">{{
-                  showItemType(item.statusType)
-                }}</span>
+
+              <div class="info-row">
+                <van-icon name="idcard" class="row-icon" />
+                <div class="row-content">
+                  <span class="label"
+                    >{{ $t("taskMessage.managementSystemID") }}:&nbsp;</span
+                  >
+                  <span class="value">{{ item.managerId }}</span>
+                </div>
               </div>
+
+              <template v-if="item.statusType !== 1">
+                <div class="info-row">
+                  <van-icon name="clock-o" class="row-icon" />
+                  <div class="row-content">
+                    <span class="label"
+                      >{{ $t("taskMessage.approvalTime") }}:&nbsp;</span
+                    >
+                    <span class="value">{{
+                      showDateTime(item.modifyDate)
+                    }}</span>
+                  </div>
+                </div>
+              </template>
+            </div>
+
+            <!-- 审批操作按钮 -->
+            <div v-if="item.statusType === 1 && isOper" class="card-actions">
+              <van-button
+                round
+                size="small"
+                class="reject-btn"
+                @click="changeStatusFun(item, 'unAgreed')"
+              >
+                <van-icon name="close" size="20" class="btn-icon" />
+                {{ $t("taskMessage.refuse") }}
+              </van-button>
+              <van-button
+                round
+                size="small"
+                class="approve-btn"
+                @click="changeStatusFun(item, 'agreed')"
+              >
+                <van-icon name="passed" size="20" class="btn-icon" />
+                {{ $t("taskMessage.agree") }}
+              </van-button>
             </div>
           </div>
         </div>
       </van-list>
     </div>
+
     <!-- 筛选弹窗 -->
-    <kDialog :dialogTitle="$t('taskMessage.equipmentInit.searchPop.title')"
-      :confirmBtnTxt="$t('taskMessage.equipmentInit.searchPop.filterBtn')" ref="kDialogRef" @confirmclk="confirmClk">
+    <kDialog
+      :dialogTitle="$t('taskMessage.equipmentInit.searchPop.title')"
+      :confirmBtnTxt="$t('taskMessage.equipmentInit.searchPop.filterBtn')"
+      ref="kDialogRef"
+      @confirmclk="confirmClk"
+    >
       <template #content>
-        <div class="cust_vantBorder">
-          <van-field clearable v-model="searchForm.equipmentNo" :placeholder="$t('taskMessage.equipmentInit.searchPop.equipmentNoPlace')
-            " :label="$t('taskMessage.equipmentInit.searchPop.equipmentNo')" />
-          <van-field clearable v-model="searchForm.managementSystemID" :placeholder="$t('taskMessage.equipmentInit.searchPop.managementSystemIDPlace')
-            " :label="$t('taskMessage.equipmentInit.searchPop.managementSystemID')
-              " />
-          <van-field clearable v-model="searchForm.merchantName" :placeholder="$t('taskMessage.equipmentInit.searchPop.merchantNamePlace')
-            " :label="$t('taskMessage.equipmentInit.searchPop.merchantName')" />
-          <van-field @click-input="busiInpClk" readonly clearable v-model="searchForm.stateName"
+        <div class="dialog-content">
+          <van-field
+            clearable
+            v-model="searchForm.equipmentNo"
+            :placeholder="
+              $t('taskMessage.equipmentInit.searchPop.equipmentNoPlace')
+            "
+            :label="$t('taskMessage.equipmentInit.searchPop.equipmentNo')"
+          />
+
+          <van-field
+            clearable
+            v-model="searchForm.managementSystemID"
+            :placeholder="
+              $t('taskMessage.equipmentInit.searchPop.managementSystemIDPlace')
+            "
+            :label="
+              $t('taskMessage.equipmentInit.searchPop.managementSystemID')
+            "
+          />
+
+          <van-field
+            clearable
+            v-model="searchForm.merchantName"
+            :placeholder="
+              $t('taskMessage.equipmentInit.searchPop.merchantNamePlace')
+            "
+            :label="$t('taskMessage.equipmentInit.searchPop.merchantName')"
+          />
+
+          <van-field
+            @click-input="busiInpClk"
+            readonly
+            clearable
+            v-model="searchForm.stateName"
             :placeholder="$t('taskMessage.equipmentInit.searchPop.statePlace')"
-            :label="$t('taskMessage.equipmentInit.searchPop.state')">
+            :label="$t('taskMessage.equipmentInit.searchPop.state')"
+          >
             <template #right-icon>
-              <div class="l-flex-RC">
-                <van-icon v-if="searchForm.stateName" @click="
-                  searchForm.stateName = '';
-                searchForm.state = '';
-                " class="o-mr-6" name="clear" />
-                <van-icon @click="busiInpClk" name="arrow-down" />
+              <div class="icon-container">
+                <van-icon
+                  v-if="searchForm.stateName"
+                  @click.stop="clearState"
+                  class="clear-icon"
+                  name="clear"
+                />
+                <van-icon @click.stop="busiInpClk" name="arrow-down" />
               </div>
             </template>
           </van-field>
         </div>
       </template>
     </kDialog>
+
     <!-- 状态选择框 -->
-    <van-popup v-model:show="busiPopShow" position="bottom">
-      <van-picker :title="$t('taskMessage.equipmentInit.searchPop.statePlace')" :columns="busiPopList"
-        :columns-field-names="busiPopFieldName" @confirm="busiPopConfirm" @cancel="busiPopShow = false" />
+    <van-popup v-model:show="busiPopShow" position="bottom" round>
+      <van-picker
+        :title="$t('taskMessage.equipmentInit.searchPop.statePlace')"
+        :columns="busiPopList"
+        :columns-field-names="busiPopFieldName"
+        @confirm="busiPopConfirm"
+        @cancel="busiPopShow = false"
+      />
     </van-popup>
   </div>
 </template>
@@ -131,17 +224,17 @@ import { onMounted, reactive, ref } from "vue";
 import sHeader from "@/components/SimpleHeader";
 import { getTaskEquipmentList, changeStatus } from "@/service/taskMessage";
 import { showSuccessToast, showFailToast } from "vant";
-import { getLoginUser, styleUrl } from "@/common/js/utils";
+import { getLoginUser } from "@/common/js/utils";
 import dateUtil from "@/utils/dateUtil";
 import kDialog from "@/components/commom/kDialog/index.vue";
 import { useI18n } from "vue-i18n";
-import { useRouter } from 'vue-router'
+import { useRouter } from "vue-router";
 
 export default {
   components: { sHeader, kDialog },
   setup() {
     const { t } = useI18n();
-    const router = useRouter()
+    const router = useRouter();
     // 筛选弹窗
     const busiPopList = reactive([
       {
@@ -293,8 +386,6 @@ export default {
     const isOper = ref(true);
     // 初始化页面获取列表
     onMounted(async () => {
-      // 加载样式
-      styleUrl('taskMessage');
       if (user) {
         searchParams.adminId = user.id;
         searchGetList();
@@ -331,5 +422,279 @@ export default {
 </script>
 
 <style lang="less" scoped>
-@import "../../../common/style/common.less";
-</style>
+@theme-color: #4d6add;
+@pending-color: #ff9800;
+@approved-color: #4caf50;
+@rejected-color: #f44336;
+@light-bg: #f5f8ff;
+@card-shadow: 0 3px 10px rgba(77, 106, 221, 0.15);
+@hover-shadow: 0 8px 15px rgba(77, 106, 221, 0.2);
+@transition: all 0.3s ease;
+@text-dark: #333;
+@text-light: #666;
+@text-lighter: #999;
+@border-radius: 12px;
+
+.task-page {
+  display: flex;
+  flex-direction: column;
+  height: 100vh;
+  background-color: @light-bg;
+}
+
+.task-container {
+  flex: 1;
+  padding: 15px;
+  overflow-y: auto;
+}
+
+.header-info {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 20px;
+  padding: 12px 15px;
+  background: white;
+  border-radius: @border-radius;
+  box-shadow: @card-shadow;
+}
+
+.total-card {
+  display: flex;
+  align-items: center;
+}
+
+.icon-box {
+  width: 40px;
+  height: 40px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  background-color: fade(@theme-color, 8%);
+  border-radius: 10px;
+  margin-right: 12px;
+
+  .equipment-icon {
+    color: @theme-color;
+    font-size: 24px;
+  }
+}
+
+.total-info {
+  font-size: 12px;
+  color: @text-dark;
+
+  .highlight {
+    color: @theme-color;
+    font-size: 15px;
+    font-weight: bold;
+    margin: 0 3px;
+  }
+}
+
+.actions {
+  display: flex;
+  gap: 10px;
+}
+
+.action-btn {
+  height: 32px;
+  padding: 0 12px;
+  border-color: fade(@theme-color, 50%);
+  color: @theme-color;
+
+}
+
+.list-container {
+  display: flex;
+  flex-direction: column;
+  gap: 15px;
+}
+
+.list-card {
+  background: white;
+  border-radius: @border-radius;
+  box-shadow: @card-shadow;
+  padding: 16px;
+  transition: @transition;
+  position: relative;
+  overflow: hidden;
+
+  &.pending {
+    border-left: 3px solid @pending-color;
+
+    .status-tag {
+      background-color: fade(@pending-color, 15%);
+      color: darken(@pending-color, 10%);
+    }
+  }
+
+  &.approved {
+    border-left: 3px solid @approved-color;
+
+    .status-tag {
+      background-color: fade(@approved-color, 15%);
+      color: darken(@approved-color, 10%);
+    }
+  }
+
+  &.rejected {
+    border-left: 3px solid @rejected-color;
+
+    .status-tag {
+      background-color: fade(@rejected-color, 15%);
+      color: darken(@rejected-color, 10%);
+    }
+  }
+
+  &:hover {
+    transform: translateY(-2px);
+    box-shadow: @hover-shadow;
+  }
+}
+
+.card-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 15px;
+  padding-bottom: 12px;
+  border-bottom: 1px solid fade(@theme-color, 10%);
+}
+
+.status-tag {
+  padding: 4px 10px;
+  border-radius: 30px;
+  font-size: 13px;
+  font-weight: 600;
+  min-width: 60px;
+  text-align: center;
+}
+
+.time-label {
+  font-size: 12px;
+  color: @text-lighter;
+}
+
+.card-content {
+  display: flex;
+  flex-direction: column;
+  gap: 12px;
+}
+
+.info-row {
+  display: flex;
+  align-items: flex-start;
+
+  .row-icon {
+    flex-shrink: 0;
+    font-size: 18px;
+    color: @theme-color;
+    margin-right: 10px;
+    margin-top: 2px;
+  }
+
+  .row-content {
+    flex: 1;
+    font-size: 14px;
+  }
+
+  .label {
+    color: @text-light;
+    min-width: 90px;
+    display: inline-block;
+  }
+
+  .value {
+    color: @text-dark;
+    word-break: break-all;
+  }
+}
+
+.card-actions {
+  display: flex;
+  justify-content: flex-end;
+  gap: 15px;
+  margin-top: 15px;
+  padding-top: 15px;
+  border-top: 1px dashed fade(@theme-color, 15%);
+
+  .reject-btn,
+  .approve-btn {
+    min-width: 90px;
+    height: 34px;
+    padding: 0 15px;
+    font-size: 13px;
+
+    .btn-icon {
+      vertical-align: -2px;
+      margin-right: 5px;
+    }
+  }
+
+  .reject-btn {
+    border-color: fade(@rejected-color, 50%);
+    color: @rejected-color;
+    background-color: fade(@rejected-color, 8%);
+  }
+
+  .approve-btn {
+    border-color: fade(@approved-color, 50%);
+    color: @approved-color;
+    background-color: fade(@approved-color, 8%);
+  }
+}
+
+.dialog-content {
+  padding: 10px 0;
+
+  :deep(.van-cell) {
+    padding: 12px 0;
+    border-bottom: 1px solid rgba(0, 0, 0, 0.05);
+  }
+}
+
+.icon-container {
+  display: flex;
+  align-items: center;
+
+  .clear-icon {
+    color: #999;
+    margin-right: 8px;
+  }
+}
+
+/* 空状态样式 */
+.empty-list {
+  text-align: center;
+  padding: 40px 20px;
+
+  .empty-icon {
+    font-size: 80px;
+    color: fade(@theme-color, 20%);
+    margin-bottom: 15px;
+  }
+
+  .empty-text {
+    color: @text-light;
+    font-size: 16px;
+  }
+}
+
+/* 动画效果 */
+@keyframes cardEntry {
+  0% {
+    transform: translateY(15px);
+    opacity: 0;
+  }
+  100% {
+    transform: translateY(0);
+    opacity: 1;
+  }
+}
+
+.list-card {
+  animation: cardEntry 0.4s ease-out forwards;
+  opacity: 0;
+}
+</style>

+ 266 - 29
src/views/taskMessage/index.vue

@@ -1,30 +1,99 @@
 <template>
-  <!-- 任务消息列表 -->
-  <div class="taskMessagePage flex-col">
+  <div class="task-message-page">
     <s-header :name="$t('taskMessage.taskMessage')" :noback="false"></s-header>
-    <div class="taskMessageBox flex-col">
-      <div class="taskListRow flex-col" @click="pushPageList('/taskEquipment')">
-        <div class="taskIcon deviceIcon"></div>
-        <div class="taskRight">
-          <div class="taskTitle">{{ $t('taskMessage.equipmentInitializationApproval') }}</div>
+    
+    <div class="task-message-container">
+      <div class="task-list">
+        <!-- 设备初始化审批 -->
+        <div 
+          class="task-card" 
+          :class="{'glow-effect': hoverIndex === 0}"
+          @mouseover="hoverIndex = 0"
+          @mouseleave="hoverIndex = -1"
+          @click="pushPageList('/taskEquipment')"
+        >
+          <div class="card-content">
+            <div class="icon-container" :style="{ backgroundColor: lightenColor('#4d6add', 80) }">
+              <van-icon name="setting" class="task-icon" color="#4d6add" />
+            </div>
+            <div class="task-info">
+              <div class="task-title">{{ $t('taskMessage.equipmentInitializationApproval') }}</div>
+
+            </div>
+            <div class="badge-icon">
+              <van-icon name="arrow" color="#4d6add" size="18" />
+            </div>
+          </div>
+          <div class="task-progress" :style="{ width: '100%' }"></div>
         </div>
-      </div>
-      <div v-if="user.ifForeign != '1'" class="taskListRow flex-col" @click="pushPageList('/taskProportion')">
-        <div class="taskIcon retailIcon"></div>
-        <div class="taskRight">
-          <div class="taskTitle">{{ $t('taskMessage.distributionApplicationApproval') }}</div>
+        
+        <!-- 分销申请审批 -->
+        <div 
+          v-if="user.ifForeign != '1'" 
+          class="task-card" 
+          :class="{'glow-effect': hoverIndex === 1}"
+          @mouseover="hoverIndex = 1"
+          @mouseleave="hoverIndex = -1"
+          @click="pushPageList('/taskProportion')"
+        >
+          <div class="card-content">
+            <div class="icon-container" :style="{ backgroundColor: lightenColor('#4d6add', 80) }">
+              <van-icon name="cluster" class="task-icon" color="#4d6add" />
+            </div>
+            <div class="task-info">
+              <div class="task-title">{{ $t('taskMessage.distributionApplicationApproval') }}</div>
+            </div>
+            <div class="badge-icon">
+              <van-icon name="arrow" color="#4d6add" size="18" />
+            </div>
+          </div>
+          <div class="task-progress" :style="{ width: '100%' }"></div>
         </div>
-      </div>
-      <div v-if="user.type < 2" class="taskListRow flex-col" @click="pushPageList('/refundReminder')">
-        <div class="taskIcon refundIcon"></div>
-        <div class="taskRight">
-          <div class="taskTitle">{{ $t('taskMessage.refundRemind') }}</div>
+        
+        <!-- 退款提醒 -->
+        <div 
+          v-if="user.type < 2" 
+          class="task-card" 
+          :class="{'glow-effect': hoverIndex === 2}"
+          @mouseover="hoverIndex = 2"
+          @mouseleave="hoverIndex = -1"
+          @click="pushPageList('/refundReminder')"
+        >
+          <div class="card-content">
+            <div class="icon-container" :style="{ backgroundColor: lightenColor('#4d6add', 80) }">
+              <van-icon name="balance-list" class="task-icon" color="#4d6add" />
+            </div>
+            <div class="task-info">
+              <div class="task-title">{{ $t('taskMessage.refundRemind') }}</div>
+            </div>
+            <div class="badge-icon">
+              <van-icon name="arrow" color="#4d6add" size="18" />
+            </div>
+          </div>
+          <div class="task-progress" :style="{ width: '100%' }"></div>
         </div>
-      </div>
-      <div v-if="user.type == 0 || user.type == 2 || user.type == 3" class="taskListRow flex-col" @click="pushPageList('/toDaySugarList')">
-        <div class="taskIcon makeIcon"></div>
-        <div class="taskRight">
-          <div class="taskTitle">{{ $t('device.todaysSugarList') }}</div>
+        
+        <!-- 今日糖单 -->
+        <div 
+          v-if="user.type == 0 || user.type == 2 || user.type == 3" 
+          class="task-card" 
+          :class="{'glow-effect': hoverIndex === 3}"
+          @mouseover="hoverIndex = 3"
+          @mouseleave="hoverIndex = -1"
+          @click="pushPageList('/toDaySugarList')"
+        >
+          <div class="card-content">
+            <div class="icon-container" :style="{ backgroundColor: lightenColor('#4d6add', 80) }">
+              <van-icon name="notes" class="task-icon" color="#4d6add" />
+            </div>
+            <div class="task-info">
+              <div class="task-title">{{ $t('device.todaysSugarList') }}</div>
+            </div>
+            <div class="badge-icon">
+              <van-icon name="arrow" color="#4d6add" size="18" />
+            </div>
+          </div>
+          <div class="task-progress" :style="{ width: '100%' }"></div>
         </div>
       </div>
     </div>
@@ -32,28 +101,196 @@
 </template>
 
 <script>
-import { onMounted } from 'vue';
+import { onMounted, ref } from "vue";
 import sHeader from "@/components/SimpleHeader";
 import { useRouter } from "vue-router";
-import { getLoginUser, styleUrl } from "../../common/js/utils";
+import { getLoginUser } from "../../common/js/utils";
 
 export default {
   components: { sHeader },
   setup() {
     const router = useRouter();
     const user = getLoginUser();
+    // 状态控制
+    const hoverIndex = ref(-1);
     // 初始化页面获取列表
     onMounted(async () => {
-      styleUrl('taskMessage');
     });
+    const lightenColor = (hex, percent) => {
+      console.log(hex, percent);
+      return '#e6f0ff';
+    };
     const pushPageList = (url) => {
       router.push(url);
-    }
-    return { pushPageList, user };
-  }
+    };
+    return { pushPageList, user, hoverIndex, lightenColor };
+  },
 };
 </script>
 
 <style lang="less" scoped>
-@import "../../common/style/common.less";
+@theme-color: #4d6add;
+@light-bg: #f5f8ff;
+@card-shadow: 0 4px 12px rgba(77, 106, 221, 0.15);
+@hover-shadow: 0 8px 24px rgba(77, 106, 221, 0.25);
+@transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
+@text-dark: #333;
+@text-light: #666;
+@card-radius: 16px;
+
+.task-message-page {
+  display: flex;
+  flex-direction: column;
+  height: 100vh;
+  background-color: @light-bg;
+  font-family: 'PingFang SC', 'Helvetica Neue', Arial, sans-serif;
+  
+  .task-message-container {
+    flex: 1;
+    display: flex;
+    flex-direction: column;
+    padding: 16px;
+    overflow-y: auto;
+    
+    .task-list {
+      flex: 1;
+      display: flex;
+      flex-direction: column;
+      gap: 16px;
+      margin-bottom: 20px;
+    }
+  }
+}
+
+/* 任务卡片样式 */
+.task-card {
+  background: white;
+  border-radius: @card-radius;
+  box-shadow: @card-shadow;
+  padding: 18px 16px;
+  position: relative;
+  overflow: hidden;
+  transition: @transition;
+  cursor: pointer;
+  border: 1px solid rgba(77, 106, 221, 0.1);
+  
+  &:hover {
+    transform: translateY(-4px);
+    box-shadow: @hover-shadow;
+    border-color: rgba(77, 106, 221, 0.3);
+    
+    .badge-icon {
+      transform: translateX(5px);
+    }
+  }
+  
+  &.glow-effect {
+    border-color: rgba(77, 106, 221, 0.5);
+    background-color: rgba(77, 106, 221, 0.03);
+  }
+  
+  .card-content {
+    display: flex;
+    align-items: center;
+    position: relative;
+    z-index: 2;
+  }
+  
+  .icon-container {
+    width: 54px;
+    height: 54px;
+    border-radius: 14px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    flex-shrink: 0;
+    transition: @transition;
+    
+    .task-icon {
+      font-size: 24px;
+    }
+  }
+  
+  .task-info {
+    flex: 1;
+    margin-left: 16px;
+    margin-right: 10px;
+    overflow: hidden;
+    
+    .task-title {
+      font-size: 17px;
+      font-weight: 600;
+      color: @text-dark;
+      margin-bottom: 5px;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      white-space: nowrap;
+    }
+  
+  }
+  
+  .badge-icon {
+    width: 30px;
+    height: 30px;
+    background-color: fade(@theme-color, 10%);
+    border-radius: 50%;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    transition: @transition;
+  }
+  
+  .task-progress {
+    position: absolute;
+    bottom: 0;
+    left: 0;
+    height: 3px;
+    background: linear-gradient(90deg, @theme-color, lighten(@theme-color, 20%));
+    border-bottom-left-radius: @card-radius;
+    transition: all 0.8s cubic-bezier(0.22, 0.61, 0.36, 1);
+  }
+}
+
+/* 动画效果 */
+@keyframes cardEntry {
+  0% { transform: translateY(20px); opacity: 0; }
+  100% { transform: translateY(0); opacity: 1; }
+}
+
+.task-card {
+  animation: cardEntry 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards;
+  opacity: 0;
+  
+  &:nth-child(1) { animation-delay: 0.1s; }
+  &:nth-child(2) { animation-delay: 0.2s; }
+  &:nth-child(3) { animation-delay: 0.3s; }
+  &:nth-child(4) { animation-delay: 0.4s; }
+}
+
+/* 响应式设计 */
+@media (max-width: 480px) {
+  .task-message-container {
+    padding: 12px;
+  }
+  
+  .task-card {
+    padding: 16px 14px;
+    
+    .icon-container {
+      width: 50px;
+      height: 50px;
+      
+      .task-icon {
+        font-size: 22px;
+      }
+    }
+    
+    .task-info {
+      .task-title {
+        font-size: 16px;
+      }
+    }
+  }
+
+}
 </style>

+ 648 - 117
src/views/taskMessage/proportion/index.vue

@@ -1,109 +1,241 @@
 <template>
-  <!-- 分销申请审批 -->
-  <div class="taskMessagePage flex-col">
-    <s-header :name="$t('taskMessage.distributionApplicationApproval')" :noback="false"></s-header>
-    <div class="taskMessageBox flex-col">
-      <van-list v-model:loading="loading" v-model:error="error" :error-text="$t('common.reqFailClkReload')"
-        :finished="finished" :finished-text="$t('common.noMoreTxt')" offset="300" :immediate-check="false" @load="onLoad">
-        <div class="searchRow flex-row justify-between">
-          <div class="flex-col">
-            <div class="flex-row justify-between bd3">
-              <div class="flex-col outer4 proportionIcon"></div>
-              <span class="flex-col txt2">{{ $t('taskMessage.total') }}<span class="discountNumber">{{ alarmHistoryTotal
-              }}</span>{{ $t('taskMessage.recordsInTotal') }}</span>
+  <div class="task-page">
+    <!-- 顶部导航 -->
+    <s-header
+      :name="$t('taskMessage.distributionApplicationApproval')"
+      :noback="false"
+    ></s-header>
+
+    <div class="task-container">
+      <van-list
+        v-model:loading="loading"
+        v-model:error="error"
+        :error-text="$t('common.reqFailClkReload')"
+        :finished="finished"
+        :finished-text="$t('common.noMoreTxt')"
+        offset="300"
+        :immediate-check="false"
+        @load="onLoad"
+      >
+        <!-- 顶部筛选和信息区域 -->
+        <div class="header-info">
+          <div class="total-card">
+            <div class="icon-box">
+              <van-icon name="todo-list" class="dist-icon" />
             </div>
-          </div>
-          <div class="l-flex-RC">
-            <div @click="reviewedClk" class="label3 o-mr-10">{{
-              $t('taskMessage.toViewAppro')
-            }}</div>
-            <div @click="noticeClk" class="main5 l-flex-RC">
-              <img class="label2 o-mr-5" src="../../../assets/device/searchIcon.png" />
+            <div class="total-info">
+              {{ $t("taskMessage.total") }}
+              <span class="highlight">{{ alarmHistoryTotal }}</span>
+              {{ $t("taskMessage.recordsInTotal") }}
             </div>
           </div>
+
+          <div class="actions">
+            <van-button
+              round
+              size="small"
+              plain
+              class="action-btn"
+              @click="reviewedClk"
+            >
+              {{ $t("taskMessage.toViewAppro") }}
+            </van-button>
+            <van-button
+              round
+              size="small"
+              plain
+              class="action-btn"
+              @click="noticeClk"
+            >
+              <van-icon name="search" size="20" />
+            </van-button>
+          </div>
         </div>
-        <div class="listBox">
-          <div v-for="(item, index) in alarmHistoryList" :key="index" class="listItem">
-            <div class="itemBox">
-              <div class="itemRow">
-                <span class="itemTitle">{{ $t('taskMessage.equipmentName') }}:&nbsp;</span>
-                {{ item.equipmentName != null ? item.equipmentName : item.clientId.slice(-6) }}
-              </div>
-              <div class="itemRow">
-                <span class="itemTitle">{{ $t('taskMessage.equipmentNo') }}:&nbsp;</span>
-                {{ item.clientId }}
-              </div>
-              <!-- 机主的 -->
-              <div class="itemRow">
-                <span class="itemTitle">{{ $t('taskMessage.owner') }}:&nbsp;</span>
-                {{ $t('taskMessage.machineOwner') }}
-                <span class="itemTitle discount">{{ $t('taskMessage.proportion') }}:&nbsp;</span>
-                {{ item.proportion }}%
-              </div>
-              <!-- 平台的 -->
-              <div class="itemRow">
-                <span class="itemTitle">{{ $t('taskMessage.platform') }}:&nbsp;</span>
-                {{ $t('taskMessage.platformAccount') }}
-                <span class="itemTitle discount">{{ $t('taskMessage.proportion') }}:&nbsp;</span>
-                {{ item.adminProportion }}%
-              </div>
-              <!-- 分账方的 -->
-              <div class="itemRow" v-if="item.type >= 1">
-                <span class="itemTitle">{{ $t('taskMessage.partners') }}:&nbsp;</span>
-                {{ item.agencyName }}
-                <span class="itemTitle discount">{{ $t('taskMessage.proportion') }}:&nbsp;</span>
-                {{ item.agencyProportion }}%
-              </div>
-              <!-- 分账方4个 -->
-              <div class="itemRow" v-if="item.type >= 2">
-                <span class="itemTitle">{{ $t('taskMessage.partners') }}:&nbsp;</span>
-                {{ item.merchantName }}
-                <span class="itemTitle discount">{{ $t('taskMessage.proportion') }}:&nbsp;</span>
-                {{ item.merchantProportion }}%
-              </div>
-              <!-- 分账方5个以上 -->
-              <div class="itemRow" v-if="item.type >= 3">
-                <span class="itemTitle">{{ $t('taskMessage.partners') }}:&nbsp;</span>
-                {{ item.personageNam }}
-                <span class="itemTitle discount">{{ $t('taskMessage.proportion') }}:&nbsp;</span>
-                {{ item.personageProportion }}%
+
+        <!-- 分销申请列表 -->
+        <div class="list-container">
+          <div
+            v-for="(item, index) in alarmHistoryList"
+            :key="index"
+            class="list-card"
+            :class="{
+              pending: item.checkType === '0',
+              approved: item.checkType === '1',
+              cancelled: item.checkType === '2',
+              rejected: item.checkType === '3',
+            }"
+          >
+            <div class="card-header">
+              <div class="status-tag">
+                {{ getStatusText(item.checkType) }}
               </div>
-              <div class="itemRow">
-                <span class="itemTitle">{{ $t('taskMessage.applicationTime') }}:&nbsp;</span>
+              <div class="time-label">
+                {{ $t("taskMessage.applicationTime") }}:
                 {{ showDateTime(item.createDate) }}
               </div>
-              <div class="itemRow" v-if="item.checkType !== '0'">
-                <span class="itemTitle">{{ $t('taskMessage.approvalTime') }}:&nbsp;</span>
-                {{ showDateTime(item.modifyDate) }}
+            </div>
+
+            <div class="card-content">
+              <!-- 设备信息 -->
+              <div class="info-row">
+                <van-icon name="setting-o" class="row-icon" />
+                <div class="row-content">
+                  <span class="label"
+                    >{{ $t("taskMessage.equipmentNo") }}:&nbsp;</span
+                  >
+                  <span class="value">{{ item.clientId }}</span>
+                </div>
               </div>
-              <div class="itemRow" style="display: flex; justify-content: flex-end"
-                v-if="item.checkType === '0' && isOper">
-                <van-button span="5" round type="primary" style="
-                      height: 2em;
-                      padding: 0 1em;
-                      margin: 0 0.5em;
-                      background: rgb(255 0 0 / 20%);
-                      color: #ff0000;
-                      border-color: #ff0000;
-                    " @click="changeStatusFun(item, 3)">
-                  {{ $t('taskMessage.fail') }}
-                </van-button>
-                <van-button span="5" round type="primary" style="
-                      height: 2em;
-                      padding: 0 1em;
-                      margin: 0 0.5em;
-                      background: rgb(25 137 250 / 20%);
-                      color: #1989fa;
-                    " @click="changeStatusFun(item, 1)">
-                  {{ $t('taskMessage.adopt') }}
-                </van-button>
+
+              <div class="info-row">
+                <van-icon name="idcard" class="row-icon" />
+                <div class="row-content">
+                  <span class="label"
+                    >{{ $t("taskMessage.equipmentName") }}:&nbsp;</span
+                  >
+                  <span class="value">{{
+                    item.equipmentName || item.clientId.slice(-6)
+                  }}</span>
+                </div>
               </div>
-              <div class="itemRow" style="display: flex; justify-content: flex-end">
-                <span v-if="item.checkType === '0' && (user.type > 1 && user.type < 4)" style="color: #FFA500"> {{ $t('taskMessage.toBeApproved') }}</span>
-                <span v-if="item.checkType === '1'" style="color: #1989fa"> {{ $t('taskMessage.adopt') }}</span>
-                <span v-if="item.checkType === '2'" style="color: #ff0033"> {{ $t('taskMessage.cancel') }}</span>
-                <span v-if="item.checkType === '3'" style="color: #ff0000"> {{ $t('taskMessage.fail') }}</span>
+
+              <!-- 分账比例 -->
+              <div class="dist-grid">
+                <!-- 固定分账方 -->
+                <div class="dist-section">
+                  <div class="dist-item">
+                    <div class="dist-icon-box">
+                      <van-icon name="user-o" class="dist-icon" />
+                    </div>
+                    <div class="dist-info">
+                      <div class="dist-title">
+                        {{ $t("taskMessage.owner") }}
+                      </div>
+                      <div class="dist-content">
+                        <span class="dist-name">{{
+                          $t("taskMessage.machineOwner")
+                        }}</span>
+                        <span class="dist-percent">{{ item.proportion }}%</span>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+                <div class="dist-section">
+                  <div class="dist-item">
+                    <div class="dist-icon-box">
+                      <van-icon name="label-o" class="dist-icon" />
+                    </div>
+                    <div class="dist-info">
+                      <div class="dist-title">
+                        {{ $t("taskMessage.platform") }}
+                      </div>
+                      <div class="dist-content">
+                        <span class="dist-name">{{
+                          $t("taskMessage.platformAccount")
+                        }}</span>
+                        <span class="dist-percent"
+                          >{{ item.adminProportion }}%</span
+                        >
+                      </div>
+                    </div>
+                  </div>
+                </div>
+
+                <!-- 动态分账方 -->
+                <div class="dist-section" v-if="item.type >= 1">
+                  <div class="dist-item">
+                    <div class="dist-icon-box">
+                      <van-icon name="friends-o" class="dist-icon" />
+                    </div>
+                    <div class="dist-info">
+                      <div class="dist-title">
+                        {{ $t("taskMessage.partners") }}
+                      </div>
+                      <div class="dist-content">
+                        <span class="dist-name">{{ item.agencyName }}</span>
+                        <span class="dist-percent"
+                          >{{ item.agencyProportion }}%</span
+                        >
+                      </div>
+                    </div>
+                  </div>
+                </div>
+
+                <div class="dist-section" v-if="item.type >= 2">
+                  <div class="dist-item">
+                    <div class="dist-icon-box">
+                      <van-icon name="friends-o" class="dist-icon" />
+                    </div>
+                    <div class="dist-info">
+                      <div class="dist-title">
+                        {{ $t("taskMessage.partners") }}
+                      </div>
+                      <div class="dist-content">
+                        <span class="dist-name">{{ item.merchantName }}</span>
+                        <span class="dist-percent"
+                          >{{ item.merchantProportion }}%</span
+                        >
+                      </div>
+                    </div>
+                  </div>
+                </div>
+
+                <div class="dist-section" v-if="item.type >= 3">
+                  <div class="dist-item">
+                    <div class="dist-icon-box">
+                      <van-icon name="friends-o" class="dist-icon" />
+                    </div>
+                    <div class="dist-info">
+                      <div class="dist-title">
+                        {{ $t("taskMessage.partners") }}
+                      </div>
+                      <div class="dist-content">
+                        <span class="dist-name">{{ item.personageNam }}</span>
+                        <span class="dist-percent"
+                          >{{ item.personageProportion }}%</span
+                        >
+                      </div>
+                    </div>
+                  </div>
+                </div>
               </div>
+
+              <!-- 审批时间 -->
+              <template v-if="item.checkType !== '0'">
+                <div class="info-row">
+                  <van-icon name="clock-o" class="row-icon" />
+                  <div class="row-content">
+                    <span class="label"
+                      >{{ $t("taskMessage.approvalTime") }}:&nbsp;</span
+                    >
+                    <span class="value">{{
+                      showDateTime(item.modifyDate)
+                    }}</span>
+                  </div>
+                </div>
+              </template>
+            </div>
+
+            <!-- 审批操作按钮 -->
+            <div v-if="item.checkType === '0' && isOper" class="card-actions">
+              <van-button
+                round
+                size="small"
+                class="reject-btn"
+                @click="changeStatusFun(item, 3)"
+              >
+                <van-icon name="close" size="20" class="btn-icon" />
+                {{ $t("taskMessage.fail") }}
+              </van-button>
+              <van-button
+                round
+                size="small"
+                class="approve-btn"
+                @click="changeStatusFun(item, 1)"
+              >
+                <van-icon name="passed" size="20" class="btn-icon" />
+                {{ $t("taskMessage.adopt") }}
+              </van-button>
             </div>
           </div>
         </div>
@@ -111,30 +243,56 @@
     </div>
 
     <!-- 筛选弹窗 -->
-    <kDialog :dialogTitle="$t('taskMessage.equipmentInit.searchPop.title')"
-      :confirmBtnTxt="$t('taskMessage.equipmentInit.searchPop.filterBtn')" ref="kDialogRef" @confirmclk="confirmClk">
+    <kDialog
+      :dialogTitle="$t('taskMessage.equipmentInit.searchPop.title')"
+      :confirmBtnTxt="$t('taskMessage.equipmentInit.searchPop.filterBtn')"
+      ref="kDialogRef"
+      @confirmclk="confirmClk"
+    >
       <template #content>
-        <div class="cust_vantBorder">
-          <van-field clearable v-model="searchForm.merchantName" :placeholder="$t('taskMessage.equipmentInit.searchPop.merchantNamePlace')
-            " :label="$t('taskMessage.equipmentInit.searchPop.merchantName')" />
-          <van-field @click-input="busiInpClk" readonly clearable v-model="searchForm.stateName"
+        <div class="dialog-content">
+          <van-field
+            clearable
+            v-model="searchForm.merchantName"
+            :placeholder="
+              $t('taskMessage.equipmentInit.searchPop.merchantNamePlace')
+            "
+            :label="$t('taskMessage.equipmentInit.searchPop.merchantName')"
+          />
+
+          <van-field
+            @click-input="busiInpClk"
+            readonly
+            clearable
+            v-model="searchForm.stateName"
             :placeholder="$t('taskMessage.equipmentInit.searchPop.statePlace')"
-            :label="$t('taskMessage.equipmentInit.searchPop.state')">
+            :label="$t('taskMessage.equipmentInit.searchPop.state')"
+          >
             <template #right-icon>
-              <div class="l-flex-RC">
-                <van-icon v-if="searchForm.stateName" @click="searchForm.stateName = ''; searchForm.state = ''"
-                  class="o-mr-6" name="clear" />
-                <van-icon @click="busiInpClk" name="arrow-down" />
+              <div class="icon-container">
+                <van-icon
+                  v-if="searchForm.stateName"
+                  @click.stop="clearState"
+                  class="clear-icon"
+                  name="clear"
+                />
+                <van-icon @click.stop="busiInpClk" name="arrow-down" />
               </div>
             </template>
           </van-field>
         </div>
       </template>
     </kDialog>
+
     <!-- 状态选择框 -->
-    <van-popup v-model:show="busiPopShow" position="bottom">
-      <van-picker :title="$t('taskMessage.equipmentInit.searchPop.statePlace')" :columns="busiPopList"
-        :columns-field-names="busiPopFieldName" @confirm="busiPopConfirm" @cancel="busiPopShow = false" />
+    <van-popup v-model:show="busiPopShow" position="bottom" round>
+      <van-picker
+        :title="$t('taskMessage.equipmentInit.searchPop.statePlace')"
+        :columns="busiPopList"
+        :columns-field-names="busiPopFieldName"
+        @confirm="busiPopConfirm"
+        @cancel="busiPopShow = false"
+      />
     </van-popup>
   </div>
 </template>
@@ -147,7 +305,7 @@ import {
   changeProportionStatus,
 } from "@/service/taskMessage";
 import { showFailToast } from "vant";
-import { getLoginUser, styleUrl } from "@/common/js/utils";
+import { getLoginUser } from "@/common/js/utils";
 import dateUtil from "@/utils/dateUtil";
 import kDialog from "@/components/commom/kDialog/index.vue";
 import { useI18n } from "vue-i18n";
@@ -159,11 +317,11 @@ export default {
     // 筛选弹窗
     const busiPopList = reactive([
       {
-        name: t('taskMessage.whole'),
+        name: t("taskMessage.whole"),
         id: "1",
       },
       {
-        name: t('taskMessage.unapproved'),
+        name: t("taskMessage.unapproved"),
         id: "0",
       },
     ]);
@@ -177,7 +335,7 @@ export default {
     const searchForm = reactive({
       merchantName: "",
       state: "",
-      stateName: '',
+      stateName: "",
     });
     // 点击状态输入框
     const busiInpClk = () => {
@@ -261,8 +419,6 @@ export default {
     const isOper = ref(true);
     // 初始化页面获取列表
     onMounted(async () => {
-      // 加载样式
-      styleUrl('taskMessage');
       if (user) {
         searchParams.adminId = user.id;
         searchGetList();
@@ -288,7 +444,21 @@ export default {
       } else {
         showFailToast(data.message);
       }
-      console.log(data);
+    };
+
+    const getStatusText = (status) => {
+      switch (status) {
+        case "0":
+          return t("taskMessage.toBeApproved");
+        case "1":
+          return t("taskMessage.adopt");
+        case "2":
+          return t("taskMessage.cancel");
+        case "3":
+          return t("taskMessage.fail");
+        default:
+          return "";
+      }
     };
     return {
       loading,
@@ -311,11 +481,372 @@ export default {
       reviewedClk,
       isOper,
       user,
+      getStatusText,
     };
   },
 };
 </script>
 
 <style lang="less" scoped>
-@import "../../../common/style/common.less";
+@theme-color: #4d6add;
+@pending-color: #ff9800;
+@approved-color: #4caf50;
+@cancelled-color: #9e9e9e;
+@rejected-color: #f44336;
+@light-bg: #f5f8ff;
+@card-shadow: 0 3px 10px rgba(77, 106, 221, 0.15);
+@hover-shadow: 0 8px 15px rgba(77, 106, 221, 0.2);
+@transition: all 0.3s ease;
+@text-dark: #333;
+@text-light: #666;
+@text-lighter: #999;
+@border-radius: 12px;
+
+.task-page {
+  display: flex;
+  flex-direction: column;
+  height: 100vh;
+  background-color: @light-bg;
+}
+
+.task-container {
+  flex: 1;
+  padding: 15px;
+  overflow-y: auto;
+}
+
+.header-info {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 20px;
+  padding: 12px 15px;
+  background: white;
+  border-radius: @border-radius;
+  box-shadow: @card-shadow;
+}
+
+.total-card {
+  display: flex;
+  align-items: center;
+}
+
+.icon-box {
+  width: 44px;
+  height: 44px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  background-color: fade(@theme-color, 8%);
+  border-radius: 10px;
+  margin-right: 12px;
+
+  .dist-icon {
+    color: @theme-color;
+    font-size: 24px;
+  }
+}
+
+.total-info {
+  font-size: 14px;
+  color: @text-dark;
+
+  .highlight {
+    color: @theme-color;
+    font-weight: bold;
+    margin: 0 3px;
+    font-size: 18px;
+  }
+}
+
+.actions {
+  display: flex;
+  gap: 10px;
+}
+
+.action-btn {
+  height: 32px;
+  padding: 0 12px;
+  border-color: fade(@theme-color, 50%);
+  color: @theme-color;
+}
+
+.list-container {
+  display: flex;
+  flex-direction: column;
+  gap: 15px;
+}
+
+.list-card {
+  background: white;
+  border-radius: @border-radius;
+  box-shadow: @card-shadow;
+  padding: 16px;
+  transition: @transition;
+  position: relative;
+  overflow: hidden;
+
+  &.pending {
+    border-left: 3px solid @pending-color;
+
+    .status-tag {
+      background-color: fade(@pending-color, 15%);
+      color: darken(@pending-color, 10%);
+    }
+  }
+
+  &.approved {
+    border-left: 3px solid @approved-color;
+
+    .status-tag {
+      background-color: fade(@approved-color, 15%);
+      color: darken(@approved-color, 10%);
+    }
+  }
+
+  &.cancelled {
+    border-left: 3px solid @cancelled-color;
+
+    .status-tag {
+      background-color: fade(@cancelled-color, 15%);
+      color: darken(@cancelled-color, 10%);
+    }
+  }
+
+  &.rejected {
+    border-left: 3px solid @rejected-color;
+
+    .status-tag {
+      background-color: fade(@rejected-color, 15%);
+      color: darken(@rejected-color, 10%);
+    }
+  }
+
+  &:hover {
+    transform: translateY(-2px);
+    box-shadow: @hover-shadow;
+  }
+}
+
+.card-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 15px;
+  padding-bottom: 12px;
+  border-bottom: 1px solid fade(@theme-color, 10%);
+}
+
+.status-tag {
+  padding: 4px 10px;
+  border-radius: 30px;
+  font-size: 13px;
+  font-weight: 600;
+  min-width: 70px;
+  text-align: center;
+}
+
+.time-label {
+  font-size: 12px;
+  color: @text-lighter;
+}
+
+.card-content {
+  display: flex;
+  flex-direction: column;
+  gap: 12px;
+}
+
+.info-row {
+  display: flex;
+  align-items: flex-start;
+
+  .row-icon {
+    flex-shrink: 0;
+    font-size: 18px;
+    color: @theme-color;
+    margin-right: 10px;
+  }
+
+  .row-content {
+    flex: 1;
+    font-size: 14px;
+  }
+
+  .label {
+    color: @text-light;
+    min-width: 90px;
+    display: inline-block;
+  }
+
+  .value {
+    color: @text-dark;
+    word-break: break-all;
+  }
+}
+
+.dist-grid {
+  display: flex;
+  flex-direction: column;
+  gap: 12px;
+  padding: 12px;
+  background: fade(@theme-color, 4%);
+  border-radius: 10px;
+  margin: 12px 0;
+}
+
+.dist-section {
+  display: flex;
+  flex-direction: column;
+  gap: 8px;
+  padding-bottom: 8px;
+  border-bottom: 1px solid fade(@theme-color, 10%);
+
+  &:last-child {
+    border-bottom: none;
+    padding-bottom: 0;
+  }
+}
+
+.dist-item {
+  display: flex;
+  align-items: flex-start;
+  gap: 12px;
+}
+
+.dist-icon-box {
+  width: 36px;
+  height: 36px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  background-color: fade(@theme-color, 8%);
+  border-radius: 8px;
+  flex-shrink: 0;
+
+  .dist-icon {
+    color: @theme-color;
+    font-size: 18px;
+  }
+}
+
+.dist-info {
+  flex: 1;
+}
+
+.dist-title {
+  font-size: 14px;
+  color: @text-dark;
+  font-weight: 500;
+  margin-bottom: 4px;
+}
+
+.dist-content {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  font-size: 13px;
+}
+
+.dist-name {
+  color: @text-light;
+  flex: 1;
+  padding-right: 10px;
+  word-break: break-word;
+}
+
+.dist-percent {
+  font-weight: bold;
+  color: @theme-color;
+  font-size: 15px;
+  min-width: 50px;
+  text-align: right;
+}
+
+.card-actions {
+  display: flex;
+  justify-content: flex-end;
+  gap: 15px;
+  margin-top: 15px;
+  padding-top: 15px;
+  border-top: 1px dashed fade(@theme-color, 15%);
+
+  .reject-btn,
+  .approve-btn {
+    min-width: 90px;
+    height: 34px;
+    padding: 0 15px;
+    font-size: 13px;
+
+    .btn-icon {
+      vertical-align: -2px;
+      margin-right: 5px;
+    }
+  }
+
+  .reject-btn {
+    border-color: fade(@rejected-color, 50%);
+    color: @rejected-color;
+    background-color: fade(@rejected-color, 8%);
+  }
+
+  .approve-btn {
+    border-color: fade(@approved-color, 50%);
+    color: @approved-color;
+    background-color: fade(@approved-color, 8%);
+  }
+}
+
+.dialog-content {
+  padding: 10px 0;
+
+  :deep(.van-cell) {
+    padding: 12px 0;
+    border-bottom: 1px solid rgba(0, 0, 0, 0.05);
+  }
+}
+
+.icon-container {
+  display: flex;
+  align-items: center;
+
+  .clear-icon {
+    color: #999;
+    margin-right: 8px;
+  }
+}
+
+/* 空状态样式 */
+.empty-list {
+  text-align: center;
+  padding: 40px 20px;
+
+  .empty-icon {
+    font-size: 80px;
+    color: fade(@theme-color, 20%);
+    margin-bottom: 15px;
+  }
+
+  .empty-text {
+    color: @text-light;
+    font-size: 16px;
+  }
+}
+
+/* 动画效果 */
+@keyframes cardEntry {
+  0% {
+    transform: translateY(15px);
+    opacity: 0;
+  }
+  100% {
+    transform: translateY(0);
+    opacity: 1;
+  }
+}
+
+.list-card {
+  animation: cardEntry 0.4s ease-out forwards;
+  opacity: 0;
+}
 </style>

+ 587 - 196
src/views/taskMessage/refundReminder/index.vue

@@ -1,217 +1,608 @@
 <template>
-    <!-- 分销申请审批 -->
-    <div class="taskMessagePage flex-col">
-        <s-header :name="$t('taskMessage.refundRemind')" :noback="false"></s-header>
-        <div class="taskMessageBox flex-col">
-            <van-list v-model:loading="loading" v-model:error="error" :error-text="$t('common.reqFailClkReload')"
-                :finished="finished" :finished-text="$t('common.noMoreTxt')" offset="300" :immediate-check="false"
-                @load="onLoad">
-                <div class="searchRow flex-row justify-between">
-                    <div class="flex-col">
-                        <div class="flex-row justify-between bd3">
-                            <div class="flex-col outer4 proportionIcon"></div>
-                            <span class="flex-col txt2">{{ $t('taskMessage.total') }}<span class="discountNumber">{{
-            alarmHistoryTotal
-        }}</span>{{ $t('taskMessage.recordsInTotal') }}</span>
-                        </div>
-                    </div>
-                    <div @click="noticeClk" class="main5 l-flex-RC">
-                        <img class="label2 o-mr-5" src="../../../assets/device/searchIcon.png" />
-                    </div>
+  <div class="task-message-page">
+    <!-- 顶部导航 -->
+    <s-header :name="$t('taskMessage.refundRemind')" :noback="false"></s-header>
+
+    <div class="task-container">
+      <van-list
+        v-model:loading="loading"
+        v-model:error="error"
+        :error-text="$t('common.reqFailClkReload')"
+        :finished="finished"
+        :finished-text="$t('common.noMoreTxt')"
+        offset="300"
+        :immediate-check="false"
+        @load="onLoad"
+      >
+        <!-- 顶部信息卡片 -->
+        <div class="info-card">
+          <div class="stats-area">
+            <div class="icon-box">
+              <van-icon name="todo-list" class="icon" />
+            </div>
+            <div class="stats-text">
+              {{ $t("taskMessage.total") }}
+              <span class="highlight">{{ alarmHistoryTotal }}</span>
+              {{ $t("taskMessage.recordsInTotal") }}
+            </div>
+          </div>
+
+          <van-button
+            round
+            size="small"
+            plain
+            class="search-btn"
+            @click="noticeClk"
+          >
+            <van-icon name="search" size="20" class="action-icon" />
+          </van-button>
+        </div>
+
+        <!-- 列表容器 -->
+        <div class="list-container">
+          <div
+            v-for="(item, index) in alarmHistoryList"
+            :key="index"
+            class="list-card"
+            :class="{
+              pending: item.status === 0,
+              success: item.status === 1,
+              failed: item.checkType === 2,
+            }"
+          >
+            <div class="card-header">
+              <div class="status-tag">
+                <van-icon name="label-o" class="tag-icon" />
+                {{ getStatusText(item) }}
+              </div>
+              <div class="ref-id">#{{ index + 1 }}</div>
+            </div>
+
+            <div class="card-body">
+              <div class="info-row">
+                <van-icon name="todo-list-o" class="row-icon" />
+                <div class="row-content">
+                  <span class="label">{{ $t("taskMessage.sn") }}:</span>
+                  <span class="value">{{ item.sn || "-" }}</span>
                 </div>
-                <div class="listBox">
-                    <div v-for="(item, index) in alarmHistoryList" :key="index" class="listItem">
-                        <div class="itemBox">
-                            <div class="itemRow">
-                                <span class="itemTitle">{{ $t('taskMessage.sn') }}:&nbsp;</span>
-                                {{ item.sn }}
-                            </div>
-                            <div class="itemRow">
-                                <span class="itemTitle">{{ $t('taskMessage.clientId') }}:&nbsp;</span>
-                                {{ item.clientId }}
-                            </div>
-                            <div class="itemRow">
-                                <span class="itemTitle">{{ $t('taskMessage.phone') }}:&nbsp;</span>
-                                {{ item.phone }}
-                            </div>
-                            <div class="itemRow">
-                                <span class="itemTitle">{{ $t('taskMessage.sendTime') }}:&nbsp;</span>
-                                {{ showDateTime(item.createDate) }}
-                            </div>
-                            <div class="itemRow" v-if="item.status === 2">
-                                <span class="itemTitle">{{ $t('taskMessage.remark') }}:&nbsp;</span>
-                                {{ item.remark }}
-                            </div>
-                            <div class="itemRow" style="display: flex; justify-content: flex-end">
-                                <span v-if="item.status === 0" style="color: #FFA500"> {{
-            $t('taskMessage.sendWait') }}</span>
-                                <span v-if="item.status === 1" style="color: #1989fa"> {{ $t('taskMessage.sendSucess')
-                                    }}</span>
-                                <span v-if="item.checkType === 2" style="color: #ff0033"> {{ $t('taskMessage.sendFail')
-                                    }}</span>
-                            </div>
-                        </div>
-                    </div>
+              </div>
+
+              <div class="info-row">
+                <van-icon name="idcard" class="row-icon" />
+                <div class="row-content">
+                  <span class="label">{{ $t("taskMessage.clientId") }}:</span>
+                  <span class="value">{{ item.clientId || "-" }}</span>
                 </div>
-            </van-list>
-        </div>
+              </div>
 
-        <!-- 筛选弹窗 -->
-        <kDialog :dialogTitle="$t('taskMessage.equipmentInit.searchPop.title')"
-            :confirmBtnTxt="$t('taskMessage.equipmentInit.searchPop.filterBtn')" ref="kDialogRef"
-            @confirmclk="confirmClk">
-            <template #content>
-                <div class="cust_vantBorder">
-                    <van-field clearable v-model="searchParams.sn" :placeholder="$t('taskMessage.snPlaceholder')
-            " :label="$t('taskMessage.sn')" />
-                    <van-field clearable v-model="searchParams.clientId" :placeholder="$t('taskMessage.clientIdPlaceholder')
-            " :label="$t('taskMessage.clientId')" />
-                    <van-field v-model="searchDate" is-link readonly :label="$t('taskMessage.searchDate')" :placeholder="$t('taskMessage.searchDatePlaceholder')"
-                        @click="showPicker = true" />
+              <div class="info-row">
+                <van-icon name="phone-o" class="row-icon" />
+                <div class="row-content">
+                  <span class="label">{{ $t("taskMessage.phone") }}:</span>
+                  <span class="value">{{ item.phone || "-" }}</span>
                 </div>
-            </template>
-        </kDialog>
+              </div>
 
-        <van-popup v-model:show="showPicker" position="bottom">
-            <van-date-picker @confirm="onConfirm" :title="$t('taskMessage.chooseTitle')" :min-date="minDate" :max-date="maxDate"
-                @cancel="showPicker = false" :columns-type="columnsType" />
-        </van-popup>
+              <div class="info-row">
+                <van-icon name="clock-o" class="row-icon" />
+                <div class="row-content">
+                  <span class="label">{{ $t("taskMessage.sendTime") }}:</span>
+                  <span class="value">{{ showDateTime(item.createDate) }}</span>
+                </div>
+              </div>
+
+              <div v-if="item.remark" class="info-row">
+                <van-icon name="comment-o" class="row-icon" />
+                <div class="row-content">
+                  <span class="label">{{ $t("taskMessage.remark") }}:</span>
+                  <span class="value">{{ item.remark }}</span>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </van-list>
     </div>
+
+    <!-- 筛选弹窗 -->
+    <k-dialog
+      :dialogTitle="$t('taskMessage.equipmentInit.searchPop.title')"
+      :confirmBtnTxt="$t('taskMessage.equipmentInit.searchPop.filterBtn')"
+      ref="kDialogRef"
+      @confirmclk="confirmClk"
+    >
+      <template #content>
+        <div class="dialog-form">
+          <van-field
+            clearable
+            v-model="searchParams.sn"
+            :placeholder="$t('taskMessage.snPlaceholder')"
+            :label="$t('taskMessage.sn')"
+            label-align="top"
+            class="custom-field"
+          >
+            <template #left-icon>
+              <van-icon name="notes-o" class="field-icon" />
+            </template>
+          </van-field>
+
+          <van-field
+            clearable
+            v-model="searchParams.clientId"
+            :placeholder="$t('taskMessage.clientIdPlaceholder')"
+            :label="$t('taskMessage.clientId')"
+            label-align="top"
+            class="custom-field"
+          >
+            <template #left-icon>
+              <van-icon name="idcard" class="field-icon" />
+            </template>
+          </van-field>
+
+          <van-field
+            v-model="searchDate"
+            is-link
+            readonly
+            :label="$t('taskMessage.searchDate')"
+            :placeholder="$t('taskMessage.searchDatePlaceholder')"
+            @click="showPicker = true"
+            label-align="top"
+            class="custom-field"
+          >
+            <template #left-icon>
+              <van-icon name="calendar-o" class="field-icon" />
+            </template>
+          </van-field>
+        </div>
+      </template>
+    </k-dialog>
+
+    <!-- 日期选择器 -->
+    <van-popup v-model:show="showPicker" position="bottom" round>
+      <van-date-picker
+        :title="$t('taskMessage.chooseTitle')"
+        :min-date="minDate"
+        :max-date="maxDate"
+        @confirm="onConfirm"
+        @cancel="showPicker = false"
+        :columns-type="columnsType"
+        class="date-picker-popup"
+      />
+    </van-popup>
+  </div>
 </template>
 
 <script>
 import { onMounted, reactive, ref } from "vue";
 import sHeader from "@/components/SimpleHeader";
-import {
-    refundRecord
-} from "@/service/taskMessage";
+import { refundRecord } from "@/service/taskMessage";
 import { showFailToast } from "vant";
-import { getLoginUser, styleUrl } from "@/common/js/utils";
+import { getLoginUser } from "@/common/js/utils";
 import dateUtil from "@/utils/dateUtil";
 import kDialog from "@/components/commom/kDialog/index.vue";
+import { useI18n } from "vue-i18n";
 
 export default {
-    components: { sHeader, kDialog },
-    setup() {
-        const kDialogRef = ref(null);
-        const showPicker = ref(false);
-        const searchDate = ref('');
-        const minDate = new Date(2024, 9, 1);
-        const maxDate = new Date();
-        const columnsType = ['year', 'month'];
-        let startTime = null;
-        let endTime = null;
-        const onConfirm = ({ selectedValues }) => {
-            searchDate.value = selectedValues[0] + '年' + selectedValues[1] + '月';
-            startTime = new Date(selectedValues[0] + '-' + selectedValues[1] + '-01');
-            endTime = new Date(selectedValues[0], selectedValues[1], 0);
-            searchParams.startTime =
-                dateUtil.formateDate(startTime, "yyyy-MM-dd") + " 00:00:00";
-            searchParams.endTime =
-                dateUtil.formateDate(endTime, "yyyy-MM-dd") + " 23:59:59";
-            showPicker.value = false;
-        };
-        // 点击筛选
-        const noticeClk = () => {
-            kDialogRef.value.openDialog();
-        };
-        // 点击查询按钮
-        const confirmClk = () => {
-            searchRecordList();
-        };
-        const user = getLoginUser();
-        const loading = ref(false); // 加载状态
-        const error = ref(false); // 错误状态
-        const finished = ref(false); // 结束翻页状态
-        const alarmHistoryList = ref([]); // 列表集合
-        const alarmHistoryTotal = ref(0); // 列表总数
-        const searchParams = reactive({
-            sendAdminId: "", // 当前登录账户的id
-            clientId: "", // 设备编号
-            current: 1, // 当前页
-            size: 20, // 页大小
-            username: "", // 商家名称
-            startTime: "", // 开始时间
-            endTime: "", // 结束时间
-            sn: "", // 订单编号
-        });
-        // 滚动加载
-        const onLoad = () => {
-            if (!finished.value) {
-                searchParams.current = searchParams.current + 1;
-                getList();
-            }
-        };
-        // 查询退款提醒记录
-        const searchRecordList = () => {
-            alarmHistoryList.value = [];
-            searchParams.current = 1;
-            getList();
-        };
-        // 获取设备初始化审批列表数据
-        const getList = async () => {
-            // // 把弹窗的筛选条件组合到请求参数里面
-            // if (!isClkReview.value) {
-            //   searchParams.type = searchForm.state;
-            // }
-            // searchParams.userName = searchForm.merchantName;
-            const { data } = await refundRecord(
-                Object.assign({}, searchParams)
-            );
-            if (data.code === "00000") {
-                // 列表值叠加
-                alarmHistoryList.value = alarmHistoryList.value.concat(
-                    data.data.records
-                );
-                alarmHistoryTotal.value = data.data.total;
-                if (alarmHistoryList.value.length === data.data.total) {
-                    finished.value = true;
-                }
-                loading.value = false;
-                console.log(alarmHistoryList);
-            } else {
-                showFailToast(data.message);
-            }
-        };
-
-        // 初始化页面获取列表
-        onMounted(async () => {
-            // 加载样式
-            styleUrl('taskMessage');
-            if (user) {
-                searchParams.sendAdminId = user.id;
-                searchRecordList();
-            }
-        });
-        const showDateTime = (date) => {
-            return date
-                ? dateUtil.formateDate(new Date(date), "yyyy/MM/dd hh:mm:ss")
-                : "";
-        };
-        return {
-            loading,
-            error,
-            finished,
-            onLoad,
-            alarmHistoryList,
-            alarmHistoryTotal,
-            showDateTime,
-            kDialogRef,
-            noticeClk,
-            confirmClk,
-            user,
-            searchParams,
-            searchDate,
-            showPicker,
-            onConfirm,
-            columnsType,
-            minDate,
-            maxDate,
-        };
-    },
+  components: { sHeader, kDialog },
+  setup() {
+    const { t } = useI18n();
+    const kDialogRef = ref(null);
+    const showPicker = ref(false);
+    const searchDate = ref("");
+    const minDate = new Date(2024, 9, 1);
+    const maxDate = new Date();
+    const columnsType = ["year", "month"];
+    let startTime = null;
+    let endTime = null;
+    const onConfirm = ({ selectedValues }) => {
+      searchDate.value = selectedValues[0] + "年" + selectedValues[1] + "月";
+      startTime = new Date(selectedValues[0] + "-" + selectedValues[1] + "-01");
+      endTime = new Date(selectedValues[0], selectedValues[1], 0);
+      searchParams.startTime =
+        dateUtil.formateDate(startTime, "yyyy-MM-dd") + " 00:00:00";
+      searchParams.endTime =
+        dateUtil.formateDate(endTime, "yyyy-MM-dd") + " 23:59:59";
+      showPicker.value = false;
+    };
+    // 点击筛选
+    const noticeClk = () => {
+      kDialogRef.value.openDialog();
+    };
+    // 点击查询按钮
+    const confirmClk = () => {
+      searchRecordList();
+    };
+    const user = getLoginUser();
+    const loading = ref(false); // 加载状态
+    const error = ref(false); // 错误状态
+    const finished = ref(false); // 结束翻页状态
+    const alarmHistoryList = ref([]); // 列表集合
+    const alarmHistoryTotal = ref(0); // 列表总数
+    const searchParams = reactive({
+      sendAdminId: "", // 当前登录账户的id
+      clientId: "", // 设备编号
+      current: 1, // 当前页
+      size: 20, // 页大小
+      username: "", // 商家名称
+      startTime: "", // 开始时间
+      endTime: "", // 结束时间
+      sn: "", // 订单编号
+    });
+    // 滚动加载
+    const onLoad = () => {
+      if (!finished.value) {
+        searchParams.current = searchParams.current + 1;
+        getList();
+      }
+    };
+    // 查询退款提醒记录
+    const searchRecordList = () => {
+      alarmHistoryList.value = [];
+      searchParams.current = 1;
+      getList();
+    };
+    // 获取设备初始化审批列表数据
+    const getList = async () => {
+      const { data } = await refundRecord(Object.assign({}, searchParams));
+      if (data.code === "00000") {
+        // 列表值叠加
+        alarmHistoryList.value = alarmHistoryList.value.concat(
+          data.data.records
+        );
+        alarmHistoryTotal.value = data.data.total;
+        if (alarmHistoryList.value.length === data.data.total) {
+          finished.value = true;
+        }
+        loading.value = false;
+        console.log(alarmHistoryList);
+      } else {
+        showFailToast(data.message);
+      }
+    };
+
+    // 初始化页面获取列表
+    onMounted(async () => {
+      if (user) {
+        searchParams.sendAdminId = user.id;
+        searchRecordList();
+      }
+    });
+    const showDateTime = (date) => {
+      return date
+        ? dateUtil.formateDate(new Date(date), "yyyy/MM/dd hh:mm:ss")
+        : "";
+    };
+
+    const getStatusText = (item) => {
+      if (item.status === 0) return t('taskMessage.sendWait');
+      if (item.status === 1) return t('taskMessage.sendSucess');
+      if (item.checkType === 2) return t('taskMessage.sendFail');
+      return '-';
+    };
+    return {
+      loading,
+      error,
+      finished,
+      onLoad,
+      alarmHistoryList,
+      alarmHistoryTotal,
+      showDateTime,
+      kDialogRef,
+      noticeClk,
+      confirmClk,
+      user,
+      searchParams,
+      searchDate,
+      showPicker,
+      onConfirm,
+      columnsType,
+      minDate,
+      maxDate,
+      getStatusText,
+    };
+  },
 };
 </script>
 
 <style lang="less" scoped>
-@import "../../../common/style/common.less";
-</style>
+@theme-color: #4d6add;
+@success-color: #4caf50;
+@pending-color: #ff9800;
+@failed-color: #f44336;
+@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;
+
+.task-message-page {
+  display: flex;
+  flex-direction: column;
+  height: 100vh;
+  background-color: @light-bg;
+  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen,
+    sans-serif;
+}
+
+.task-container {
+  flex: 1;
+  padding: 16px;
+  overflow-y: auto;
+}
+
+.info-card {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 14px 16px;
+  margin-bottom: 20px;
+  background: @card-bg;
+  border-radius: @border-radius;
+  box-shadow: @card-shadow;
+}
+
+.stats-area {
+  display: flex;
+  align-items: center;
+}
+
+.icon-box {
+  width: 44px;
+  height: 44px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  background-color: fade(@theme-color, 8%);
+  border-radius: 10px;
+  margin-right: 12px;
+
+  .icon {
+    color: @theme-color;
+    font-size: 24px;
+  }
+}
+
+.stats-text {
+  font-size: 15px;
+  color: @text-dark;
+
+  .highlight {
+    font-size: 18px;
+    color: @theme-color;
+    font-weight: bold;
+    margin: 0 4px;
+  }
+}
+
+.search-btn {
+  height: 32px;
+  padding: 0 12px;
+  border-color: fade(@theme-color, 50%);
+  color: @theme-color;
+  font-weight: 500;
+
+  &:active {
+    background-color: fade(@theme-color, 8%);
+  }
+}
+
+.list-container {
+  display: flex;
+  flex-direction: column;
+  gap: 16px;
+}
+
+.list-card {
+  background: @card-bg;
+  border-radius: @border-radius;
+  box-shadow: @card-shadow;
+  padding: 18px 16px 16px;
+  transition: @transition;
+  position: relative;
+  overflow: hidden;
+
+  &.pending {
+    border-left: 3px solid @pending-color;
+  }
+
+  &.success {
+    border-left: 3px solid @success-color;
+  }
+
+  &.failed {
+    border-left: 3px solid @failed-color;
+  }
+
+  &:hover {
+    transform: translateY(-2px);
+    box-shadow: @hover-shadow;
+  }
+}
+
+.card-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 16px;
+  padding-bottom: 12px;
+  border-bottom: 1px solid fade(@theme-color, 10%);
+}
+
+.status-tag {
+  display: flex;
+  align-items: center;
+  padding: 5px 10px;
+  border-radius: 18px;
+  font-size: 13px;
+  font-weight: 500;
+  min-width: 80px;
+
+  .tag-icon {
+    margin-right: 5px;
+    font-size: 14px;
+  }
+
+  .pending & {
+    background-color: fade(@pending-color, 12%);
+    color: darken(@pending-color, 15%);
+  }
+
+  .success & {
+    background-color: fade(@success-color, 12%);
+    color: darken(@success-color, 15%);
+  }
+
+  .failed & {
+    background-color: fade(@failed-color, 12%);
+    color: darken(@failed-color, 15%);
+  }
+}
+
+.ref-id {
+  font-size: 12px;
+  color: @text-lighter;
+  letter-spacing: 0.5px;
+}
+
+.card-body {
+  display: flex;
+  flex-direction: column;
+  gap: 13px;
+}
+
+.info-row {
+  display: flex;
+  align-items: flex-start;
+
+  .row-icon {
+    flex-shrink: 0;
+    font-size: 18px;
+    color: @theme-color;
+    margin-right: 10px;
+  }
+
+  .row-content {
+    flex: 1;
+    display: flex;
+    // flex-wrap: wrap;
+  }
+
+  .label {
+    color: @text-light;
+    min-width: 90px;
+    display: inline-block;
+    font-size: 14px;
+    padding-right: 5px;
+  }
+
+  .value {
+    color: @text-dark;
+    word-break: break-all;
+    flex: 1;
+    display: flex;
+    align-items: center;
+    min-width: 150px;
+    font-size: 13px;
+    font-weight: 500;
+  }
+}
+
+.dialog-form {
+  padding: 10px 0 15px;
+}
+
+.custom-field {
+  background-color: fade(@theme-color, 4%);
+  border-radius: 8px;
+  margin-bottom: 15px;
+  padding: 12px 16px;
+
+  :deep(.van-cell) {
+    padding: 0;
+    background: transparent;
+  }
+
+  :deep(.van-field__label) {
+    margin-bottom: 6px;
+    font-weight: 500;
+  }
+
+  .field-icon {
+    font-size: 20px;
+    color: @theme-color;
+    margin-right: 8px;
+  }
+}
+
+.date-picker-popup {
+  :deep(.van-picker__toolbar) {
+    background-color: @light-bg;
+  }
+
+  :deep(.van-picker__confirm) {
+    color: @theme-color;
+  }
+}
+
+// 动画效果
+@keyframes cardEntry {
+  0% {
+    transform: translateY(15px);
+    opacity: 0;
+  }
+  100% {
+    transform: translateY(0);
+    opacity: 1;
+  }
+}
+
+.list-card {
+  animation: cardEntry 0.4s ease-out forwards;
+  opacity: 0;
+
+  &:nth-child(1) {
+    animation-delay: 0.05s;
+  }
+  &:nth-child(2) {
+    animation-delay: 0.1s;
+  }
+  &:nth-child(3) {
+    animation-delay: 0.15s;
+  }
+  &:nth-child(4) {
+    animation-delay: 0.2s;
+  }
+  &:nth-child(5) {
+    animation-delay: 0.25s;
+  }
+}
+
+// 响应式调整
+@media (max-width: 360px) {
+  .task-container {
+    padding: 12px;
+  }
+
+  .info-card {
+    padding: 12px;
+  }
+
+  .icon-box {
+    width: 40px;
+    height: 40px;
+  }
+
+  .search-btn {
+    padding: 0 14px;
+    font-size: 13px;
+  }
+
+  .info-row .label {
+    min-width: 80px;
+  }
+}
+</style>

+ 2 - 2
src/views/user.vue

@@ -105,7 +105,7 @@
           </div>
           <!-- 手机号码 -->
           <div
-            v-if="user.type != '0' && !phoneNumberShow"
+            v-if="user.type == '2' && user.ifForeign == '0' && !phoneNumberShow"
             class="userInfo l-flex-between"
           >
             <span class="userInfoLeft">{{ $t("user.phoneNumber") }}</span>
@@ -128,7 +128,7 @@
             </van-field>
           </div>
           <div
-            v-if="user.type != '0' && phoneNumberShow"
+            v-if="user.type == '2' && user.ifForeign == '0' && phoneNumberShow"
             class="userInfo l-flex-between"
           >
             <span class="userInfoLeft">{{ $t("user.phoneNumber") }}</span>