Commit 13203a04c9c4ee0ac0b95a6b92b11eeb4d95ebdc

Authored by 刘淇
1 parent 2d57b60f

首页 统计

pages-sub/daily/maintain-manage/add-record.vue
@@ -4,14 +4,21 @@ @@ -4,14 +4,21 @@
4 <up-form label-position="left" :model="inspectForm" ref="inspectFormRef" label-width="140rpx"> 4 <up-form label-position="left" :model="inspectForm" ref="inspectFormRef" label-width="140rpx">
5 <!-- ========== 动态表单区域 ========== --> 5 <!-- ========== 动态表单区域 ========== -->
6 <template v-for="item in dynamicFields" :key="item.fieldCode"> 6 <template v-for="item in dynamicFields" :key="item.fieldCode">
7 - <up-form-item :label="item.fieldName" :prop="item.fieldCode" :required="item.required === 1" class="form-item"  
8 - @click="openPickerIfNeeded(item)"> 7 + <up-form-item :label="item.fieldName" :prop="item.fieldCode" class="form-item" @click="openPickerIfNeeded(item)">
  8 +
9 <!-- type 1 数值:u-number-box,最多2位小数,min=0,max取item.length --> 9 <!-- type 1 数值:u-number-box,最多2位小数,min=0,max取item.length -->
10 <view v-if="item.fieldType === 1" class="number-box-wrap"> 10 <view v-if="item.fieldType === 1" class="number-box-wrap">
11 - <u-number-box v-model="inspectForm[item.fieldCode]" min="1" :step="1"  
12 - :max="item.length ? 10 ** Number(item.length) - 1 : null"  
13 - :placeholder="`请输入${item.fieldName}${item.unit} `" @change="valChange(item)" class="large-number-box">  
14 - </u-number-box> 11 + <u-number-box
  12 + v-model="inspectForm[item.fieldCode]"
  13 + min="1"
  14 + :step="1"
  15 + :max="item.length ? 10 ** Number(item.length) - 1 : null"
  16 + :placeholder="`请输入${item.fieldName}${item.unit} `"
  17 + @change="valChange(item)"
  18 + @blur="valChange(item)"
  19 + class="large-number-box">
  20 +</u-number-box>
  21 +
15 <text class="unit-text" v-if="item.unit">{{ item.unit }}</text> 22 <text class="unit-text" v-if="item.unit">{{ item.unit }}</text>
16 </view> 23 </view>
17 <!-- type 2 文本 --> 24 <!-- type 2 文本 -->
@@ -132,10 +139,14 @@ @@ -132,10 +139,14 @@
132 </up-form> 139 </up-form>
133 </view> 140 </view>
134 <!-- 底部提交按钮 --> 141 <!-- 底部提交按钮 -->
135 - <view class="fixed-bottom-btn-wrap">  
136 - <up-button type="primary" text="提交" @click="submitInspect"  
137 - style="width: 100%; height: 88rpx; font-size:32rpx; border-radius: 0;"></up-button>  
138 - </view> 142 + <view v-if="dynamicFields.length === 0" class="empty-field-tip">
  143 + <text>请去平台配置业务类型字段</text>
  144 +</view>
  145 +<!-- ========== 底部提交按钮:只有存在动态字段才显示 ========== -->
  146 +<view class="fixed-bottom-btn-wrap" v-if="dynamicFields.length > 0">
  147 +<up-button type="primary" text="提交" @click="submitInspect"
  148 +style="width: 100%; height: 88rpx; font-size:32rpx; border-radius: 0;"></up-button>
  149 +</view>
139 <!-- uview-plus 日期时间选择器(全局复用) --> 150 <!-- uview-plus 日期时间选择器(全局复用) -->
140 <up-datetime-picker :show="datePickerShow" v-model="datePickerValue" mode="datetime" close-on-click-overlay 151 <up-datetime-picker :show="datePickerShow" v-model="datePickerValue" mode="datetime" close-on-click-overlay
141 @confirm="onDateConfirm" @cancel="onDateClose" @close="onDateClose"></up-datetime-picker> 152 @confirm="onDateConfirm" @cancel="onDateClose" @close="onDateClose"></up-datetime-picker>
@@ -646,31 +657,51 @@ export default { @@ -646,31 +657,51 @@ export default {
646 * 7/8/9/11 的值是数组或对象,async-validator 的 required 按默认 string 类型判定, 657 * 7/8/9/11 的值是数组或对象,async-validator 的 required 按默认 string 类型判定,
647 * 会放过「空数组」「null」⇒ 必须用 validator 显式判空,否则未选也能提交 658 * 会放过「空数组」「null」⇒ 必须用 validator 显式判空,否则未选也能提交
648 */ 659 */
649 - buildRequiredRule(field: any) {  
650 - const type = field.fieldType  
651 - if (type === 6 || type === 7 || type === 8) {  
652 - const action = type === 6 ? '请选择' : '请上传'  
653 - return {  
654 - required: true,  
655 - trigger: 'change',  
656 - validator: (rule, value, callback) => {  
657 - Array.isArray(value) && value.length > 0 ? callback() : callback(new Error(`${action}${field.fieldName}`))  
658 - }  
659 - } 660 +buildRequiredRule(field: any) {
  661 + const type = field.fieldType
  662 + if (type === 6 || type === 7 || type === 8) {
  663 + const action = type === 6 ? '请选择' : '请上传'
  664 + return {
  665 + required: true,
  666 + trigger: ['change','blur'],
  667 + validator: (rule, value, callback) => {
  668 + Array.isArray(value) && value.length > 0 ? callback() : callback(new Error(`${action}${field.fieldName}`))
660 } 669 }
661 - if (type === 9 || type === 11) {  
662 - return {  
663 - required: true,  
664 - trigger: 'change',  
665 - validator: (rule, value, callback) => {  
666 - value ? callback() : callback(new Error(type === 9 ? `请选择${field.fieldName}` : `请选择${field.fieldName}的位置`))  
667 - } 670 + }
  671 + }
  672 + if (type === 9 || type === 11) {
  673 + return {
  674 + required: true,
  675 + trigger: ['change','blur'],
  676 + validator: (rule, value, callback) => {
  677 + value ? callback() : callback(new Error(type === 9 ? `请选择${field.fieldName}` : `请选择${field.fieldName}的位置`))
  678 + }
  679 + }
  680 + }
  681 + // ========= 新增:数值类型单独校验 =========
  682 + if (type === 1) {
  683 + return {
  684 + required: true,
  685 + trigger: ['change','blur'],
  686 + validator: (rule, value, callback) => {
  687 + // 空字符串、null、undefined 才是空;数字 1,7,100 全部合法
  688 + if (value === '' || value === null || value === undefined) {
  689 + callback(new Error(`请填写${field.fieldName}`))
  690 + } else {
  691 + callback()
668 } 692 }
669 } 693 }
670 - // 1数值/2文本/4日期/5布尔/10链接 为字符串;3枚举/6单选为选择项  
671 - const action = type === 3 || type === 5 ? '请选择' : '请填写'  
672 - return { required: true, message: `${action}${field.fieldName}`, trigger: 'change' }  
673 - }, 694 + }
  695 + }
  696 + // 2文本 /4日期 /5布尔 /10链接
  697 + const action = type === 3 || type === 5 ? '请选择' : '请填写'
  698 + return {
  699 + required: true,
  700 + message: `${action}${field.fieldName}`,
  701 + trigger: ['change','blur']
  702 + }
  703 +},
  704 +
674 /** 幂等流水号(后端按 userId+clientSeq 去重,命中则返回已存在的 recordId) */ 705 /** 幂等流水号(后端按 userId+clientSeq 去重,命中则返回已存在的 recordId) */
675 genClientSeq() { 706 genClientSeq() {
676 return `${Date.now()}-${Math.random().toString(16).slice(2, 10)}` 707 return `${Date.now()}-${Math.random().toString(16).slice(2, 10)}`
@@ -910,6 +941,12 @@ this.$refs.inspectFormRef.validateField(code) @@ -910,6 +941,12 @@ this.$refs.inspectFormRef.validateField(code)
910 * 重试安全:commitId 一旦取到就缓存住,重试只补写 ②(② 自身按 clientSeq 幂等),避免重复创建养护记录 941 * 重试安全:commitId 一旦取到就缓存住,重试只补写 ②(② 自身按 clientSeq 幂等),避免重复创建养护记录
911 */ 942 */
912 async submitInspect() { 943 async submitInspect() {
  944 + // 调试打印,打开小程序控制台查看
  945 + console.log('=====调试=====')
  946 + console.log('dynamicFields', this.dynamicFields)
  947 + this.dynamicFields.forEach(item=>{
  948 + console.log(item.fieldCode, this.inspectForm[item.fieldCode], typeof this.inspectForm[item.fieldCode])
  949 + })
913 try { 950 try {
914 await this.$refs.inspectFormRef.validate() 951 await this.$refs.inspectFormRef.validate()
915 const dynamicValues = this.buildDynamicFields() 952 const dynamicValues = this.buildDynamicFields()
@@ -1068,4 +1105,13 @@ this.$refs.inspectFormRef.validateField(code) @@ -1068,4 +1105,13 @@ this.$refs.inspectFormRef.validateField(code)
1068 } 1105 }
1069 } 1106 }
1070 } 1107 }
  1108 +
  1109 +.empty-field-tip {
  1110 + padding: 80rpx 30rpx;
  1111 + text-align: center;
  1112 + font-size: 30rpx;
  1113 + color: #999;
  1114 +}
  1115 +
  1116 +
1071 </style> 1117 </style>
pages-sub/daily/maintain-manage/finish-plan-detail.vue
@@ -95,7 +95,7 @@ @@ -95,7 +95,7 @@
95 title="提交人" 95 title="提交人"
96 :value="i.userName || '--'" 96 :value="i.userName || '--'"
97 align="middle" 97 align="middle"
98 - :border="false" 98 +
99 ></up-cell> 99 ></up-cell>
100 </up-cell-group> 100 </up-cell-group>
101 101
@@ -105,9 +105,12 @@ @@ -105,9 +105,12 @@
105 :border="false" 105 :border="false"
106 inset 106 inset
107 title="" 107 title=""
108 - style="margin-top: 16rpx;" 108 +
109 > 109 >
110 - <up-cell v-for="(f, fi) in i.fieldRows" :key="fi" :title="f.name" align="middle"> 110 + <up-cell v-for="(f, fi) in i.fieldRows" :key="fi" align="middle">
  111 + <template #title>
  112 + <view class="field-cell-title-multi">{{f.name}}</view>
  113 + </template>
111 <template #value> 114 <template #value>
112 <!-- 7 图片:复用本页照片的相册组件(预览/尺寸一致) --> 115 <!-- 7 图片:复用本页照片的相册组件(预览/尺寸一致) -->
113 <up-album 116 <up-album
@@ -616,4 +619,8 @@ onLoad((options) =&gt; { @@ -616,4 +619,8 @@ onLoad((options) =&gt; {
616 font-size: 26rpx; 619 font-size: 26rpx;
617 word-break: break-all; 620 word-break: break-all;
618 } 621 }
  622 +:deep(.field-cell-title-multi) {
  623 + min-width: 160rpx; // 固定左侧标题最大宽度,文字会在这个宽度内自动换行
  624 +}
  625 +
619 </style> 626 </style>
620 \ No newline at end of file 627 \ No newline at end of file
pages-sub/problem/regional-order-manage/list-detail.vue
@@ -96,8 +96,8 @@ @@ -96,8 +96,8 @@
96 <up-album 96 <up-album
97 v-if="!!orderDetail.problemsImgs?.length" 97 v-if="!!orderDetail.problemsImgs?.length"
98 :urls="orderDetail.problemsImgs.slice(0, 3)" 98 :urls="orderDetail.problemsImgs.slice(0, 3)"
99 - :singleSize="70"  
100 - :multipleSize="70" 99 + singleSize="70"
  100 + multipleSize="70"
101 :preview-full-image="true" 101 :preview-full-image="true"
102 ></up-album> 102 ></up-album>
103 <text v-else class="empty-text">暂无问题照片</text> 103 <text v-else class="empty-text">暂无问题照片</text>
pages/index/index.vue
@@ -8,27 +8,25 @@ @@ -8,27 +8,25 @@
8 <view class="login-desc">蓟城山水全域智能运营管理平台</view> 8 <view class="login-desc">蓟城山水全域智能运营管理平台</view>
9 </view> 9 </view>
10 </view> 10 </view>
11 - <view class="msg-icon" @click="handleMsgClick" hover-class="msg-icon--hover"> 11 + <!-- <view class="msg-icon" @click="handleMsgClick" hover-class="msg-icon--hover">
12 <up-icon name="chat" color="#fff" size="24" /> 12 <up-icon name="chat" color="#fff" size="24" />
13 <view class="msg-badge"> 13 <view class="msg-badge">
14 - <up-badge type="error" showZero="true" max="999" :value="msgCount"></up-badge> 14 + <up-badge type="error" show-zero max="999" :value="msgCount"></up-badge>
15 </view> 15 </view>
16 - </view> 16 + </view> -->
17 </view> 17 </view>
18 -  
19 <view class="content-wrap"> 18 <view class="content-wrap">
20 <!-- 图表区域 增加平滑动画容器 --> 19 <!-- 图表区域 增加平滑动画容器 -->
21 <view class="chart-wrap" v-show="showChartArea"> 20 <view class="chart-wrap" v-show="showChartArea">
22 <!-- 任务完成情况标题 --> 21 <!-- 任务完成情况标题 -->
23 <view class="module-title">任务完成情况</view> 22 <view class="module-title">任务完成情况</view>
24 -  
25 <!-- 任务完成情况卡片 --> 23 <!-- 任务完成情况卡片 -->
26 <view class="task-chart-card"> 24 <view class="task-chart-card">
27 <view class="card-header"> 25 <view class="card-header">
28 <view class="unit-tip">数字指标</view> 26 <view class="unit-tip">数字指标</view>
29 <!-- ActionSheet 点击唤起 --> 27 <!-- ActionSheet 点击唤起 -->
30 <view class="sort-trigger" @click="openActionSheet"> 28 <view class="sort-trigger" @click="openActionSheet">
31 - {{ sortLabel }} 29 + <view class="sort-text">{{ sortLabel }}</view>
32 <up-icon name="arrow-down" size="14" style="margin-left:4rpx;"></up-icon> 30 <up-icon name="arrow-down" size="14" style="margin-left:4rpx;"></up-icon>
33 </view> 31 </view>
34 <!-- ActionSheet组件 --> 32 <!-- ActionSheet组件 -->
@@ -40,14 +38,11 @@ @@ -40,14 +38,11 @@
40 @popup-hide="handlePopupHide" /> 38 @popup-hide="handlePopupHide" />
41 </view> 39 </view>
42 </view> 40 </view>
43 -  
44 -  
45 <!-- 双折线K线图 --> 41 <!-- 双折线K线图 -->
46 <!-- <view class="chart-container"> 42 <!-- <view class="chart-container">
47 <uni-charts v-if="!isDatePickerOpen" type="line" :data="klineChartData" :categories="klineCategories" 43 <uni-charts v-if="!isDatePickerOpen" type="line" :data="klineChartData" :categories="klineCategories"
48 :option="klineOption" :width="chartWidth" :height="chartHeight" /> 44 :option="klineOption" :width="chartWidth" :height="chartHeight" />
49 </view> --> 45 </view> -->
50 -  
51 <up-grid :border="false" col="4"> 46 <up-grid :border="false" col="4">
52 <up-grid-item v-for="(baseListItem, baseListIndex) in baseList" :key="baseListIndex"> 47 <up-grid-item v-for="(baseListItem, baseListIndex) in baseList" :key="baseListIndex">
53 <view class="grid-item-icon-box"> 48 <view class="grid-item-icon-box">
@@ -57,14 +52,30 @@ @@ -57,14 +52,30 @@
57 </view> 52 </view>
58 </up-grid-item> 53 </up-grid-item>
59 </up-grid> 54 </up-grid>
60 -  
61 </view> 55 </view>
62 </view> 56 </view>
63 -  
64 <view class="con-wrap"> 57 <view class="con-wrap">
65 - <view class="con-title">养护任务 </view>  
66 -  
67 - <!-- 手写Tab切换:胶囊分段样式 --> 58 + <!-- ========= 一级大Tab【养护任务 / 巡检任务 / 工单】权限控制 ========= -->
  59 + <view class="main-tab-wrap">
  60 + <view
  61 + v-if="showMainTabYh"
  62 + class="main-tab-item"
  63 + :class="{active: mainTab === 'maintain'}"
  64 + @click="handleMainTabClick('maintain')"
  65 + >养护任务</view>
  66 + <view
  67 + v-if="showMainTabXj"
  68 + class="main-tab-item"
  69 + :class="{active: mainTab === 'inspect'}"
  70 + @click="handleMainTabClick('inspect')"
  71 + >巡检任务</view>
  72 + <view
  73 + class="main-tab-item"
  74 + :class="{active: mainTab === 'workorder'}"
  75 + @click="handleMainTabClick('workorder')"
  76 + >工单</view>
  77 + </view>
  78 + <!-- 手写Tab切换:胶囊分段样式(待办/已办)【原有样式完全保留不动】 -->
68 <view class="custom-tab-wrap"> 79 <view class="custom-tab-wrap">
69 <view class="tab-capsule" :class="{ active: currentTabValue === 0 }" @click="handleTabClick(0)"> 80 <view class="tab-capsule" :class="{ active: currentTabValue === 0 }" @click="handleTabClick(0)">
70 待办事项({{ todoTotal }}) 81 待办事项({{ todoTotal }})
@@ -73,38 +84,27 @@ @@ -73,38 +84,27 @@
73 已办事项({{ doneTotal }}) 84 已办事项({{ doneTotal }})
74 </view> 85 </view>
75 </view> 86 </view>
76 -  
77 -  
78 - <!-- 动态组信息文案 -->  
79 - <!-- <view class="tip-top" style="padding: 8px 0 0 70px;">  
80 - <text>{{ tipText }}</text>  
81 - </view> -->  
82 -  
83 <!-- 顶部进度提示栏 --> 87 <!-- 顶部进度提示栏 -->
84 <view v-if="showTipHeader" class="tip-header"> 88 <view v-if="showTipHeader" class="tip-header">
85 <up-icon name="checkmark-circle" color="#00b42a" size="20"></up-icon> 89 <up-icon name="checkmark-circle" color="#00b42a" size="20"></up-icon>
86 <text style="color: #1677ff;">今日组内:您已经完成{{ finishNum }}项,小组均值{{ avgNum }}项</text> 90 <text style="color: #1677ff;">今日组内:您已经完成{{ finishNum }}项,小组均值{{ avgNum }}项</text>
87 </view> 91 </view>
88 -  
89 -  
90 - <scroll-view class="task-list-container" scroll-y @scroll="onListScroll" @scrolltoupper="handleTouchTop"  
91 - enhanced> 92 + <scroll-view class="task-list-container" scroll-y @scroll="onListScroll" @scrolltoupper="handleTouchTop" enhanced>
92 <view v-if="taskList.length === 0" class="empty-box"> 93 <view v-if="taskList.length === 0" class="empty-box">
93 - <up-empty /> 94 + <up-empty></up-empty>
94 </view> 95 </view>
95 <view class="task-item" v-for="(item, index) in taskList" :key="`${item.taskName}_${index}`" 96 <view class="task-item" v-for="(item, index) in taskList" :key="`${item.taskName}_${index}`"
96 hover-class="task-item--hover" @click="handleTaskClick(item)"> 97 hover-class="task-item--hover" @click="handleTaskClick(item)">
97 <view class="task-item__content"> 98 <view class="task-item__content">
98 <view class="name-fixed-wrap"> 99 <view class="name-fixed-wrap">
99 - <view class="task-item__name "> 100 + <view class="task-item__name">
100 事项{{ index + 1 }} 101 事项{{ index + 1 }}
101 </view> 102 </view>
102 <view class="task-name-text"> 103 <view class="task-name-text">
103 {{ item.taskName || '无' }} 104 {{ item.taskName || '无' }}
104 </view> 105 </view>
105 </view> 106 </view>
106 -  
107 - <view v-if="currentTabValue === 0" class="task-item__footer" style="padding-left: 60px;"> 107 + <view v-if="currentTabValue === 0" class="task-item__footer" style="padding-left: 60rpx;">
108 <image class="loc-icon" src="https://img.jichengshanshui.com.cn:28207/appimg/定位icon@3x.png" 108 <image class="loc-icon" src="https://img.jichengshanshui.com.cn:28207/appimg/定位icon@3x.png"
109 mode="aspectFit"></image> 109 mode="aspectFit"></image>
110 <template v-if="isWalkTextMode"> 110 <template v-if="isWalkTextMode">
@@ -129,7 +129,7 @@ import { ref, computed, nextTick, watch } from &#39;vue&#39;; @@ -129,7 +129,7 @@ import { ref, computed, nextTick, watch } from &#39;vue&#39;;
129 import { onShow, onUnload } from '@dcloudio/uni-app'; 129 import { onShow, onUnload } from '@dcloudio/uni-app';
130 import { useUserStore } from '@/pinia/user'; 130 import { useUserStore } from '@/pinia/user';
131 import { timeFormat } from '@/uni_modules/uview-plus'; 131 import { timeFormat } from '@/uni_modules/uview-plus';
132 -import uniCharts from '@/components/uni-charts/uni-charts.vue'; 132 +// import uniCharts from '@/components/uni-charts/uni-charts.vue';
133 import { getUnreadCount } from "@/api/user"; 133 import { getUnreadCount } from "@/api/user";
134 import { 134 import {
135 getTaskCompletionSummary, 135 getTaskCompletionSummary,
@@ -189,6 +189,59 @@ const isWalkTextMode = computed(() =&gt; currentGroup.value.useWalkText); @@ -189,6 +189,59 @@ const isWalkTextMode = computed(() =&gt; currentGroup.value.useWalkText);
189 const useDistanceApi = computed(() => currentGroup.value.useWalkText); 189 const useDistanceApi = computed(() => currentGroup.value.useWalkText);
190 // ========================================================================= 190 // =========================================================================
191 191
  192 +// ========== 一级Tab:养护/巡检/工单 =========
  193 +// 默认期望打开 maintain,watch权限自动修正
  194 +const mainTab = ref<'maintain' | 'inspect' | 'workorder'>('maintain');
  195 +
  196 +// ✅ 修复:用户角色数组
  197 +const userRoles = computed<string[]>(() => userStore.userInfo?.roles || []);
  198 +console.log('当前用户角色数组:', userRoles.value)
  199 +
  200 +// 权限控制角色列表:包含这些角色,则隐藏对应tab
  201 +const hideYhRoleList = ['patrol_leader', 'patrol_global', 'yl_inspector', 'hjws_inspector', 'zxgl_inspector'];
  202 +const hideXjRoleList = ['zxgl_worker', 'team_leader_hjws', 'hjws_worker', 'team_leader_wy', 'wy_worker', 'yl_worker', 'team_leader_yl'];
  203 +
  204 +// ✅ 修复:用户角色数组 和 黑名单数组 存在交集 → 隐藏养护tab
  205 +const showMainTabYh = computed(() => {
  206 + // 判断:用户角色里是否存在任意一个在hideYhRoleList中的角色
  207 + const hasHideRole = userRoles.value.some(role => hideYhRoleList.includes(role));
  208 + return !hasHideRole;
  209 +});
  210 +// ✅ 修复:巡检tab权限
  211 +const showMainTabXj = computed(() => {
  212 + const hasHideRole = userRoles.value.some(role => hideXjRoleList.includes(role));
  213 + return !hasHideRole;
  214 +});
  215 +
  216 +// 获取可见tab数组,用于自动选中
  217 +const availableTabList = computed(() => {
  218 + const list: Array<'maintain' | 'inspect' | 'workorder'> = [];
  219 + if (showMainTabYh.value) list.push('maintain');
  220 + if (showMainTabXj.value) list.push('inspect');
  221 + list.push('workorder');
  222 + return list;
  223 +});
  224 +
  225 +// 监听权限变化:如果当前选中tab不可见,自动切到第一个可用tab
  226 +watch([showMainTabYh, showMainTabXj], () => {
  227 + const available = availableTabList.value;
  228 + console.log('可用tab列表', available);
  229 + if (!available.includes(mainTab.value)) {
  230 + mainTab.value = available[0];
  231 + console.log(`当前角色无【养护任务】权限,自动切换至:${mainTab.value}`)
  232 + }
  233 +}, { immediate: true });
  234 +
  235 +// 一级Tab切换事件
  236 +const handleMainTabClick = async (tabKey: 'maintain' | 'inspect' | 'workorder') => {
  237 + if (mainTab.value === tabKey) return;
  238 + mainTab.value = tabKey;
  239 + currentTabValue.value = 0; // 切大tab默认回到待办
  240 + showChartArea.value = true;
  241 + // 重新拉取对应类型任务
  242 + await loadAllTaskByDept();
  243 +};
  244 +
192 const finishNum = ref(0); 245 const finishNum = ref(0);
193 const avgNum = ref(0); 246 const avgNum = ref(0);
194 const msgCount = ref(0); 247 const msgCount = ref(0);
@@ -205,7 +258,6 @@ const handlePopupShow = () =&gt; { @@ -205,7 +258,6 @@ const handlePopupShow = () =&gt; {
205 const handlePopupHide = () => { 258 const handlePopupHide = () => {
206 isDatePickerOpen.value = false; 259 isDatePickerOpen.value = false;
207 }; 260 };
208 -  
209 const todoTotal = ref(0); 261 const todoTotal = ref(0);
210 const doneTotal = ref(0); 262 const doneTotal = ref(0);
211 const todoFullList = ref<any[]>([]); 263 const todoFullList = ref<any[]>([]);
@@ -217,7 +269,6 @@ const chooseOptions = computed(() =&gt; [ @@ -217,7 +269,6 @@ const chooseOptions = computed(() =&gt; [
217 { title: `待办事项(${todoTotal.value})`, id: 'todo' }, 269 { title: `待办事项(${todoTotal.value})`, id: 'todo' },
218 { title: `已办事项(${doneTotal.value})`, id: 'done' }, 270 { title: `已办事项(${doneTotal.value})`, id: 'done' },
219 ]); 271 ]);
220 -  
221 const currentLon = ref<string>(''); 272 const currentLon = ref<string>('');
222 const currentLat = ref<string>(''); 273 const currentLat = ref<string>('');
223 const chartWidth = ref(0); 274 const chartWidth = ref(0);
@@ -264,12 +315,10 @@ ${params[1].seriesName}: ${params[1].value}`; @@ -264,12 +315,10 @@ ${params[1].seriesName}: ${params[1].value}`;
264 textStyle: { fontSize: 12 } 315 textStyle: { fontSize: 12 }
265 } 316 }
266 }); 317 });
267 -  
268 -const baseList = ref<Array<{ num: string; title: string }>>([]); 318 +const baseList = ref<Array<{ num: string; title: string; name: string }>>([]);
269 const orgOptions = ref<any[]>([]); 319 const orgOptions = ref<any[]>([]);
270 const value1 = ref<number | string>(''); 320 const value1 = ref<number | string>('');
271 const showActionSheet = ref(false); 321 const showActionSheet = ref(false);
272 -  
273 watch(orgOptions, async (list) => { 322 watch(orgOptions, async (list) => {
274 if (list.length && !value1.value) { 323 if (list.length && !value1.value) {
275 value1.value = list[0].value; 324 value1.value = list[0].value;
@@ -279,7 +328,6 @@ watch(orgOptions, async (list) =&gt; { @@ -279,7 +328,6 @@ watch(orgOptions, async (list) =&gt; {
279 } 328 }
280 } 329 }
281 }, { immediate: true }); 330 }, { immediate: true });
282 -  
283 const actionSheetOptions = computed(() => { 331 const actionSheetOptions = computed(() => {
284 return orgOptions.value.map(opt => ({ 332 return orgOptions.value.map(opt => ({
285 name: opt.label, 333 name: opt.label,
@@ -302,13 +350,11 @@ const handleSheetSelect = async (item: { name: string; value: number }) =&gt; { @@ -302,13 +350,11 @@ const handleSheetSelect = async (item: { name: string; value: number }) =&gt; {
302 await fetchOrgIndicator(item.value, dateRange.value[0], dateRange.value[1]); 350 await fetchOrgIndicator(item.value, dateRange.value[0], dateRange.value[1]);
303 } 351 }
304 }; 352 };
305 -  
306 -const userName = computed(() => userStore.userInfo?.nickname || '用户'); 353 +const userName = computed(() => userStore.userInfo.user.nickname || '用户');
307 const rpx2px = (rpx: number) => { 354 const rpx2px = (rpx: number) => {
308 const systemInfo = uni.getSystemInfoSync(); 355 const systemInfo = uni.getSystemInfoSync();
309 return Math.floor(systemInfo.screenWidth / 750 * rpx); 356 return Math.floor(systemInfo.screenWidth / 750 * rpx);
310 }; 357 };
311 -  
312 // ========== 滚动逻辑 ========== 358 // ========== 滚动逻辑 ==========
313 const showChartArea = ref(true); 359 const showChartArea = ref(true);
314 const scrollHideThreshold = rpx2px(80); 360 const scrollHideThreshold = rpx2px(80);
@@ -336,7 +382,6 @@ const handleTabClick = (tabIndex: number) =&gt; { @@ -336,7 +382,6 @@ const handleTabClick = (tabIndex: number) =&gt; {
336 currentTabValue.value = tabIndex; 382 currentTabValue.value = tabIndex;
337 showChartArea.value = true; 383 showChartArea.value = true;
338 }; 384 };
339 -  
340 // ========== 公共函数:请求 orgTaskIndicator 指标接口 ========== 385 // ========== 公共函数:请求 orgTaskIndicator 指标接口 ==========
341 const fetchOrgIndicator = async (orgId: number, beginDate: string, endDate: string) => { 386 const fetchOrgIndicator = async (orgId: number, beginDate: string, endDate: string) => {
342 try { 387 try {
@@ -355,19 +400,16 @@ const fetchOrgIndicator = async (orgId: number, beginDate: string, endDate: stri @@ -355,19 +400,16 @@ const fetchOrgIndicator = async (orgId: number, beginDate: string, endDate: stri
355 { num: String(res.pendingCnt ?? 0), title: '待办任务数', name: 'clock' }, 400 { num: String(res.pendingCnt ?? 0), title: '待办任务数', name: 'clock' },
356 { num: String(res.overdueCnt ?? 0), title: '超时未完成', name: 'close-circle' } 401 { num: String(res.overdueCnt ?? 0), title: '超时未完成', name: 'close-circle' }
357 ]; 402 ];
358 -  
359 } catch (err) { 403 } catch (err) {
360 console.error('orgTaskIndicator 请求失败:', err); 404 console.error('orgTaskIndicator 请求失败:', err);
361 } 405 }
362 }; 406 };
363 -  
364 // ========== 初始化日期范围(近7天) ========== 407 // ========== 初始化日期范围(近7天) ==========
365 const initRecent7Days = () => { 408 const initRecent7Days = () => {
366 const now = new Date(); 409 const now = new Date();
367 const end = new Date(now); 410 const end = new Date(now);
368 - end.setDate(end.getDate() - 1); 411 + end.setDate(end.getDate());
369 const start = new Date(end); 412 const start = new Date(end);
370 - console.log(start)  
371 start.setDate(start.getDate() - 6); 413 start.setDate(start.getDate() - 6);
372 dateRange.value = [ 414 dateRange.value = [
373 timeFormat(start, 'yyyy-mm-dd'), 415 timeFormat(start, 'yyyy-mm-dd'),
@@ -376,7 +418,6 @@ const initRecent7Days = () =&gt; { @@ -376,7 +418,6 @@ const initRecent7Days = () =&gt; {
376 console.log(dateRange.value) 418 console.log(dateRange.value)
377 initChartData(dateRange.value[0], dateRange.value[1]); 419 initChartData(dateRange.value[0], dateRange.value[1]);
378 }; 420 };
379 -  
380 const getUnread = async () => { 421 const getUnread = async () => {
381 try { 422 try {
382 const res = await getUnreadCount(); 423 const res = await getUnreadCount();
@@ -385,7 +426,6 @@ const getUnread = async () =&gt; { @@ -385,7 +426,6 @@ const getUnread = async () =&gt; {
385 console.error('获取未读消息失败:', error); 426 console.error('获取未读消息失败:', error);
386 } 427 }
387 }; 428 };
388 -  
389 // getOrg:只拉组织下拉选项,不处理指标 429 // getOrg:只拉组织下拉选项,不处理指标
390 const getOrg = async () => { 430 const getOrg = async () => {
391 try { 431 try {
@@ -396,7 +436,6 @@ const getOrg = async () =&gt; { @@ -396,7 +436,6 @@ const getOrg = async () =&gt; {
396 console.error('获取组织下拉失败:', error); 436 console.error('获取组织下拉失败:', error);
397 } 437 }
398 }; 438 };
399 -  
400 const initChartData = async (beginTime: string, endTime: string) => { 439 const initChartData = async (beginTime: string, endTime: string) => {
401 try { 440 try {
402 const postData = { beginTime, endTime }; 441 const postData = { beginTime, endTime };
@@ -408,11 +447,10 @@ const initChartData = async (beginTime: string, endTime: string) =&gt; { @@ -408,11 +447,10 @@ const initChartData = async (beginTime: string, endTime: string) =&gt; {
408 console.error('图表数据请求失败:', error); 447 console.error('图表数据请求失败:', error);
409 } 448 }
410 }; 449 };
411 -  
412 -const loadDistanceApiTask = async (lon: string, lat: string) => { 450 +const loadDistanceApiTask = async (lon: string, lat: string, taskType: string) => {
413 try { 451 try {
414 - const paramsTodo = { queryType: 1, currentLon: lon, currentLat: lat };  
415 - const paramsDone = { queryType: 2, currentLon: lon, currentLat: lat }; 452 + const paramsTodo = { queryType: 1, currentLon: lon, currentLat: lat, taskType };
  453 + const paramsDone = { queryType: 2, currentLon: lon, currentLat: lat, taskType };
416 const [todoRes, doneRes] = await Promise.all([ 454 const [todoRes, doneRes] = await Promise.all([
417 taskDetailsWithDistance(paramsTodo), 455 taskDetailsWithDistance(paramsTodo),
418 taskDetailsWithDistance(paramsDone) 456 taskDetailsWithDistance(paramsDone)
@@ -433,11 +471,11 @@ const loadDistanceApiTask = async (lon: string, lat: string) =&gt; { @@ -433,11 +471,11 @@ const loadDistanceApiTask = async (lon: string, lat: string) =&gt; {
433 doneTotal.value = 0; 471 doneTotal.value = 0;
434 } 472 }
435 }; 473 };
436 -const loadSmartSortTask = async (lon: string, lat: string) => { 474 +const loadSmartSortTask = async (lon: string, lat: string, taskType: string) => {
437 try { 475 try {
438 const [todoRes, doneRes] = await Promise.all([ 476 const [todoRes, doneRes] = await Promise.all([
439 - taskDetailsWithSmartSort({ queryType: 1, currentLon: lon, currentLat: lat }),  
440 - taskDetailsWithSmartSort({ queryType: 2, currentLon: lon, currentLat: lat }) 477 + taskDetailsWithSmartSort({ queryType: 1, currentLon: lon, currentLat: lat, taskType }),
  478 + taskDetailsWithSmartSort({ queryType: 2, currentLon: lon, currentLat: lat, taskType })
441 ]); 479 ]);
442 todoFullList.value = todoRes?.sortedTasks || []; 480 todoFullList.value = todoRes?.sortedTasks || [];
443 doneFullList.value = doneRes?.sortedTasks || []; 481 doneFullList.value = doneRes?.sortedTasks || [];
@@ -459,22 +497,27 @@ const loadAllTaskByDept = async () =&gt; { @@ -459,22 +497,27 @@ const loadAllTaskByDept = async () =&gt; {
459 const loc = await getCurrentLocation(); 497 const loc = await getCurrentLocation();
460 currentLon.value = loc.lon; 498 currentLon.value = loc.lon;
461 currentLat.value = loc.lat; 499 currentLat.value = loc.lat;
462 - if (useDistanceApi.value) {  
463 - await loadDistanceApiTask(loc.lon, loc.lat);  
464 - } else {  
465 - await loadSmartSortTask(loc.lon, loc.lat);  
466 - }  
467 -};  
468 -  
469 -// 日期确认回调:更新图表 + 重新请求指标orgTaskIndicator  
470 -const handleDateConfirm = async (e: string[]) => {  
471 - dateRange.value = e;  
472 - await initChartData(e[0], e[1]);  
473 - if (value1.value) {  
474 - await fetchOrgIndicator(Number(value1.value), e[0], e[1]); 500 + // 根据一级Tab选择不同接口
  501 + if (mainTab.value === 'maintain') {
  502 + if (useDistanceApi.value) {
  503 + await loadDistanceApiTask(loc.lon, loc.lat, 'maintain');
  504 + } else {
  505 + await loadSmartSortTask(loc.lon, loc.lat, 'maintain');
  506 + }
  507 + } else if (mainTab.value === 'inspect') {
  508 + if (useDistanceApi.value) {
  509 + await loadDistanceApiTask(loc.lon, loc.lat, 'inspect');
  510 + } else {
  511 + await loadSmartSortTask(loc.lon, loc.lat, 'inspect');
  512 + }
  513 + } else if (mainTab.value === 'workorder') {
  514 + // ========= 工单tab,后续对接工单接口,先置空列表占位 =========
  515 + todoFullList.value = [];
  516 + doneFullList.value = [];
  517 + todoTotal.value = 0;
  518 + doneTotal.value = 0;
475 } 519 }
476 }; 520 };
477 -  
478 const getCurrentLocation = (): Promise<{ lon: string; lat: string }> => { 521 const getCurrentLocation = (): Promise<{ lon: string; lat: string }> => {
479 return new Promise((resolve, reject) => { 522 return new Promise((resolve, reject) => {
480 uni.getSetting({ 523 uni.getSetting({
@@ -533,7 +576,6 @@ const getCurrentLocation = (): Promise&lt;{ lon: string; lat: string }&gt; =&gt; { @@ -533,7 +576,6 @@ const getCurrentLocation = (): Promise&lt;{ lon: string; lat: string }&gt; =&gt; {
533 }); 576 });
534 }); 577 });
535 }; 578 };
536 -  
537 const handleMsgClick = () => { 579 const handleMsgClick = () => {
538 uni.navigateTo({ url: '/pages-sub/msg/msg' }); 580 uni.navigateTo({ url: '/pages-sub/msg/msg' });
539 }; 581 };
@@ -561,39 +603,34 @@ const handleTaskClick = (item: any) =&gt; { @@ -561,39 +603,34 @@ const handleTaskClick = (item: any) =&gt; {
561 } 603 }
562 } 604 }
563 }; 605 };
564 -  
565 onShow(async () => { 606 onShow(async () => {
566 showChartArea.value = true; 607 showChartArea.value = true;
567 chartWidth.value = rpx2px(750 - 60); 608 chartWidth.value = rpx2px(750 - 60);
568 chartHeight.value = rpx2px(300); 609 chartHeight.value = rpx2px(300);
569 initRecent7Days(); 610 initRecent7Days();
570 - getUnread(); 611 + // getUnread();
571 await getOrg(); // 拉取组织下拉列表 612 await getOrg(); // 拉取组织下拉列表
572 await loadAllTaskByDept(); 613 await loadAllTaskByDept();
573 }); 614 });
574 -  
575 onUnload(() => { 615 onUnload(() => {
576 if (scrollTimer) clearTimeout(scrollTimer); 616 if (scrollTimer) clearTimeout(scrollTimer);
577 }); 617 });
578 </script> 618 </script>
579 619
580 -  
581 -  
582 <style scoped lang="scss"> 620 <style scoped lang="scss">
583 $primary-color: #1677ff; 621 $primary-color: #1677ff;
584 $danger-color: #E53935; 622 $danger-color: #E53935;
585 $text-color: #333; 623 $text-color: #333;
586 $text-color-light: #666; 624 $text-color-light: #666;
587 -$text-color-placeholder: #999; 625 +$text-placeholder: #999;
588 $bg-color: #f5f5f7; 626 $bg-color: #f5f5f7;
589 $card-bg: #fff; 627 $card-bg: #fff;
590 -$border-radius: 16px;  
591 -$card-radius: 5px;  
592 -$spacing-sm: 5px;  
593 -$spacing-md: 10px;  
594 -$spacing-lg: 15px; 628 +$border-radius: 16rpx;
  629 +$card-radius: 5rpx;
  630 +$spacing-sm: 5rpx;
  631 +$spacing-md: 10rpx;
  632 +$spacing-lg: 15rpx;
595 $border-color: #e5e5e5; 633 $border-color: #e5e5e5;
596 -  
597 .page-container { 634 .page-container {
598 height: 100vh; 635 height: 100vh;
599 background-color: $bg-color; 636 background-color: $bg-color;
@@ -601,128 +638,134 @@ $border-color: #e5e5e5; @@ -601,128 +638,134 @@ $border-color: #e5e5e5;
601 display: flex; 638 display: flex;
602 flex-direction: column; 639 flex-direction: column;
603 } 640 }
604 -  
605 .user-info-bar { 641 .user-info-bar {
606 flex-shrink: 0; 642 flex-shrink: 0;
607 background: url("https://img.jichengshanshui.com.cn:28207/appimg/bg.jpg") no-repeat; 643 background: url("https://img.jichengshanshui.com.cn:28207/appimg/bg.jpg") no-repeat;
608 background-size: 100% 100%; 644 background-size: 100% 100%;
609 - padding: 80px $spacing-lg 135px; 645 + padding: 140rpx $spacing-lg 165rpx;
610 display: flex; 646 display: flex;
611 justify-content: space-between; 647 justify-content: space-between;
612 align-items: center; 648 align-items: center;
613 color: #fff; 649 color: #fff;
614 -  
615 .username { 650 .username {
616 - font-size: 16px;  
617 - margin-bottom: 4px; 651 + font-size: 32rpx;
  652 + margin-bottom: 4rpx;
618 } 653 }
619 -  
620 .login-desc { 654 .login-desc {
621 - font-size: 16px; 655 + font-size: 28rpx;
622 } 656 }
623 -  
624 .msg-icon { 657 .msg-icon {
625 position: relative; 658 position: relative;
626 - padding: 5px;  
627 - top: 10px; 659 + padding: 5rpx;
  660 + top: 10rpx;
628 border-radius: 50%; 661 border-radius: 50%;
629 -  
630 &--hover { 662 &--hover {
631 background-color: rgba(255, 255, 255, 0.2); 663 background-color: rgba(255, 255, 255, 0.2);
632 } 664 }
633 -  
634 .msg-badge { 665 .msg-badge {
635 position: absolute; 666 position: absolute;
636 - top: -2px;  
637 - right: -3px; 667 + top: -2rpx;
  668 + right: -3rpx;
638 } 669 }
639 } 670 }
640 } 671 }
641 -  
642 .content-wrap { 672 .content-wrap {
643 flex: 1; 673 flex: 1;
644 - margin-top: -122px; 674 + margin-top: -122rpx;
645 border-radius: $border-radius $border-radius 0 0; 675 border-radius: $border-radius $border-radius 0 0;
646 background-color: $bg-color; 676 background-color: $bg-color;
647 overflow: hidden; 677 overflow: hidden;
648 display: flex; 678 display: flex;
649 flex-direction: column; 679 flex-direction: column;
650 } 680 }
651 -  
652 .chart-wrap { 681 .chart-wrap {
653 flex-shrink: 0; 682 flex-shrink: 0;
654 transition: all 0.35s ease-out; 683 transition: all 0.35s ease-out;
655 opacity: 1; 684 opacity: 1;
656 overflow: hidden; 685 overflow: hidden;
  686 + &[hidden] {
  687 + opacity: 0;
  688 + height: 0;
  689 + margin: 0;
  690 + }
657 } 691 }
658 -  
659 -.chart-wrap[hidden] {  
660 - opacity: 0;  
661 - height: 0;  
662 - margin: 0;  
663 -}  
664 -  
665 .module-title { 692 .module-title {
666 padding: $spacing-lg; 693 padding: $spacing-lg;
667 - font-size: 14px; 694 + font-size: 28rpx;
668 font-weight: 600; 695 font-weight: 600;
669 color: $text-color-light; 696 color: $text-color-light;
670 flex-shrink: 0; 697 flex-shrink: 0;
671 } 698 }
672 -  
673 .task-chart-card { 699 .task-chart-card {
674 background-color: $card-bg; 700 background-color: $card-bg;
675 border-radius: $card-radius; 701 border-radius: $card-radius;
676 margin: 0 $spacing-lg $spacing-md; 702 margin: 0 $spacing-lg $spacing-md;
677 padding: $spacing-md; 703 padding: $spacing-md;
678 flex-shrink: 0; 704 flex-shrink: 0;
679 -  
680 .card-header { 705 .card-header {
681 display: flex; 706 display: flex;
682 justify-content: space-between; 707 justify-content: space-between;
683 align-items: center; 708 align-items: center;
684 - font-size: 12px;  
685 - color: $text-color-placeholder; 709 + font-size: 24rpx;
  710 + color: $text-placeholder;
686 margin-bottom: $spacing-md; 711 margin-bottom: $spacing-md;
687 -  
688 .date-picker-wrap { 712 .date-picker-wrap {
689 - border-radius: 3px; 713 + border-radius: 3rpx;
690 transition: background-color 0.2s; 714 transition: background-color 0.2s;
691 position: relative; 715 position: relative;
692 z-index: 999; 716 z-index: 999;
693 -  
694 &:active { 717 &:active {
695 background-color: $bg-color; 718 background-color: $bg-color;
696 } 719 }
697 } 720 }
698 } 721 }
699 -  
700 .chart-container { 722 .chart-container {
701 width: 100%; 723 width: 100%;
702 - height: 150px; 724 + height: 150rpx;
703 display: flex; 725 display: flex;
704 align-items: center; 726 align-items: center;
705 justify-content: center; 727 justify-content: center;
706 } 728 }
707 } 729 }
708 -  
709 .con-wrap { 730 .con-wrap {
710 - border-radius: 8px; 731 + border-radius: 8rpx;
711 background-color: #fff; 732 background-color: #fff;
712 - margin: 0 15px; 733 + margin: 0 15rpx;
713 flex: 1; 734 flex: 1;
714 min-height: 0; 735 min-height: 0;
715 display: flex; 736 display: flex;
716 flex-direction: column; 737 flex-direction: column;
717 overflow: hidden; 738 overflow: hidden;
718 } 739 }
719 -  
720 -.con-title {  
721 - padding: 10px 15px;  
722 - border-bottom: 1px solid #f0e9e9;  
723 - flex-shrink: 0; 740 +// ========= 【仅一级Tab:养护/巡检/工单】下划线样式,其余全部保留原有css =========
  741 +.main-tab-wrap {
  742 + display: flex;
  743 + align-items: center;
  744 + background: #fff;
  745 + padding: 0 30rpx;
724 } 746 }
725 - 747 +.main-tab-item {
  748 + padding: 24rpx 16rpx;
  749 + font-size: 30rpx;
  750 + color: #666;
  751 + position: relative;
  752 + transition: color 0.24s;
  753 + &.active {
  754 + color: #1677ff;
  755 + font-weight: 500;
  756 + &::after {
  757 + content: '';
  758 + position: absolute;
  759 + left: 0;
  760 + bottom: 0;
  761 + width: 100%;
  762 + height: 4rpx;
  763 + background-color: #1677ff;
  764 + border-radius: 2rpx;
  765 + }
  766 + }
  767 +}
  768 +// 待办/已办胶囊tab【原样保留你原来的样式,完全没改动!!】
726 .custom-tab-wrap { 769 .custom-tab-wrap {
727 display: flex; 770 display: flex;
728 align-items: center; 771 align-items: center;
@@ -731,88 +774,76 @@ $border-color: #e5e5e5; @@ -731,88 +774,76 @@ $border-color: #e5e5e5;
731 background: #fff; 774 background: #fff;
732 flex-shrink: 0; 775 flex-shrink: 0;
733 } 776 }
734 -  
735 .tab-capsule { 777 .tab-capsule {
736 padding: 10rpx 20rpx; 778 padding: 10rpx 20rpx;
737 - display: flex;  
738 - align-items: center;  
739 - justify-content: center;  
740 font-size: 28rpx; 779 font-size: 28rpx;
741 color: #999; 780 color: #999;
742 background: #f5f5f5; 781 background: #f5f5f5;
743 border-radius: 0; 782 border-radius: 0;
744 transition: all 0.2s ease; 783 transition: all 0.2s ease;
745 font-weight: 500; 784 font-weight: 500;
  785 + &.active {
  786 + color: #d4af37;
  787 + background: #fff8dc;
  788 + }
746 } 789 }
747 -  
748 -.tab-capsule.active {  
749 - color: #d4af37;  
750 - background: #fff8dc;  
751 -}  
752 -  
753 .tip-header { 790 .tip-header {
754 display: flex; 791 display: flex;
755 align-items: center; 792 align-items: center;
756 gap: 8rpx; 793 gap: 8rpx;
757 padding: 12rpx 15rpx; 794 padding: 12rpx 15rpx;
758 background: #e6f7ff; 795 background: #e6f7ff;
759 - font-size: 14px; 796 + font-size: 28rpx;
760 color: #000; 797 color: #000;
761 flex-shrink: 0; 798 flex-shrink: 0;
762 } 799 }
763 -  
764 .tip-top { 800 .tip-top {
765 - padding: 8px 0 0 70px; 801 + padding: 8rpx 0 0 70rpx;
766 flex-shrink: 0; 802 flex-shrink: 0;
767 } 803 }
768 -  
769 .task-list-container { 804 .task-list-container {
770 width: 100%; 805 width: 100%;
771 height: 100%; 806 height: 100%;
772 padding-bottom: 300rpx; 807 padding-bottom: 300rpx;
773 box-sizing: border-box; 808 box-sizing: border-box;
774 } 809 }
775 -  
776 .empty-box { 810 .empty-box {
777 padding: 60rpx 0; 811 padding: 60rpx 0;
778 } 812 }
779 -  
780 .sort-trigger { 813 .sort-trigger {
781 display: flex; 814 display: flex;
782 align-items: center; 815 align-items: center;
783 - font-size: 12px;  
784 - color: $text-color-placeholder; 816 + font-size: 24rpx;
  817 + color: $text-placeholder;
  818 + .sort-text {
  819 + white-space: nowrap;
  820 + overflow: hidden;
  821 + text-overflow: ellipsis;
  822 + max-width: 220rpx;
  823 + }
785 } 824 }
786 -  
787 -  
788 .task-item { 825 .task-item {
789 padding: $spacing-md; 826 padding: $spacing-md;
790 transition: background-color 0.2s; 827 transition: background-color 0.2s;
791 - border-bottom: 1px solid $border-color;  
792 - 828 + border-bottom: 1rpx solid $border-color;
793 &:last-child { 829 &:last-child {
794 border-bottom: none; 830 border-bottom: none;
795 } 831 }
796 -  
797 &--hover { 832 &--hover {
798 background-color: $bg-color; 833 background-color: $bg-color;
799 } 834 }
800 -  
801 &__content { 835 &__content {
802 width: 100%; 836 width: 100%;
803 } 837 }
804 -  
805 .name-fixed-wrap { 838 .name-fixed-wrap {
806 display: flex; 839 display: flex;
807 } 840 }
808 -  
809 .task-item__name { 841 .task-item__name {
810 - width: 60px; 842 + width: 80rpx;
811 } 843 }
812 -  
813 .task-name-text { 844 .task-name-text {
814 flex: 1; 845 flex: 1;
815 - font-size: 14px; 846 + font-size: 24rpx;
816 color: $text-color; 847 color: $text-color;
817 display: -webkit-box; 848 display: -webkit-box;
818 -webkit-line-clamp: 2; 849 -webkit-line-clamp: 2;
@@ -820,49 +851,43 @@ $border-color: #e5e5e5; @@ -820,49 +851,43 @@ $border-color: #e5e5e5;
820 overflow: hidden; 851 overflow: hidden;
821 text-overflow: ellipsis; 852 text-overflow: ellipsis;
822 } 853 }
823 -  
824 &__name { 854 &__name {
825 - font-size: 15px; 855 + font-size: 24rpx;
826 color: $text-color; 856 color: $text-color;
827 display: inline-block; 857 display: inline-block;
828 } 858 }
829 -  
830 &__footer { 859 &__footer {
831 display: flex; 860 display: flex;
832 align-items: flex-start; 861 align-items: flex-start;
833 gap: 6rpx; 862 gap: 6rpx;
834 - font-size: 13px; 863 + font-size: 24rpx;
835 color: $text-color-light; 864 color: $text-color-light;
836 margin-top: $spacing-sm; 865 margin-top: $spacing-sm;
837 align-items: center; 866 align-items: center;
838 } 867 }
839 } 868 }
840 -  
841 .loc-icon { 869 .loc-icon {
842 - width: 20px;  
843 - height: 20px; 870 + width: 28rpx;
  871 + height: 28rpx;
844 } 872 }
845 -  
846 .urgency-tag { 873 .urgency-tag {
847 color: #7D7D7D; 874 color: #7D7D7D;
848 } 875 }
849 -  
850 .grid-item-icon-box { 876 .grid-item-icon-box {
851 - display:flex;  
852 - flex-direction:column;  
853 - align-items:center;  
854 - padding:16rpx; 877 + display: flex;
  878 + flex-direction: column;
  879 + align-items: center;
  880 + padding: 16rpx;
855 } 881 }
856 .grid-num-icon { 882 .grid-num-icon {
857 - font-size:40rpx;  
858 - font-weight:600;  
859 - color:#333;  
860 - margin-top:8rpx; 883 + font-size: 40rpx;
  884 + font-weight: 600;
  885 + color: #333;
  886 + margin-top: 8rpx;
861 } 887 }
862 .grid-label-icon { 888 .grid-label-icon {
863 - font-size:22rpx;  
864 - color:#666;  
865 - margin-top:4rpx; 889 + font-size: 22rpx;
  890 + color: #666;
  891 + margin-top: 4rpx;
866 } 892 }
867 -  
868 -</style>  
869 \ No newline at end of file 893 \ No newline at end of file
  894 +</style>