Commit 4570c70a1d9591941e882d2f01091a992c113b21

Authored by 刘淇
1 parent 4f475013

消息中心

api/user.js
@@ -55,8 +55,8 @@ export const refreshToken = (params) => { @@ -55,8 +55,8 @@ export const refreshToken = (params) => {
55 * 获得当前用户的未读站内信数量 55 * 获得当前用户的未读站内信数量
56 * @returns {Promise} 56 * @returns {Promise}
57 */ 57 */
58 -export const getMsg = () => {  
59 - return get('/app-api/system/notify-message/my-page') 58 +export const getMsg = (params) => {
  59 + return get('/app-api/system/notify-message/my-page',params)
60 } 60 }
61 61
62 /** 62 /**
pages-sub/daily/quick-order/add-order.vue
@@ -149,6 +149,7 @@ @@ -149,6 +149,7 @@
149 <view class="fixed-bottom-btn-wrap"> 149 <view class="fixed-bottom-btn-wrap">
150 <up-button 150 <up-button
151 type="primary" 151 type="primary"
  152 + size="large"
152 text="提交工单" 153 text="提交工单"
153 @click="submitWorkOrder" 154 @click="submitWorkOrder"
154 ></up-button> 155 ></up-button>
pages-sub/daily/quick-order/index.vue
@@ -60,7 +60,7 @@ @@ -60,7 +60,7 @@
60 </view> 60 </view>
61 <view class="u-body-item u-flex"> 61 <view class="u-body-item u-flex">
62 <view class="u-body-item-title">工单位置:</view> 62 <view class="u-body-item-title">工单位置:</view>
63 - <view class="u-line-1 u-body-value">{{ item.roadName || '-' }}</view> 63 + <view class="u-line-1 u-body-value">{{ item.lonLatAddress || '-' }}</view>
64 </view> 64 </view>
65 65
66 <view class="u-body-item u-flex "> 66 <view class="u-body-item u-flex ">
pages-sub/daily/quick-order/order-detail.vue
@@ -30,12 +30,27 @@ @@ -30,12 +30,27 @@
30 align="middle" 30 align="middle"
31 > 31 >
32 <template #title> 32 <template #title>
33 - <view style="min-width: 200rpx">工单位置</view> 33 + <view style="min-width: 200rpx">工单道路</view>
34 </template> 34 </template>
35 <template #value> 35 <template #value>
36 <view class="up-line-1 common-text-color" >{{orderDetail.roadName || '--'}}</view> 36 <view class="up-line-1 common-text-color" >{{orderDetail.roadName || '--'}}</view>
37 </template> 37 </template>
38 38
  39 +
  40 + </up-cell>
  41 +
  42 +
  43 + <up-cell
  44 + align="middle"
  45 + >
  46 + <template #title>
  47 + <view style="min-width: 200rpx">工单位置</view>
  48 + </template>
  49 + <template #value>
  50 + <view class="up-line-1 common-text-color" >{{orderDetail.lonLatAddress || '--'}}</view>
  51 + </template>
  52 + lonLatAddress
  53 +
39 </up-cell> 54 </up-cell>
40 55
41 <!-- 3. 工单名称 --> 56 <!-- 3. 工单名称 -->
pages-sub/msg/index.vue
1 <template> 1 <template>
2 <view class="user-center-page"> 2 <view class="user-center-page">
  3 + <z-paging
  4 + ref="paging"
  5 + v-model="dataList"
  6 + @query="queryList"
  7 + :auto-show-system-loading="true"
  8 +
  9 + >
  10 + <template #empty>
  11 + <empty-view/>
  12 + </template>
3 <up-card 13 <up-card
4 :border="false" 14 :border="false"
5 :foot-border-top="false" 15 :foot-border-top="false"
6 - v-for="(item,index) in orderList" 16 + v-for="(item,index) in dataList"
7 :key="`${item.orderNo}_${index}`" 17 :key="`${item.orderNo}_${index}`"
8 :show-head="false" 18 :show-head="false"
9 > 19 >
@@ -11,17 +21,18 @@ @@ -11,17 +21,18 @@
11 <template #body> 21 <template #body>
12 <view class="card-body"> 22 <view class="card-body">
13 <view class="u-flex common-item-center common-justify-between" style="font-size: 14px;margin-top: 5px;"> 23 <view class="u-flex common-item-center common-justify-between" style="font-size: 14px;margin-top: 5px;">
14 - <view class="u-line-1" style="flex: 1;margin-right: 20px;color: #333"> {{ item.orderName || '无' }}</view> 24 + <view class="u-line-1" style="flex: 1;margin-right: 20px;color: #333"> {{ item.templateCode || '无' }}</view>
15 <view style="color: #000">{{ timeFormat(item.createTime, 'yyyy-mm-dd hh:MM:ss') }}</view> 25 <view style="color: #000">{{ timeFormat(item.createTime, 'yyyy-mm-dd hh:MM:ss') }}</view>
16 </view> 26 </view>
17 <view class="u-line-1 "> 27 <view class="u-line-1 ">
18 - {{ item.remark || '无' }} 28 + {{ item.templateContent || '无' }}
19 </view> 29 </view>
20 30
21 31
22 </view> 32 </view>
23 </template> 33 </template>
24 </up-card> 34 </up-card>
  35 + </z-paging>
25 </view> 36 </view>
26 </template> 37 </template>
27 38
@@ -35,25 +46,31 @@ const userStore = useUserStore() @@ -35,25 +46,31 @@ const userStore = useUserStore()
35 import { timeFormat } from '@/uni_modules/uview-plus'; 46 import { timeFormat } from '@/uni_modules/uview-plus';
36 // 计算属性获取用户信息(响应式) 47 // 计算属性获取用户信息(响应式)
37 const userInfo = computed(() => userStore.userInfo.user || {}) 48 const userInfo = computed(() => userStore.userInfo.user || {})
38 -const orderList = ref([  
39 - {  
40 - orderNo:'123',  
41 - orderName:'阜成门内大街巡检阜成门内大街巡检阜成门内大街巡检阜成门内大街巡检阜成门内大街巡检阜成门内大街巡检',  
42 - remark:'阜成门内大街周期计划即将到期,请及时处理。阜成门内大街周期计划即将到期,请及时处理。阜成门内大街周期计划即将到期,请及时处理。阜成门内大街周期计划即将到期,请及时处理。',  
43 - createTime:'1736160000000'  
44 - },  
45 - {  
46 - orderNo:'1223',  
47 - orderName:'阜成门内大街巡检阜成门内大街巡检阜成门内大街巡检阜成门内大街巡检阜成门内大街巡检阜成门内大街巡检',  
48 - remark:'阜成门内大街周期计划即将到期,请及时处理。阜成门内大街周期计划即将到期,请及时处理。阜成门内大街周期计划即将到期,请及时处理。阜成门内大街周期计划即将到期,请及时处理。',  
49 - createTime:'1736160000000' 49 +
  50 +const paging = ref(null);
  51 +const dataList = ref([]);
  52 +// 分页查询列表
  53 +const queryList = async (pageNo, pageSize) => {
  54 + try {
  55 + const apiParams = {
  56 + readStatus: false,
  57 + pageNo,
  58 + pageSize,
  59 + };
  60 + const res = await getMsg(apiParams)
  61 + // 适配z-paging分页
  62 + paging.value.complete(res.list, res.total);
  63 + } catch (error) {
  64 + console.error('加载工单失败:', error);
  65 + paging.value?.complete(false);
  66 + uni.showToast({title: res.msg||'加载失败,请重试', icon: 'none'});
50 } 67 }
51 -]) 68 +};
52 69
53 -// 页面显示时检查登录状态  
54 -onShow( async () => {  
55 - const res = await getMsg()  
56 -}) 70 +// // 页面显示时检查登录状态
  71 +// onShow( async () => {
  72 +// const res = await getMsg()
  73 +// })
57 </script> 74 </script>
58 75
59 76
pages-sub/problem/work-order-manage/index.vue
@@ -391,6 +391,16 @@ const handleSearch = (val) =&gt; { @@ -391,6 +391,16 @@ const handleSearch = (val) =&gt; {
391 searchValue.value = val; 391 searchValue.value = val;
392 paging.value?.reload(); // 搜索刷新列表 392 paging.value?.reload(); // 搜索刷新列表
393 }; 393 };
  394 +// const isRefreshing = ref(false);
  395 +// const refreshList = () => {
  396 +// if (isRefreshing.value) return;
  397 +// isRefreshing.value = true;
  398 +// paging.value?.reload().finally(() => {
  399 +// setTimeout(() => {
  400 +// isRefreshing.value = false;
  401 +// }, 500);
  402 +// });
  403 +// };
394 // 工单详情 404 // 工单详情
395 const handleDetail = (item) => { 405 const handleDetail = (item) => {
396 // 0-待办 1我发起的- 2-已办 406 // 0-待办 1我发起的- 2-已办
@@ -513,7 +523,7 @@ const handleProcess = async (item) =&gt; { @@ -513,7 +523,7 @@ const handleProcess = async (item) =&gt; {
513 } 523 }
514 } catch (error) { 524 } catch (error) {
515 console.error('处理工单失败:', error); 525 console.error('处理工单失败:', error);
516 - uni.showToast({title: '处理失败,请重试', icon: 'none'}); 526 + uni.showToast({title: error.msg||'处理失败,请重试', icon: 'none'});
517 } 527 }
518 }; 528 };
519 529
@@ -574,7 +584,7 @@ const confirmReject = async () =&gt; { @@ -574,7 +584,7 @@ const confirmReject = async () =&gt; {
574 paging.value?.reload(); // 刷新列表 584 paging.value?.reload(); // 刷新列表
575 } catch (error) { 585 } catch (error) {
576 console.error('回退工单失败:', error); 586 console.error('回退工单失败:', error);
577 - uni.showToast({title: '网络异常,回退失败', icon: 'none', duration: 1000}); 587 + uni.showToast({title: error.msg||'回退失败', icon: 'none', duration: 1000});
578 } finally { 588 } finally {
579 // 隐藏加载中 589 // 隐藏加载中
580 uni.hideLoading(); 590 uni.hideLoading();
@@ -641,7 +651,7 @@ const handleAcceptModalConfirm = async () =&gt; { @@ -641,7 +651,7 @@ const handleAcceptModalConfirm = async () =&gt; {
641 } catch (error) { 651 } catch (error) {
642 // 5. 操作失败处理 652 // 5. 操作失败处理
643 console.error('验收失败:', error); 653 console.error('验收失败:', error);
644 - uni.showToast({title: '验收提交失败,请重试', icon: 'none', duration: 1000}); 654 + uni.showToast({title: error.msg||'验收提交失败,请重试', icon: 'none', duration: 1000});
645 } 655 }
646 }; 656 };
647 657
pages-sub/problem/work-order-manage/order-detail.vue
@@ -63,7 +63,6 @@ @@ -63,7 +63,6 @@
63 </template> 63 </template>
64 </up-cell> 64 </up-cell>
65 65
66 -  
67 <!-- 情况描述 --> 66 <!-- 情况描述 -->
68 <up-cell> 67 <up-cell>
69 <template #title> 68 <template #title>
@@ -101,10 +100,6 @@ @@ -101,10 +100,6 @@
101 </template> 100 </template>
102 </up-cell> 101 </up-cell>
103 102
104 -  
105 -  
106 -  
107 -  
108 <!-- 问题照片 --> 103 <!-- 问题照片 -->
109 <up-cell title="问题照片"> 104 <up-cell title="问题照片">
110 <template #value> 105 <template #value>
@@ -114,7 +109,6 @@ @@ -114,7 +109,6 @@
114 :urls="orderDetail.problemsImgs.slice(0, 3)" 109 :urls="orderDetail.problemsImgs.slice(0, 3)"
115 :singleSize="70" 110 :singleSize="70"
116 :multipleSize="70" 111 :multipleSize="70"
117 -  
118 :preview-full-image="true" 112 :preview-full-image="true"
119 ></up-album> 113 ></up-album>
120 <text v-else class="empty-text">暂无问题照片</text> 114 <text v-else class="empty-text">暂无问题照片</text>
@@ -204,16 +198,10 @@ @@ -204,16 +198,10 @@
204 <!-- 1. 原标题内容:节点名称 + 操作人 --> 198 <!-- 1. 原标题内容:节点名称 + 操作人 -->
205 <view class="step-title"> 199 <view class="step-title">
206 {{ item.name }} 200 {{ item.name }}
207 -<!-- <text class="operator-name">-->  
208 -<!-- {{-->  
209 -<!-- item.tasks && item.tasks[0]?.assigneeUser?.nickname ? '(' + item.tasks[0].assigneeUser.nickname + ')' : '(未知操作人)'-->  
210 -<!-- }}-->  
211 -<!-- </text>-->  
212 </view> 201 </view>
213 202
214 <!-- 2. 原描述内容:时间 + 处理说明(最多200字) --> 203 <!-- 2. 原描述内容:时间 + 处理说明(最多200字) -->
215 <view class="step-desc"> 204 <view class="step-desc">
216 -  
217 <view class="operator-name up-line-1"> 205 <view class="operator-name up-line-1">
218 处理人: 206 处理人:
219 <text>{{ item.tasks?.map(itemName => itemName.assigneeUser?.nickname).filter(Boolean).join(',') }}</text> 207 <text>{{ item.tasks?.map(itemName => itemName.assigneeUser?.nickname).filter(Boolean).join(',') }}</text>
@@ -242,7 +230,6 @@ @@ -242,7 +230,6 @@
242 :urls="item.tasks[0].attattmentUrls.slice(0, 3)" 230 :urls="item.tasks[0].attattmentUrls.slice(0, 3)"
243 :singleSize="70" 231 :singleSize="70"
244 :multipleSize="70" 232 :multipleSize="70"
245 -  
246 :preview-full-image="true" 233 :preview-full-image="true"
247 class="step-album" 234 class="step-album"
248 ></up-album> 235 ></up-album>
@@ -251,7 +238,6 @@ @@ -251,7 +238,6 @@
251 </template> 238 </template>
252 </up-steps-item> 239 </up-steps-item>
253 </template> 240 </template>
254 -  
255 </up-steps> 241 </up-steps>
256 242
257 <!-- 流程节点为空时的提示 --> 243 <!-- 流程节点为空时的提示 -->
@@ -280,7 +266,6 @@ @@ -280,7 +266,6 @@
280 nextStepMap[orderDetail.taskKey].btnText 266 nextStepMap[orderDetail.taskKey].btnText
281 }} 267 }}
282 </up-button> 268 </up-button>
283 -  
284 </view> 269 </view>
285 </view> 270 </view>
286 271
@@ -369,7 +354,6 @@ @@ -369,7 +354,6 @@
369 </view> 354 </view>
370 </view> 355 </view>
371 </up-modal> 356 </up-modal>
372 -  
373 </view> 357 </view>
374 </template> 358 </template>
375 359
@@ -469,6 +453,9 @@ const orderDetail = ref&lt;any&gt;({ @@ -469,6 +453,9 @@ const orderDetail = ref&lt;any&gt;({
469 materialImgs: [] 453 materialImgs: []
470 }); 454 });
471 455
  456 +// ========== 新增:声明eventChannel变量 ==========
  457 +const eventChannel = ref(null);
  458 +
472 /** 459 /**
473 * 当前激活的图片列表(无需函数调用,直接访问) 460 * 当前激活的图片列表(无需函数调用,直接访问)
474 */ 461 */
@@ -591,7 +578,6 @@ const rejectImgs = useUploadImgs({ @@ -591,7 +578,6 @@ const rejectImgs = useUploadImgs({
591 fieldName: 'rejectImgs' 578 fieldName: 'rejectImgs'
592 }) 579 })
593 580
594 -  
595 // ========== 验收弹窗相关状态(新增图片上传实例) ========== 581 // ========== 验收弹窗相关状态(新增图片上传实例) ==========
596 const acceptModalShow = ref(false); // 验收弹窗显示开关 582 const acceptModalShow = ref(false); // 验收弹窗显示开关
597 const acceptRadioValue = ref('0'); // 单选框值,默认0(通过) 583 const acceptRadioValue = ref('0'); // 单选框值,默认0(通过)
@@ -606,7 +592,6 @@ const acceptImgs = useUploadImgs({ @@ -606,7 +592,6 @@ const acceptImgs = useUploadImgs({
606 fieldName: 'acceptImgs' 592 fieldName: 'acceptImgs'
607 }) 593 })
608 594
609 -  
610 // ========== 生成临时key ========== 595 // ========== 生成临时key ==========
611 const generateTempKey = () => { 596 const generateTempKey = () => {
612 return 'renew_order_' + Date.now() + '_' + Math.floor(Math.random() * 10000); 597 return 'renew_order_' + Date.now() + '_' + Math.floor(Math.random() * 10000);
@@ -691,11 +676,12 @@ const confirmReject = async () =&gt; { @@ -691,11 +676,12 @@ const confirmReject = async () =&gt; {
691 uni.showToast({title: '回退成功', icon: 'success', duration: 1000}); 676 uni.showToast({title: '回退成功', icon: 'success', duration: 1000});
692 677
693 rejectModalShow.value = false; 678 rejectModalShow.value = false;
694 - // 重新获取工单详情,刷新页面  
695 - // await DetailQuery(taskId.value);  
696 - uni.reLaunch({  
697 - url: `/pages-sub/problem/work-order-manage/index`  
698 - }); 679 + // 修复:正确使用eventChannel通知列表页刷新
  680 + if (eventChannel.value) {
  681 + eventChannel.value.emit('needRefresh');
  682 + }
  683 + // 返回列表页
  684 + uni.navigateBack({delta: 1});
699 } catch (error) { 685 } catch (error) {
700 console.error('回退工单失败:', error); 686 console.error('回退工单失败:', error);
701 uni.showToast({title: '网络异常,回退失败', icon: 'none', duration: 1000}); 687 uni.showToast({title: '网络异常,回退失败', icon: 'none', duration: 1000});
@@ -711,7 +697,7 @@ const handleProcess = async (item: any) =&gt; { @@ -711,7 +697,7 @@ const handleProcess = async (item: any) =&gt; {
711 try { 697 try {
712 if (nextStepMap[item.taskKey]?.name == '养护组长分配') { 698 if (nextStepMap[item.taskKey]?.name == '养护组长分配') {
713 uni.navigateTo({ 699 uni.navigateTo({
714 - url: `/pages-sub/problem/work-order-manage/distribution-order?taskId=${item.taskId}&orderNo=${item.orderNo}&id=${item.id}` 700 + url: `/pages-sub/problem/work-order-manage/distribution-order?taskId=${item.taskId}&orderNo=${item.orderNo}&id=${item.id}&busiLine=${item.busiLine}`
715 }) 701 })
716 } 702 }
717 if (nextStepMap[item.taskKey]?.name == '养护员待实施') { 703 if (nextStepMap[item.taskKey]?.name == '养护员待实施') {
@@ -770,8 +756,12 @@ const handleProcess = async (item: any) =&gt; { @@ -770,8 +756,12 @@ const handleProcess = async (item: any) =&gt; {
770 // 调用回退工单接口 756 // 调用回退工单接口
771 const res = await universalApproval(requestData); 757 const res = await universalApproval(requestData);
772 uni.showToast({title: '结束成功', icon: 'success', duration: 1000}); 758 uni.showToast({title: '结束成功', icon: 'success', duration: 1000});
773 - // 重新获取工单详情,刷新页面  
774 - await DetailQuery(taskId.value); 759 +
  760 + // 通知列表页刷新
  761 + if (eventChannel.value) {
  762 + eventChannel.value.emit('needRefresh');
  763 + }
  764 + uni.navigateBack({delta: 1});
775 } else if (res.cancel) { 765 } else if (res.cancel) {
776 console.log("用户点击取消"); 766 console.log("用户点击取消");
777 } 767 }
@@ -780,7 +770,7 @@ const handleProcess = async (item: any) =&gt; { @@ -780,7 +770,7 @@ const handleProcess = async (item: any) =&gt; {
780 } 770 }
781 } catch (error) { 771 } catch (error) {
782 console.error('处理工单失败:', error); 772 console.error('处理工单失败:', error);
783 - uni.showToast({title: '处理失败,请重试', icon: 'none'}); 773 + uni.showToast({title: error.msg||'处理失败,请重试', icon: 'none'});
784 } 774 }
785 }; 775 };
786 776
@@ -830,22 +820,21 @@ const handleAcceptModalConfirm = async () =&gt; { @@ -830,22 +820,21 @@ const handleAcceptModalConfirm = async () =&gt; {
830 } 820 }
831 } 821 }
832 const acceptRes = await universalApproval(postData); 822 const acceptRes = await universalApproval(postData);
833 - // 4. 操作成功处理  
834 823
835 handleAcceptModalCancel(); // 清空状态 824 handleAcceptModalCancel(); // 清空状态
836 - // 重新获取工单详情,刷新页面  
837 - // await DetailQuery(taskId.value);  
838 - // uni.reLaunch({  
839 - // url: `/pages-sub/problem/work-order-manage/index`  
840 - // });  
841 - eventChannel.emit('needRefresh');  
842 - // 4. 返回列表页 825 +
  826 + // 通知列表页刷新
  827 + if (eventChannel.value) {
  828 + eventChannel.value.emit('needRefresh');
  829 + }
  830 + // 返回列表页
843 uni.navigateBack({delta: 1}); 831 uni.navigateBack({delta: 1});
  832 +
844 uni.showToast({title: '提交成功', icon: 'success', duration: 1000}); 833 uni.showToast({title: '提交成功', icon: 'success', duration: 1000});
845 } catch (error) { 834 } catch (error) {
846 // 5. 操作失败处理 835 // 5. 操作失败处理
847 console.error('验收失败:', error); 836 console.error('验收失败:', error);
848 - uni.showToast({title: '验收提交失败,请重试', icon: 'none', duration: 1000}); 837 + uni.showToast({title: error.msg||'验收提交失败,请重试', icon: 'none', duration: 1000});
849 } 838 }
850 }; 839 };
851 840
@@ -856,6 +845,12 @@ onLoad((options: any) =&gt; { @@ -856,6 +845,12 @@ onLoad((options: any) =&gt; {
856 taskId.value = taskIdOpt || ''; 845 taskId.value = taskIdOpt || '';
857 activeTab.value = activeTabOpt || '0'; 846 activeTab.value = activeTabOpt || '0';
858 processInstanceId.value = processInstanceIdOpt; 847 processInstanceId.value = processInstanceIdOpt;
  848 +
  849 + // 初始化eventChannel
  850 + const pages = getCurrentPages();
  851 + const currentPage = pages[pages.length - 1];
  852 + eventChannel.value = currentPage.getOpenerEventChannel();
  853 +
859 DetailQuery(taskId.value); 854 DetailQuery(taskId.value);
860 }); 855 });
861 856
@@ -1062,6 +1057,4 @@ onShow(() =&gt; { @@ -1062,6 +1057,4 @@ onShow(() =&gt; {
1062 width: 70px !important; // 与多图保持一致 1057 width: 70px !important; // 与多图保持一致
1063 height: 70px !important; 1058 height: 70px !important;
1064 } 1059 }
1065 -  
1066 -  
1067 </style> 1060 </style>
1068 \ No newline at end of file 1061 \ No newline at end of file
pages/index/index.vue
@@ -18,7 +18,7 @@ @@ -18,7 +18,7 @@
18 18
19 <view class="content-wrap"> 19 <view class="content-wrap">
20 <!-- 任务完成情况标题 --> 20 <!-- 任务完成情况标题 -->
21 - <view class="module-title">任务完成情况(K线图)</view> 21 + <view class="module-title">任务完成情况</view>
22 22
23 <!-- 任务完成情况卡片 --> 23 <!-- 任务完成情况卡片 -->
24 <view class="task-chart-card"> 24 <view class="task-chart-card">
@@ -35,7 +35,7 @@ @@ -35,7 +35,7 @@
35 </view> 35 </view>
36 </view> 36 </view>
37 37
38 - <!-- 双折线K线图(匹配示例图) --> 38 + <!-- 双折线K线图 -->
39 <view class="chart-container"> 39 <view class="chart-container">
40 <uni-charts 40 <uni-charts
41 type="line" 41 type="line"
@@ -96,18 +96,14 @@ @@ -96,18 +96,14 @@
96 </template> 96 </template>
97 97
98 <script setup> 98 <script setup>
99 -import { ref, watch, computed, onMounted } from 'vue'; 99 +import { ref, watch, computed } from 'vue';
  100 +import { onShow } from '@dcloudio/uni-app'
100 import { useUserStore } from '@/pinia/user'; 101 import { useUserStore } from '@/pinia/user';
101 import { timeFormat } from '@/uni_modules/uview-plus'; 102 import { timeFormat } from '@/uni_modules/uview-plus';
102 import uniCharts from '@/components/uni-charts/uni-charts.vue'; 103 import uniCharts from '@/components/uni-charts/uni-charts.vue';
  104 +import { getUnreadCount } from "@/api/user";
103 105
104 // ========== 1. 常量抽离 ========== 106 // ========== 1. 常量抽离 ==========
105 -const FORMAT_CONST = {  
106 - DATE: 'MM.DD', // 匹配示例图的日期格式(12.28)  
107 - DATETIME: 'YYYY-MM-DD HH:mm',  
108 - TIME: 'HH:mm'  
109 -};  
110 -  
111 const URGENCY_MAP = { 107 const URGENCY_MAP = {
112 特急: 'urgent', 108 特急: 'urgent',
113 紧急: 'high', 109 紧急: 'high',
@@ -117,27 +113,28 @@ const URGENCY_MAP = { @@ -117,27 +113,28 @@ const URGENCY_MAP = {
117 }; 113 };
118 114
119 // ========== 2. 响应式数据 ========== 115 // ========== 2. 响应式数据 ==========
120 -const msgCount = ref(9999); 116 +const msgCount = ref();
121 const currentTab = ref('todo'); 117 const currentTab = ref('todo');
122 const dateRange = ref([]); 118 const dateRange = ref([]);
123 119
124 -// 双折线K线图专用数据 120 +// 折线图数据配置
125 const chartWidth = ref(0); 121 const chartWidth = ref(0);
126 const chartHeight = ref(300); 122 const chartHeight = ref(300);
127 -const klineCategories = ref([]); // X轴日期(12.28/12.29...) 123 +const klineCategories = ref([]); // X轴日期
128 const klineChartData = ref([ 124 const klineChartData = ref([
129 { 125 {
130 - name: '已完成任务数', // 匹配示例图的绿色折线 126 + name: '已完成任务数',
131 data: [], 127 data: [],
132 color: '#25AF69' 128 color: '#25AF69'
133 }, 129 },
134 { 130 {
135 - name: '待完成总任务数', // 匹配示例图的棕色折线 131 + name: '待完成总任务数',
136 data: [], 132 data: [],
137 color: '#B34C17' 133 color: '#B34C17'
138 } 134 }
139 ]); 135 ]);
140 -// 图表配置(匹配示例图样式) 136 +
  137 +// 图表配置
141 const klineOption = ref({ 138 const klineOption = ref({
142 grid: { 139 grid: {
143 top: '25%', 140 top: '25%',
@@ -150,15 +147,14 @@ const klineOption = ref({ @@ -150,15 +147,14 @@ const klineOption = ref({
150 }, 147 },
151 yAxis: { 148 yAxis: {
152 min: 0, 149 min: 0,
153 -  
154 splitLine: { lineStyle: { color: '#f5f5f7' } }, 150 splitLine: { lineStyle: { color: '#f5f5f7' } },
155 axisLabel: { fontSize: 12, color: '#666' } 151 axisLabel: { fontSize: 12, color: '#666' }
156 }, 152 },
157 tooltip: { 153 tooltip: {
158 trigger: 'axis', 154 trigger: 'axis',
159 formatter: (params) => { 155 formatter: (params) => {
160 - return `${params[0].name}<br  
161 - ${params[0].seriesName}: ${params[0].data}<br 156 + return `${params[0].name}<br/>
  157 + ${params[0].seriesName}: ${params[0].data}<br/>
162 ${params[1].seriesName}: ${params[1].data}`; 158 ${params[1].seriesName}: ${params[1].data}`;
163 } 159 }
164 }, 160 },
@@ -204,34 +200,31 @@ const initRecent7Days = () =&gt; { @@ -204,34 +200,31 @@ const initRecent7Days = () =&gt; {
204 dateRange.value = [sevenDaysAgo, now]; 200 dateRange.value = [sevenDaysAgo, now];
205 }; 201 };
206 202
  203 +const getUnread = async ()=>{
  204 + const res = await getUnreadCount()
  205 + console.log(res)
  206 + msgCount.value = res
  207 +}
  208 +
207 /** 209 /**
208 - * 初始化双折线K线数据(匹配示例图) 210 + * 初始化折线图数据
209 */ 211 */
210 -const fetchKlineData = async () => {  
211 - try {  
212 - // 模拟示例图数据(日期+已完成+待完成)  
213 - const rawData = [  
214 - { date: '12.21', done: 10, total: 110 },  
215 - { date: '12.22', done: 35, total: 70 },  
216 - { date: '12.23', done: 55, total: 728 },  
217 - { date: '12.24', done: 35, total: 65 },  
218 - { date: '12.25', done: 65, total: 78 },  
219 - { date: '12.26', done: 50, total: 272 },  
220 - { date: '12.22', done: 35, total: 70 },  
221 - { date: '12.23', done: 55, total: 78 },  
222 - { date: '12.24', done: 35, total: 65 },  
223 - { date: '12.25', done: 65, total: 78 },  
224 - { date: '12.26', done: 50, total: 72 },  
225 - { date: '12.27', done: 72, total: 92 }  
226 - ];  
227 -  
228 - // 转换为uni-charts格式  
229 - klineCategories.value = rawData.map(item => item.date);  
230 - klineChartData.value[0].data = rawData.map(item => item.done);  
231 - klineChartData.value[1].data = rawData.map(item => item.total);  
232 - } catch (error) {  
233 - wx.showToast({ title: '获取K线数据失败', icon: 'none' });  
234 - } 212 +const fetchKlineData = () => {
  213 + // 模拟数据
  214 + const rawData = [
  215 + { date: '12.21', done: 10, total: 110 },
  216 + { date: '12.22', done: 35, total: 70 },
  217 + { date: '12.23', done: 55, total: 728 },
  218 + { date: '12.24', done: 35, total: 65 },
  219 + { date: '12.25', done: 65, total: 78 },
  220 + { date: '12.26', done: 50, total: 272 },
  221 + { date: '12.27', done: 72, total: 92 }
  222 + ];
  223 +
  224 + // 转换为图表格式
  225 + klineCategories.value = rawData.map(item => item.date);
  226 + klineChartData.value[0].data = rawData.map(item => item.done);
  227 + klineChartData.value[1].data = rawData.map(item => item.total);
235 }; 228 };
236 229
237 // ========== 5. 业务逻辑 ========== 230 // ========== 5. 业务逻辑 ==========
@@ -256,19 +249,19 @@ const handleTaskClick = (item) =&gt; { @@ -256,19 +249,19 @@ const handleTaskClick = (item) =&gt; {
256 }; 249 };
257 250
258 // ========== 6. 生命周期 ========== 251 // ========== 6. 生命周期 ==========
259 -onMounted(() => { 252 +onShow(() => {
260 chartWidth.value = rpx2px(750 - 60); 253 chartWidth.value = rpx2px(750 - 60);
261 chartHeight.value = rpx2px(300); 254 chartHeight.value = rpx2px(300);
262 initRecent7Days(); 255 initRecent7Days();
263 fetchKlineData(); 256 fetchKlineData();
  257 + getUnread()
264 }); 258 });
265 </script> 259 </script>
266 260
267 <style scoped lang="scss"> 261 <style scoped lang="scss">
268 -/* 样式保持不变,无需修改 */ 262 +/* 样式变量 */
269 $primary-color: #1677ff; 263 $primary-color: #1677ff;
270 $danger-color: #E53935; 264 $danger-color: #E53935;
271 -$success-color: #4CAF50;  
272 $text-color: #333; 265 $text-color: #333;
273 $text-color-light: #666; 266 $text-color-light: #666;
274 $text-color-placeholder: #999; 267 $text-color-placeholder: #999;
@@ -297,14 +290,13 @@ $spacing-lg: 30rpx; @@ -297,14 +290,13 @@ $spacing-lg: 30rpx;
297 z-index: 1; 290 z-index: 1;
298 291
299 .username { 292 .username {
300 - font-size: 32rpx; 293 + font-size: 16px;
301 font-weight: 500; 294 font-weight: 500;
302 margin-bottom: 8rpx; 295 margin-bottom: 8rpx;
303 } 296 }
304 297
305 .login-desc { 298 .login-desc {
306 - font-size: 24rpx;  
307 - opacity: 0.8; 299 + font-size: 16px;
308 } 300 }
309 301
310 .msg-icon { 302 .msg-icon {
pages/workbench/index.vue
@@ -174,7 +174,7 @@ const handleMenuClick = (item: MenuItem) =&gt; { @@ -174,7 +174,7 @@ const handleMenuClick = (item: MenuItem) =&gt; {
174 top: 0; 174 top: 0;
175 left: 0; 175 left: 0;
176 width: 100%; 176 width: 100%;
177 - height: 280px; 177 + height: 260px;
178 background: url("https://img.jichengshanshui.com.cn:28207/appimg/bg.jpg") no-repeat; 178 background: url("https://img.jichengshanshui.com.cn:28207/appimg/bg.jpg") no-repeat;
179 background-size: 100% 100%; 179 background-size: 100% 100%;
180 z-index: 1; 180 z-index: 1;
@@ -183,7 +183,7 @@ const handleMenuClick = (item: MenuItem) =&gt; { @@ -183,7 +183,7 @@ const handleMenuClick = (item: MenuItem) =&gt; {
183 padding-left: 20px; 183 padding-left: 20px;
184 .welcome-text { 184 .welcome-text {
185 padding-top: 80px; 185 padding-top: 80px;
186 - font-size: 20px; 186 + font-size: 16px;
187 display: block; 187 display: block;
188 margin-bottom: 10px; 188 margin-bottom: 10px;
189 font-weight: 500; 189 font-weight: 500;
@@ -191,7 +191,7 @@ const handleMenuClick = (item: MenuItem) =&gt; { @@ -191,7 +191,7 @@ const handleMenuClick = (item: MenuItem) =&gt; {
191 191
192 .platform-name { 192 .platform-name {
193 margin-bottom: 10px; 193 margin-bottom: 10px;
194 - font-size: 20px; 194 + font-size: 16px;
195 display: block; 195 display: block;
196 opacity: 0.95; 196 opacity: 0.95;
197 } 197 }
@@ -200,7 +200,7 @@ const handleMenuClick = (item: MenuItem) =&gt; { @@ -200,7 +200,7 @@ const handleMenuClick = (item: MenuItem) =&gt; {
200 .content-wrap { 200 .content-wrap {
201 position: relative; 201 position: relative;
202 z-index: 2; 202 z-index: 2;
203 - padding: 150px 0 0; 203 + padding: 140px 0 0;
204 display: flex; 204 display: flex;
205 flex-direction: column; 205 flex-direction: column;
206 gap: 20rpx; 206 gap: 20rpx;