Commit 3da5bb94666325174474add84f0a3351cd4e501a

Authored by 王彪总
2 parents e93ebf16 9120066c

Merge remote-tracking branch 'origin/dev2.0' into dev2.0

# Conflicts:
#	App.vue
#	pages-sub/daily/maintain-manage/index.vue
#	pages-sub/daily/maintain-manage/now-list-page.vue
#	pages-sub/daily/maintain-manage/type-list-page.vue
#	pages-sub/problem/ai-manage/index.vue
#	pages-sub/problem/regional-order-manage/index.vue
#	pages-sub/problem/regional-order-manage/list-detail.vue
#	pages-sub/problem/regional-order-manage/order-detail.vue
#	pages-sub/problem/work-order-manage/index.vue
#	pages-sub/problem/work-order-manage/order-detail.vue
pages-sub/daily/maintain-manage/index.vue
@@ -80,6 +80,20 @@ @@ -80,6 +80,20 @@
80 80
81 <template #body> 81 <template #body>
82 <view class="card-body"> 82 <view class="card-body">
  83 +<!-- <view class="">-->
  84 +<!-- <up-button-->
  85 +<!-- type="primary"-->
  86 +<!-- size="mini"-->
  87 +<!-- @click="goToDetail(item)"-->
  88 +<!-- class="submit-record-btn"-->
  89 +<!-- >-->
  90 +<!-- 计划明细-->
  91 +<!-- </up-button>-->
  92 +<!-- </view>-->
  93 +
  94 + <view class="common-custom-btn" style="--btn-top: 48px;" @click="goToDetail(item)">
  95 + 养护任务
  96 + </view>
83 <!-- <view class="u-body-item u-flex">--> 97 <!-- <view class="u-body-item u-flex">-->
84 <!-- <view class="u-body-item-title">批次号:</view>--> 98 <!-- <view class="u-body-item-title">批次号:</view>-->
85 <!-- <view class="u-line-1 u-body-value">{{ item.batchNo || '-' }}</view>--> 99 <!-- <view class="u-line-1 u-body-value">{{ item.batchNo || '-' }}</view>-->
pages-sub/daily/maintain-manage/now-list-page.vue
1 <template> 1 <template>
2 - <view class="page-wrap">  
3 - <!-- 顶部提示栏 -->  
4 - <view class="tip-bar" v-if="isView==1" >  
5 - 一个任务可提交多次上报记录,每一次作业需如实上报。  
6 - </view>  
7 - <!-- 上报记录列表 -->  
8 - <view class="list-wrap" v-if="reportList.length > 0">  
9 - <view class="report-item" v-for="(item, index) in reportList[0].workRecords" :key="index">  
10 - <view class="item-title">【第{{ item.sortNum || (index + 1) }}次上报】{{ planName }}</view>  
11 - <view class="item-row item-row-bottom">  
12 - <view class="item-time">提交时间:{{ timeFormat(item.createTime,'yyyy-mm-dd hh:MM:ss')}}</view>  
13 - <view class="look-btn" @click="handleView(index,item,reportList[0])">查看</view>  
14 - </view>  
15 - </view>  
16 - </view>  
17 - <!-- 暂无数据 -->  
18 - <view class="empty-wrap" v-else>  
19 - <empty-view text="暂无数据"></empty-view>  
20 - </view>  
21 - <!-- 底部固定按钮 -->  
22 - <view class="fixed-bottom-btn-wrap" v-if="isView==1">  
23 - <up-button type="primary" size="large" block @click="handleAddReport">上报本次记录</up-button> 2 + <view class="page-wrap">
  3 + <!-- 顶部提示栏 -->
  4 + <view class="tip-bar" v-if="isView==1" >
  5 + 一个任务可提交多次上报记录,每一次作业需如实上报。
  6 + </view>
  7 + <!-- 上报记录列表 -->
  8 + <view class="list-wrap" v-if="reportList.length > 0">
  9 + <view class="report-item" v-for="(item, index) in reportList[0].workRecords" :key="index">
  10 + <view class="item-title">【第{{ item.sortNum || (index + 1) }}次上报】{{ planName }}</view>
  11 + <view class="item-row item-row-bottom">
  12 + <view class="item-time">提交时间:{{ timeFormat(item.createTime,'yyyy-mm-dd hh:MM:ss')}}</view>
  13 + <view class="look-btn" @click="handleView(index,item,reportList[0])">查看</view>
24 </view> 14 </view>
  15 + </view>
25 </view> 16 </view>
  17 + <!-- 暂无数据 -->
  18 + <view class="empty-wrap" v-else>
  19 + <empty-view text="暂无数据"></empty-view>
  20 + </view>
  21 + <!-- 底部固定按钮 -->
  22 + <view class="fixed-bottom-btn-wrap" v-if="isView==1">
  23 + <up-button type="primary" size="large" block @click="handleAddReport">上报本次记录</up-button>
  24 + </view>
  25 + </view>
26 </template> 26 </template>
27 <script setup lang="ts"> 27 <script setup lang="ts">
28 import { ref } from 'vue' 28 import { ref } from 'vue'
@@ -43,184 +43,184 @@ const currentCommitId = ref(&#39;&#39;) @@ -43,184 +43,184 @@ const currentCommitId = ref(&#39;&#39;)
43 43
44 // onLoad接收url传过来的planNo 44 // onLoad接收url传过来的planNo
45 onLoad((options) => { 45 onLoad((options) => {
46 - if (options.planNo) {  
47 - planNo.value = options.planNo  
48 - planTypeId.value = options.planTypeId  
49 - businessType.value = options.businessType  
50 - isView.value = options.isView  
51 - getReportList()  
52 - } else {  
53 - uni.showToast({ title: 'planNo参数缺失', icon: 'none' })  
54 - } 46 + if (options.planNo) {
  47 + planNo.value = options.planNo
  48 + planTypeId.value = options.planTypeId
  49 + businessType.value = options.businessType
  50 + isView.value = options.isView
  51 + getReportList()
  52 + } else {
  53 + uni.showToast({ title: 'planNo参数缺失', icon: 'none' })
  54 + }
55 }) 55 })
56 // 请求上报记录接口 56 // 请求上报记录接口
57 const getReportList = async () => { 57 const getReportList = async () => {
58 - console.log('3123')  
59 - uni.showLoading({ title: '加载中...', mask: true })  
60 - try {  
61 - // 传入planNo调取接口  
62 - let data = {  
63 - planNo: planNo.value,  
64 - pageNo: 1,  
65 - pageSize: 10  
66 - }  
67 - const res = await maintainPlanList(data)  
68 - // 接口返回list,无数据则reportList为空,页面自动显示empty  
69 - dataList.value = res?.list[0].workRecords  
70 - planName.value = res?.list[0].planName  
71 - reportList.value = res?.list || [] 58 + console.log('3123')
  59 + uni.showLoading({ title: '加载中...', mask: true })
  60 + try {
  61 + // 传入planNo调取接口
  62 + let data = {
  63 + planNo: planNo.value,
  64 + pageNo: 1,
  65 + pageSize: 10
  66 + }
  67 + const res = await maintainPlanList(data)
  68 + // 接口返回list,无数据则reportList为空,页面自动显示empty
  69 + dataList.value = res?.list[0].workRecords
  70 + planName.value = res?.list[0].planName
  71 + reportList.value = res?.list || []
72 72
73 -  
74 73
75 - // ============ 新增逻辑:寻找commitState ===1 的commitId ============  
76 - currentCommitId.value = ''  
77 - if(reportList.value.length > 0){  
78 - // 找到第一条 commitState ===1 的数据  
79 - const activeItem = reportList.value.find(item => item.commitState === 1)  
80 - if(activeItem){  
81 - currentCommitId.value = activeItem.commitId || ''  
82 - }  
83 - // 没有找到 activeItem,currentCommitId保持 ''  
84 - }  
85 - // reportList为空直接 currentCommitId=''  
86 74
87 - } catch (err) {  
88 - console.error('获取上报记录失败', err)  
89 - // uni.showToast({ title: '加载失败', icon: 'none' })  
90 - } finally {  
91 - uni.hideLoading() 75 + // ============ 新增逻辑:寻找commitState ===1 的commitId ============
  76 + currentCommitId.value = ''
  77 + if(reportList.value.length > 0){
  78 + // 找到第一条 commitState ===1 的数据
  79 + const activeItem = reportList.value.find(item => item.commitState === 1)
  80 + if(activeItem){
  81 + currentCommitId.value = activeItem.commitId || ''
  82 + }
  83 + // 没有找到 activeItem,currentCommitId保持 ''
92 } 84 }
  85 + // reportList为空直接 currentCommitId=''
  86 +
  87 + } catch (err) {
  88 + console.error('获取上报记录失败', err)
  89 + // uni.showToast({ title: '加载失败', icon: 'none' })
  90 + } finally {
  91 + uni.hideLoading()
  92 + }
93 } 93 }
94 // 查看上报详情 94 // 查看上报详情
95 const handleView = (index,item,i) => { 95 const handleView = (index,item,i) => {
96 - console.log('查看详情', item)  
97 - console.log('查看详情', index)  
98 - uni.navigateTo({  
99 - // 后端 page 接口支持 commitId 精确过滤,必须带上,否则会把该计划全部上报都展示出来  
100 - url: `/pages-sub/daily/maintain-manage/finish-plan-detail?planNo=${i.planNo}&commitId=${i.commitId}&index=${index}`  
101 - }) 96 + console.log('查看详情', item)
  97 + console.log('查看详情', index)
  98 + uni.navigateTo({
  99 + // 后端 page 接口支持 commitId 精确过滤,必须带上,否则会把该计划全部上报都展示出来
  100 + url: `/pages-sub/daily/maintain-manage/finish-plan-detail?planNo=${i.planNo}&commitId=${i.commitId}&index=${index}`
  101 + })
102 } 102 }
103 // 新增上报记录,把planNo + currentCommitId带到新增页面 103 // 新增上报记录,把planNo + currentCommitId带到新增页面
104 const handleAddReport = () => { 104 const handleAddReport = () => {
105 - console.log('上报本次记录', currentCommitId.value)  
106 - uni.navigateTo({  
107 - url: `/pages-sub/daily/maintain-manage/add-record?planNo=${planNo.value}&planTypeId=${planTypeId.value}&businessType=${businessType.value}&commitId=${currentCommitId.value}`  
108 - }) 105 + console.log('上报本次记录', currentCommitId.value)
  106 + uni.navigateTo({
  107 + url: `/pages-sub/daily/maintain-manage/add-record?planNo=${planNo.value}&planTypeId=${planTypeId.value}&businessType=${businessType.value}&commitId=${currentCommitId.value}`
  108 + })
109 } 109 }
110 </script> 110 </script>
111 <style scoped lang="scss"> 111 <style scoped lang="scss">
112 .page-wrap { 112 .page-wrap {
113 - min-height: 100vh;  
114 - // 底部固定栏(按钮 88rpx + 上下各 24rpx)+ 安全区  
115 - padding-bottom: calc(180rpx + constant(safe-area-inset-bottom));  
116 - padding-bottom: calc(180rpx + env(safe-area-inset-bottom));  
117 - background: #F4F6FA; 113 + min-height: 100vh;
  114 + // 底部固定栏(按钮 88rpx + 上下各 24rpx)+ 安全区
  115 + padding-bottom: calc(180rpx + constant(safe-area-inset-bottom));
  116 + padding-bottom: calc(180rpx + env(safe-area-inset-bottom));
  117 + background: #F4F6FA;
118 } 118 }
119 // 顶部提示条:浅蓝底 + 蓝字 + 圆形感叹号(设计稿 .banner) 119 // 顶部提示条:浅蓝底 + 蓝字 + 圆形感叹号(设计稿 .banner)
120 .tip-bar { 120 .tip-bar {
121 - display: flex;  
122 - align-items: flex-start;  
123 - gap: 12rpx;  
124 - margin: 24rpx 24rpx 0;  
125 - padding: 16rpx 24rpx;  
126 - background-color: #EBF3FF;  
127 - border-radius: 16rpx;  
128 - color: #2563EB;  
129 - font-size: 24rpx;  
130 - line-height: 1.6; 121 + display: flex;
  122 + align-items: flex-start;
  123 + gap: 12rpx;
  124 + margin: 24rpx 24rpx 0;
  125 + padding: 16rpx 24rpx;
  126 + background-color: #EBF3FF;
  127 + border-radius: 16rpx;
  128 + color: #2563EB;
  129 + font-size: 24rpx;
  130 + line-height: 1.6;
131 131
132 - &::before {  
133 - content: "!";  
134 - box-sizing: border-box;  
135 - flex: 0 0 auto;  
136 - width: 30rpx;  
137 - height: 30rpx;  
138 - margin-top: 4rpx;  
139 - line-height: 26rpx;  
140 - text-align: center;  
141 - font-size: 22rpx;  
142 - font-weight: 600;  
143 - color: #2563EB;  
144 - border: 2rpx solid #2563EB;  
145 - border-radius: 50%;  
146 - } 132 + &::before {
  133 + content: "!";
  134 + box-sizing: border-box;
  135 + flex: 0 0 auto;
  136 + width: 30rpx;
  137 + height: 30rpx;
  138 + margin-top: 4rpx;
  139 + line-height: 26rpx;
  140 + text-align: center;
  141 + font-size: 22rpx;
  142 + font-weight: 600;
  143 + color: #2563EB;
  144 + border: 2rpx solid #2563EB;
  145 + border-radius: 50%;
  146 + }
147 } 147 }
148 // 记录卡片列表:卡片之间 24rpx(设计稿 .body) 148 // 记录卡片列表:卡片之间 24rpx(设计稿 .body)
149 .list-wrap { 149 .list-wrap {
150 - display: flex;  
151 - flex-direction: column;  
152 - gap: 24rpx;  
153 - padding: 24rpx; 150 + display: flex;
  151 + flex-direction: column;
  152 + gap: 24rpx;
  153 + padding: 24rpx;
154 } 154 }
155 // 卡片:白底 / 8px 圆角 / 卡片阴影(设计稿 .card) 155 // 卡片:白底 / 8px 圆角 / 卡片阴影(设计稿 .card)
156 .report-item { 156 .report-item {
157 - padding: 24rpx;  
158 - background-color: #ffffff;  
159 - border-radius: 16rpx;  
160 - box-shadow: 0 4rpx 16rpx rgba(17, 24, 39, 0.06); 157 + padding: 24rpx;
  158 + background-color: #ffffff;
  159 + border-radius: 16rpx;
  160 + box-shadow: 0 4rpx 16rpx rgba(17, 24, 39, 0.06);
161 161
162 - .item-title {  
163 - font-size: 32rpx;  
164 - color: #1F2937;  
165 - font-weight: 500;  
166 - line-height: 1.4;  
167 - margin-bottom: 16rpx;  
168 - }  
169 - .item-row {  
170 - font-size: 26rpx;  
171 - color: #4B5563;  
172 - margin-bottom: 12rpx;  
173 - }  
174 - .item-row-bottom {  
175 - display: flex;  
176 - justify-content: space-between;  
177 - align-items: center;  
178 - margin-bottom: 0;  
179 - }  
180 - // 查看:次要操作,白底描边(设计稿 .btn 次级按钮)  
181 - .look-btn {  
182 - box-sizing: border-box;  
183 - display: flex;  
184 - align-items: center;  
185 - justify-content: center;  
186 - min-width: 120rpx;  
187 - height: 56rpx;  
188 - padding: 0 24rpx;  
189 - font-size: 24rpx;  
190 - color: #4B5563;  
191 - background-color: #ffffff;  
192 - border: 1rpx solid #E8EBF0;  
193 - border-radius: 8rpx;  
194 - flex-shrink: 0;  
195 - } 162 + .item-title {
  163 + font-size: 32rpx;
  164 + color: #1F2937;
  165 + font-weight: 500;
  166 + line-height: 1.4;
  167 + margin-bottom: 16rpx;
  168 + }
  169 + .item-row {
  170 + font-size: 26rpx;
  171 + color: #4B5563;
  172 + margin-bottom: 12rpx;
  173 + }
  174 + .item-row-bottom {
  175 + display: flex;
  176 + justify-content: space-between;
  177 + align-items: center;
  178 + margin-bottom: 0;
  179 + }
  180 + // 查看:次要操作,白底描边(设计稿 .btn 次级按钮)
  181 + .look-btn {
  182 + box-sizing: border-box;
  183 + display: flex;
  184 + align-items: center;
  185 + justify-content: center;
  186 + min-width: 120rpx;
  187 + height: 56rpx;
  188 + padding: 0 24rpx;
  189 + font-size: 24rpx;
  190 + color: #4B5563;
  191 + background-color: #ffffff;
  192 + border: 1rpx solid #E8EBF0;
  193 + border-radius: 8rpx;
  194 + flex-shrink: 0;
  195 + }
196 } 196 }
197 .empty-wrap { 197 .empty-wrap {
198 - padding-top: 120rpx; 198 + padding-top: 120rpx;
199 } 199 }
200 // 底部固定操作栏:白底 + 上分隔线 + 蓝色渐变主按钮(设计稿 .bar / .btn.pri) 200 // 底部固定操作栏:白底 + 上分隔线 + 蓝色渐变主按钮(设计稿 .bar / .btn.pri)
201 .fixed-bottom-btn-wrap { 201 .fixed-bottom-btn-wrap {
202 - position: fixed;  
203 - left: 0;  
204 - right: 0;  
205 - bottom: 0;  
206 - z-index: 10;  
207 - padding: 24rpx 24rpx calc(24rpx + constant(safe-area-inset-bottom));  
208 - padding-bottom: calc(24rpx + env(safe-area-inset-bottom));  
209 - background-color: #ffffff;  
210 - border-top: 1rpx solid #E8EBF0; 202 + position: fixed;
  203 + left: 0;
  204 + right: 0;
  205 + bottom: 0;
  206 + z-index: 10;
  207 + padding: 24rpx 24rpx calc(24rpx + constant(safe-area-inset-bottom));
  208 + padding-bottom: calc(24rpx + env(safe-area-inset-bottom));
  209 + background-color: #ffffff;
  210 + border-top: 1rpx solid #E8EBF0;
211 211
212 - :deep(.u-button) {  
213 - height: 88rpx !important;  
214 - border-radius: 16rpx !important;  
215 - border: none !important;  
216 - /* 与顶部导航栏同色 */  
217 - background-color: #2563EB !important;  
218 - background-image: none !important;  
219 - } 212 + :deep(.u-button) {
  213 + height: 88rpx !important;
  214 + border-radius: 16rpx !important;
  215 + border: none !important;
  216 + /* 与顶部导航栏同色 */
  217 + background-color: #2563EB !important;
  218 + background-image: none !important;
  219 + }
220 220
221 - :deep(.u-button__text) {  
222 - font-size: 30rpx !important;  
223 - font-weight: 500 !important;  
224 - } 221 + :deep(.u-button__text) {
  222 + font-size: 30rpx !important;
  223 + font-weight: 500 !important;
  224 + }
225 } 225 }
226 </style> 226 </style>
pages-sub/daily/maintain-manage/type-list-page.vue
1 <template> 1 <template>
2 - <view class="page-container">  
3 - <up-sticky>  
4 - <view class="sticky-wrap">  
5 - <up-tabs v-model="activeStatus" :list="statusTabs" line-width="44rpx" active-color="#2563EB"  
6 - inactive-color="#4B5563" :scrollable="false" @change="handleStatusChange"></up-tabs> 2 + <view class="page-container">
  3 + <up-sticky>
  4 + <view class="sticky-wrap">
  5 + <up-tabs v-model="activeStatus" :list="statusTabs" line-width="44rpx" active-color="#2563EB"
  6 + inactive-color="#4B5563" :scrollable="false" @change="handleStatusChange"></up-tabs>
  7 + </view>
  8 + </up-sticky>
  9 + <z-paging ref="pagingRef" v-model="currentList" @query="fetchData" :auto-show-system-loading="true">
  10 + <template #empty>
  11 + <empty-view />
  12 + </template>
  13 + <view class="card-list">
  14 + <view class="task-card" v-for="(item, index) in currentList" :key="`${item.planNo}_${index}`">
  15 + <!-- 计划名称 -->
  16 + <view class="card-head">
  17 + <view class="plan-name u-line-1">{{ item.planName || '无计划名称' }}</view>
  18 + </view>
  19 + <!-- 任务次数 -->
  20 + <view class="info-row">
  21 + <view class="info-label">任务次数</view>
  22 + <view class="info-value" v-if="activeStatus === '2'">完成 {{ item.planFinishNum }} 次</view>
  23 + <!-- 一次一条期次(planNum=1)时「第几次」取期次序号,历史多条次数的期次仍按完成次数递增 -->
  24 + <view class="info-value" v-else>第 {{ item.planNum === 1 ? (item.sortNum || 1) : (item.planFinishNum + 1) }} 次</view>
  25 + </view>
  26 + <!-- 有效期 -->
  27 + <view class="info-row">
  28 + <!-- timeFormat(start, 'yyyy-mm-dd'), -->
  29 + <view class="info-label">有效期</view>
  30 + <view class="info-value u-line-1">{{ timeFormat(item.beginTime, 'yyyy-mm-dd') }}—{{
  31 + timeFormat(item.endTime, 'yyyy-mm-dd') }}
7 </view> 32 </view>
8 - </up-sticky>  
9 - <z-paging ref="pagingRef" v-model="currentList" @query="fetchData" :auto-show-system-loading="true">  
10 - <template #empty>  
11 - <empty-view />  
12 - </template>  
13 - <view class="card-list">  
14 - <view class="task-card" v-for="(item, index) in currentList" :key="`${item.planNo}_${index}`">  
15 - <!-- 计划名称 -->  
16 - <view class="card-head">  
17 - <view class="plan-name u-line-1">{{ item.planName || '无计划名称' }}</view>  
18 - </view>  
19 - <!-- 任务次数 -->  
20 - <view class="info-row">  
21 - <view class="info-label">任务次数</view>  
22 - <view class="info-value" v-if="activeStatus === '2'">完成 {{ item.planFinishNum }} 次</view>  
23 - <!-- 一次一条期次(planNum=1)时「第几次」取期次序号,历史多条次数的期次仍按完成次数递增 -->  
24 - <view class="info-value" v-else>第 {{ item.planNum === 1 ? (item.sortNum || 1) : (item.planFinishNum + 1) }} 次</view>  
25 - </view>  
26 - <!-- 有效期 -->  
27 - <view class="info-row">  
28 - <!-- timeFormat(start, 'yyyy-mm-dd'), -->  
29 - <view class="info-label">有效期</view>  
30 - <view class="info-value u-line-1">{{ timeFormat(item.beginTime, 'yyyy-mm-dd') }}—{{  
31 - timeFormat(item.endTime, 'yyyy-mm-dd') }}  
32 - </view>  
33 - </view>  
34 - <!-- 操作区:统一收底,与信息区用分隔线隔开 -->  
35 - <view class="action-row">  
36 - <!-- 待完成且一次都没上报过才允许置为失效;已有养护记录(进行中/已完成过)不再显示 -->  
37 - <view v-if="activeStatus === '1' && !hasReport(item)" class="mini-btn btn-brand-soft"  
38 - @click.stop="handleSetInvalid(item)">  
39 - 置为失效  
40 - </view>  
41 - <view class="action-right">  
42 - <!-- ✅ 修改:去掉item.commitId判断,待完成tab就一直展示结束任务 -->  
43 - <view v-if="activeStatus === '1'" class="mini-btn btn-brand-outline"  
44 - @click.stop="handleEndTask(item)">结束任务</view>  
45 - <!-- 待完成:去作业;已完成:去查看 -->  
46 - <view v-if="activeStatus === '1'" class="mini-btn btn-brand-solid" @click.stop="handleGoWork(item)">去作业</view>  
47 - <view v-else-if="activeStatus === '2'" class="mini-btn mini-btn--info" @click.stop="handleGoWorkLook(item)">去查看</view>  
48 - <view v-else-if="activeStatus === '3'" class="mini-btn mini-btn--info" @click.stop="handleGoWorkLook(item)">去查看</view>  
49 - </view>  
50 - </view>  
51 - </view> 33 + </view>
  34 + <!-- 操作区:统一收底,与信息区用分隔线隔开 -->
  35 + <view class="action-row">
  36 + <!-- 待完成且一次都没上报过才允许置为失效;已有养护记录(进行中/已完成过)不再显示 -->
  37 + <view v-if="activeStatus === '1' && !hasReport(item)" class="mini-btn btn-brand-soft"
  38 + @click.stop="handleSetInvalid(item)">
  39 + 置为失效
52 </view> 40 </view>
53 - </z-paging>  
54 - <!-- ========== 置为失效 弹窗(必须填写失效原因) ========== -->  
55 - <up-modal :show="invalidModalShow" title="置为失效" :closeOnClickOverlay="false" :showConfirmButton="true"  
56 - :showCancelButton="true" @cancel="handleInvalidModalCancel" @confirm="confirmSetInvalid">  
57 - <view class="invalid-modal-content">  
58 - <view class="invalid-modal-label">  
59 - <text class="invalid-modal-required">*</text>  
60 - <text>失效原因</text>  
61 - </view>  
62 - <up-textarea v-model="invalidReason" placeholder="请输入失效原因" :maxlength="200" count  
63 - height="100" border="surround"></up-textarea>  
64 - <view class="invalid-modal-label">  
65 - <text>失效凭证(选填,最多3张)</text>  
66 - </view>  
67 - <up-upload :file-list="invalidImages" @after-read="uploadInvalidImgs"  
68 - @delete="deleteInvalidImg" @on-exceed="handleInvalidExceed" multiple :max-count="3"  
69 - upload-text="选择图片" del-color="#ff4d4f" class="upload-wrap"></up-upload> 41 + <view class="action-right">
  42 + <!-- ✅ 修改:去掉item.commitId判断,待完成tab就一直展示结束任务 -->
  43 + <view v-if="activeStatus === '1'" class="mini-btn btn-brand-outline"
  44 + @click.stop="handleEndTask(item)">结束任务</view>
  45 + <!-- 待完成:去作业;已完成:去查看 -->
  46 + <view v-if="activeStatus === '1'" class="mini-btn btn-brand-solid" @click.stop="handleGoWork(item)">去作业</view>
  47 + <view v-else-if="activeStatus === '2'" class="mini-btn mini-btn--info" @click.stop="handleGoWorkLook(item)">去查看</view>
  48 + <view v-else-if="activeStatus === '3'" class="mini-btn mini-btn--info" @click.stop="handleGoWorkLook(item)">去查看</view>
70 </view> 49 </view>
71 - </up-modal>  
72 - <!-- ========== 结束任务二次确认弹窗 ========== -->  
73 - <up-modal :show="endTaskModalShow" title="提示" :closeOnClickOverlay="false" :showConfirmButton="true"  
74 - :showCancelButton="true" @cancel="handleEndTaskModalCancel" @confirm="confirmEndTask">  
75 - <view class="end-task-modal-content">  
76 - <text>确定要结束吗?</text>  
77 - </view>  
78 - </up-modal>  
79 - </view> 50 + </view>
  51 + </view>
  52 + </view>
  53 + </z-paging>
  54 + <!-- ========== 置为失效 弹窗(必须填写失效原因) ========== -->
  55 + <up-modal :show="invalidModalShow" title="置为失效" :closeOnClickOverlay="false" :showConfirmButton="true"
  56 + :showCancelButton="true" @cancel="handleInvalidModalCancel" @confirm="confirmSetInvalid">
  57 + <view class="invalid-modal-content">
  58 + <view class="invalid-modal-label">
  59 + <text class="invalid-modal-required">*</text>
  60 + <text>失效原因</text>
  61 + </view>
  62 + <up-textarea v-model="invalidReason" placeholder="请输入失效原因" :maxlength="200" count
  63 + height="100" border="surround"></up-textarea>
  64 + <view class="invalid-modal-label">
  65 + <text>失效凭证(选填,最多3张)</text>
  66 + </view>
  67 + <up-upload :file-list="invalidImages" @after-read="uploadInvalidImgs"
  68 + @delete="deleteInvalidImg" @on-exceed="handleInvalidExceed" multiple :max-count="3"
  69 + upload-text="选择图片" del-color="#ff4d4f" class="upload-wrap"></up-upload>
  70 + </view>
  71 + </up-modal>
  72 + <!-- ========== 结束任务二次确认弹窗 ========== -->
  73 + <up-modal :show="endTaskModalShow" title="提示" :closeOnClickOverlay="false" :showConfirmButton="true"
  74 + :showCancelButton="true" @cancel="handleEndTaskModalCancel" @confirm="confirmEndTask">
  75 + <view class="end-task-modal-content">
  76 + <text>确定要结束吗?</text>
  77 + </view>
  78 + </up-modal>
  79 + </view>
80 </template> 80 </template>
81 <script setup lang="ts"> 81 <script setup lang="ts">
82 import { ref } from 'vue' 82 import { ref } from 'vue'
@@ -96,9 +96,9 @@ const getTodayStr = () =&gt; { @@ -96,9 +96,9 @@ const getTodayStr = () =&gt; {
96 // 有养护记录的任务不允许置为失效 96 // 有养护记录的任务不允许置为失效
97 const hasReport = (item: any) => !!item?.commitId || Number(item?.planFinishNum || 0) > 0 97 const hasReport = (item: any) => !!item?.commitId || Number(item?.planFinishNum || 0) > 0
98 const statusTabs = ref([ 98 const statusTabs = ref([
99 - { name: '待完成', id: '1' },  
100 - { name: '已失效', id: '3' },  
101 - { name: '已完成', id: '2' } 99 + { name: '待完成', id: '1' },
  100 + { name: '已失效', id: '3' },
  101 + { name: '已完成', id: '2' }
102 ]) 102 ])
103 const activeStatus = ref('1') 103 const activeStatus = ref('1')
104 const pagingRef = ref(null) 104 const pagingRef = ref(null)
@@ -119,339 +119,339 @@ const endTaskModalShow = ref(false) @@ -119,339 +119,339 @@ const endTaskModalShow = ref(false)
119 const currentEndTaskItem = ref<any>(null) 119 const currentEndTaskItem = ref<any>(null)
120 // 加载数据,根据当前activeStatus动态调用接口 120 // 加载数据,根据当前activeStatus动态调用接口
121 const loadData = async () => { 121 const loadData = async () => {
122 - console.log('123123')  
123 - if (!originRawList || originRawList.length === 0) {  
124 - // 没有批次时要显式结束分页,否则 z-paging 收不到 complete,页面一直停在加载中  
125 - allTotalData.value = []  
126 - pagingRef.value?.complete([], 0)  
127 - return 122 + console.log('123123')
  123 + if (!originRawList || originRawList.length === 0) {
  124 + // 没有批次时要显式结束分页,否则 z-paging 收不到 complete,页面一直停在加载中
  125 + allTotalData.value = []
  126 + pagingRef.value?.complete([], 0)
  127 + return
  128 + }
  129 + uni.showLoading({ title: '加载数据...', mask: true })
  130 + try {
  131 + const tempResult: any[] = []
  132 + // 获取需要请求的finishState数组
  133 + let stateArr: string[] = []
  134 + if (activeStatus.value === '1') {
  135 + // 待完成,只查1
  136 + stateArr = ['1']
  137 + } else if (activeStatus.value === '3') {
  138 + // 已失效,同时查3、4
  139 + stateArr = ['3', '4']
  140 + } else if (activeStatus.value === '2') {
  141 + // 已完成,只查2
  142 + stateArr = ['2']
128 } 143 }
129 - uni.showLoading({ title: '加载数据...', mask: true })  
130 - try {  
131 - const tempResult: any[] = []  
132 - // 获取需要请求的finishState数组  
133 - let stateArr: string[] = [] 144 + // 遍历state数组
  145 + for (const finishState of stateArr) {
  146 + // originRawList 为batchNo字符串数组,循环每一个batchNo去请求
  147 + for (const batchNoItem of originRawList) {
  148 + const apiParams: any = {
  149 + pageNo: 1,
  150 + pageSize: 10,
  151 + planNo: '',
  152 + planAttr: '',
  153 + finishState: finishState,
  154 + batchNo: batchNoItem
  155 + }
  156 + // 待完成状态追加当天日期 beginTime endTime
134 if (activeStatus.value === '1') { 157 if (activeStatus.value === '1') {
135 - // 待完成,只查1  
136 - stateArr = ['1']  
137 - } else if (activeStatus.value === '3') {  
138 - // 已失效,同时查3、4  
139 - stateArr = ['3', '4']  
140 - } else if (activeStatus.value === '2') {  
141 - // 已完成,只查2  
142 - stateArr = ['2'] 158 + const today = getTodayStr()
  159 + apiParams.beginTime = today
  160 + apiParams.endTime = today
143 } 161 }
144 - // 遍历state数组  
145 - for (const finishState of stateArr) {  
146 - // originRawList 为batchNo字符串数组,循环每一个batchNo去请求  
147 - for (const batchNoItem of originRawList) {  
148 - const apiParams: any = {  
149 - pageNo: 1,  
150 - pageSize: 10,  
151 - planNo: '',  
152 - planAttr: '',  
153 - finishState: finishState,  
154 - batchNo: batchNoItem  
155 - }  
156 - // 待完成状态追加当天日期 beginTime endTime  
157 - if (activeStatus.value === '1') {  
158 - const today = getTodayStr()  
159 - apiParams.beginTime = today  
160 - apiParams.endTime = today  
161 - }  
162 - const res = await maintainPlanNum(apiParams)  
163 - if (Array.isArray(res.list)) {  
164 - tempResult.push(...res.list)  
165 - }  
166 - } 162 + const res = await maintainPlanNum(apiParams)
  163 + if (Array.isArray(res.list)) {
  164 + tempResult.push(...res.list)
167 } 165 }
168 - allTotalData.value = tempResult  
169 - } catch (err) {  
170 - console.error('批量请求接口异常', err)  
171 - uni.showToast({ title: err.msg || '数据加载失败', icon: 'none', duration:2000 })  
172 - } finally {  
173 - uni.hideLoading()  
174 - pagingRef.value?.reload() 166 + }
175 } 167 }
  168 + allTotalData.value = tempResult
  169 + } catch (err) {
  170 + console.error('批量请求接口异常', err)
  171 + uni.showToast({ title: err.msg || '数据加载失败', icon: 'none', duration:2000 })
  172 + } finally {
  173 + uni.hideLoading()
  174 + pagingRef.value?.reload()
  175 + }
176 } 176 }
177 const planTypeId = ref('') 177 const planTypeId = ref('')
178 onLoad((options) => { 178 onLoad((options) => {
179 - planTypeId.value = options.planTypeId 179 + planTypeId.value = options.planTypeId
180 }); 180 });
181 // onShow 只保留一处,读取storage,originRawList接收batchNo字符串数组 181 // onShow 只保留一处,读取storage,originRawList接收batchNo字符串数组
182 onShow(async () => { 182 onShow(async () => {
183 - originRawList = uni.getStorageSync('temp_maintain_rawList') || []  
184 - await loadData() 183 + originRawList = uni.getStorageSync('temp_maintain_rawList') || []
  184 + await loadData()
185 }) 185 })
186 // z-paging分页查询,直接使用allTotalData 186 // z-paging分页查询,直接使用allTotalData
187 const fetchData = async (pageNo, pageSize) => { 187 const fetchData = async (pageNo, pageSize) => {
188 - await new Promise(resolve => setTimeout(resolve, 300))  
189 - const filterList = allTotalData.value  
190 - const start = (pageNo - 1) * pageSize  
191 - const pageData = filterList.slice(start, start + pageSize)  
192 - pagingRef.value?.complete(pageData, filterList.length) 188 + await new Promise(resolve => setTimeout(resolve, 300))
  189 + const filterList = allTotalData.value
  190 + const start = (pageNo - 1) * pageSize
  191 + const pageData = filterList.slice(start, start + pageSize)
  192 + pagingRef.value?.complete(pageData, filterList.length)
193 } 193 }
194 const handleStatusChange = async (tabItem) => { 194 const handleStatusChange = async (tabItem) => {
195 - activeStatus.value = tabItem.id  
196 - // 切换tab,重新拉接口  
197 - await loadData() 195 + activeStatus.value = tabItem.id
  196 + // 切换tab,重新拉接口
  197 + await loadData()
198 } 198 }
199 // 打开失效弹窗 199 // 打开失效弹窗
200 const handleSetInvalid = (item) => { 200 const handleSetInvalid = (item) => {
201 - currentInvalidItem.value = item  
202 - invalidReason.value = ''  
203 - invalidImages.value = []  
204 - invalidModalShow.value = true 201 + currentInvalidItem.value = item
  202 + invalidReason.value = ''
  203 + invalidImages.value = []
  204 + invalidModalShow.value = true
205 } 205 }
206 // 关闭弹窗,重置数据 206 // 关闭弹窗,重置数据
207 const handleInvalidModalCancel = () => { 207 const handleInvalidModalCancel = () => {
208 - invalidModalShow.value = false  
209 - currentInvalidItem.value = null  
210 - invalidReason.value = ''  
211 - invalidImages.value = [] 208 + invalidModalShow.value = false
  209 + currentInvalidItem.value = null
  210 + invalidReason.value = ''
  211 + invalidImages.value = []
212 } 212 }
213 // 失效凭证上传(最多 3 张,与 add-record 的图片上传保持一致) 213 // 失效凭证上传(最多 3 张,与 add-record 的图片上传保持一致)
214 const uploadInvalidImgs = async (event: any) => { 214 const uploadInvalidImgs = async (event: any) => {
215 - const fileList = Array.isArray(event.file) ? event.file : [event.file]  
216 - const validFiles = fileList.filter((item: any) => item && item.url)  
217 - if (!validFiles.length) return  
218 - const startIndex = invalidImages.value.length  
219 - invalidImages.value.push(...validFiles.map((item: any) => ({ ...item, status: 'uploading', message: '上传中' })))  
220 - try {  
221 - const urls = await uploadImages({ filePaths: validFiles.map((item: any) => item.url), ignoreError: true })  
222 - urls.forEach((url: string, index: number) => {  
223 - if (invalidImages.value[startIndex + index]) {  
224 - invalidImages.value.splice(startIndex + index, 1, {  
225 - ...validFiles[index], status: 'success', message: '', url  
226 - })  
227 - } 215 + const fileList = Array.isArray(event.file) ? event.file : [event.file]
  216 + const validFiles = fileList.filter((item: any) => item && item.url)
  217 + if (!validFiles.length) return
  218 + const startIndex = invalidImages.value.length
  219 + invalidImages.value.push(...validFiles.map((item: any) => ({ ...item, status: 'uploading', message: '上传中' })))
  220 + try {
  221 + const urls = await uploadImages({ filePaths: validFiles.map((item: any) => item.url), ignoreError: true })
  222 + urls.forEach((url: string, index: number) => {
  223 + if (invalidImages.value[startIndex + index]) {
  224 + invalidImages.value.splice(startIndex + index, 1, {
  225 + ...validFiles[index], status: 'success', message: '', url
228 }) 226 })
229 - for (let i = urls.length; i < validFiles.length; i++) {  
230 - if (invalidImages.value[startIndex + i]) {  
231 - invalidImages.value.splice(startIndex + i, 1, {  
232 - ...validFiles[i], status: 'failed', message: '上传失败'  
233 - })  
234 - }  
235 - }  
236 - if (urls.length < validFiles.length) {  
237 - uni.showToast({ title: `成功上传${urls.length}张,失败${validFiles.length - urls.length}张`, icon: 'none' })  
238 - }  
239 - } catch (err) {  
240 - console.error('失效凭证上传失败:', err)  
241 - for (let i = 0; i < validFiles.length; i++) {  
242 - if (invalidImages.value[startIndex + i]) {  
243 - invalidImages.value.splice(startIndex + i, 1, {  
244 - ...validFiles[i], status: 'failed', message: '上传失败'  
245 - })  
246 - }  
247 - }  
248 - uni.showToast({ title: '图片上传失败,请重试', icon: 'none' }) 227 + }
  228 + })
  229 + for (let i = urls.length; i < validFiles.length; i++) {
  230 + if (invalidImages.value[startIndex + i]) {
  231 + invalidImages.value.splice(startIndex + i, 1, {
  232 + ...validFiles[i], status: 'failed', message: '上传失败'
  233 + })
  234 + }
249 } 235 }
  236 + if (urls.length < validFiles.length) {
  237 + uni.showToast({ title: `成功上传${urls.length}张,失败${validFiles.length - urls.length}张`, icon: 'none' })
  238 + }
  239 + } catch (err) {
  240 + console.error('失效凭证上传失败:', err)
  241 + for (let i = 0; i < validFiles.length; i++) {
  242 + if (invalidImages.value[startIndex + i]) {
  243 + invalidImages.value.splice(startIndex + i, 1, {
  244 + ...validFiles[i], status: 'failed', message: '上传失败'
  245 + })
  246 + }
  247 + }
  248 + uni.showToast({ title: '图片上传失败,请重试', icon: 'none' })
  249 + }
250 } 250 }
251 const deleteInvalidImg = (event: any) => { 251 const deleteInvalidImg = (event: any) => {
252 - invalidImages.value.splice(event.index, 1) 252 + invalidImages.value.splice(event.index, 1)
253 } 253 }
254 const handleInvalidExceed = () => { 254 const handleInvalidExceed = () => {
255 - uni.showToast({ title: '最多只能上传3张图片', icon: 'none' }) 255 + uni.showToast({ title: '最多只能上传3张图片', icon: 'none' })
256 } 256 }
257 // 确认提交置为失效 257 // 确认提交置为失效
258 const confirmSetInvalid = async () => { 258 const confirmSetInvalid = async () => {
259 - const item = currentInvalidItem.value  
260 - console.log(currentInvalidItem.value)  
261 - if (!item) {  
262 - uni.showToast({ title: '数据异常', icon: 'none', duration:2000 })  
263 - return  
264 - }  
265 - // 失效原因必填:为空时不关闭弹窗、不发起任何请求  
266 - const reason = (invalidReason.value || '').trim()  
267 - if (!reason) {  
268 - uni.showToast({ title: '请填写失效原因', icon: 'none', duration:2000 })  
269 - return  
270 - }  
271 - // 图片还在上传时不能提交,否则会把空 url 或本地路径传给后端  
272 - if (invalidImages.value.some((file: any) => file.status === 'uploading')) {  
273 - uni.showToast({ title: '图片上传中,请稍候', icon: 'none', duration:2000 }) 259 + const item = currentInvalidItem.value
  260 + console.log(currentInvalidItem.value)
  261 + if (!item) {
  262 + uni.showToast({ title: '数据异常', icon: 'none', duration:2000 })
  263 + return
  264 + }
  265 + // 失效原因必填:为空时不关闭弹窗、不发起任何请求
  266 + const reason = (invalidReason.value || '').trim()
  267 + if (!reason) {
  268 + uni.showToast({ title: '请填写失效原因', icon: 'none', duration:2000 })
  269 + return
  270 + }
  271 + // 图片还在上传时不能提交,否则会把空 url 或本地路径传给后端
  272 + if (invalidImages.value.some((file: any) => file.status === 'uploading')) {
  273 + uni.showToast({ title: '图片上传中,请稍候', icon: 'none', duration:2000 })
  274 + return
  275 + }
  276 + const invalidFiles = invalidImages.value
  277 + .filter((file: any) => file.status === 'success' && file.url)
  278 + .map((file: any) => file.url)
  279 + uni.showLoading({ title: '提交中...', mask: true })
  280 + try {
  281 + let targetCommitId = item.commitId
  282 + // ✅ 如果没有 commitId,先执行 maintainCreate 创建草稿
  283 + if (!targetCommitId) {
  284 + const submitData = {
  285 + planNo: item.planNo,
  286 + imgHost: '1',
  287 + beginImg: [],
  288 + commonUserList: [],
  289 + remark: ''
  290 + }
  291 + const createRes: any = await maintainCreate(submitData)
  292 + // 兼容后端两种返回:裸id / {id:xxx}
  293 + targetCommitId = createRes && typeof createRes === 'object' ? createRes.id : createRes
  294 + if (!targetCommitId) {
  295 + uni.hideLoading()
  296 + uni.showToast({ title: '创建养护草稿失败,无法置为失效', icon: 'none', duration:2000 })
274 return 297 return
  298 + }
275 } 299 }
276 - const invalidFiles = invalidImages.value  
277 - .filter((file: any) => file.status === 'success' && file.url)  
278 - .map((file: any) => file.url)  
279 - uni.showLoading({ title: '提交中...', mask: true })  
280 - try {  
281 - let targetCommitId = item.commitId  
282 - // ✅ 如果没有 commitId,先执行 maintainCreate 创建草稿  
283 - if (!targetCommitId) {  
284 - const submitData = {  
285 - planNo: item.planNo,  
286 - imgHost: '1',  
287 - beginImg: [],  
288 - commonUserList: [],  
289 - remark: ''  
290 - }  
291 - const createRes: any = await maintainCreate(submitData)  
292 - // 兼容后端两种返回:裸id / {id:xxx}  
293 - targetCommitId = createRes && typeof createRes === 'object' ? createRes.id : createRes  
294 - if (!targetCommitId) {  
295 - uni.hideLoading()  
296 - uni.showToast({ title: '创建养护草稿失败,无法置为失效', icon: 'none', duration:2000 })  
297 - return  
298 - }  
299 - }  
300 - const params = {  
301 - commitId: targetCommitId,  
302 - // 使用弹窗中填写的原因(必填),不再写死默认文案  
303 - invalidReason: reason,  
304 - // 后端 invalidFiles 是 List<String>,无图时传空数组  
305 - invalidFiles  
306 - }  
307 - console.log('置为失效提交参数:', params)  
308 - await invalidatePlan(params)  
309 - uni.showToast({ title: '操作成功', icon: 'success', duration:2000 })  
310 - handleInvalidModalCancel()  
311 - // 重新加载数据刷新列表  
312 - await loadData()  
313 - pagingRef.value?.reload()  
314 - } catch (err) {  
315 - console.error(err)  
316 - uni.showToast({ title: err?.msg || '提交失败,请重试', icon: 'none', duration:2000 })  
317 - } finally {  
318 - uni.hideLoading() 300 + const params = {
  301 + commitId: targetCommitId,
  302 + // 使用弹窗中填写的原因(必填),不再写死默认文案
  303 + invalidReason: reason,
  304 + // 后端 invalidFiles 是 List<String>,无图时传空数组
  305 + invalidFiles
319 } 306 }
  307 + console.log('置为失效提交参数:', params)
  308 + await invalidatePlan(params)
  309 + uni.showToast({ title: '操作成功', icon: 'success', duration:2000 })
  310 + handleInvalidModalCancel()
  311 + // 重新加载数据刷新列表
  312 + await loadData()
  313 + pagingRef.value?.reload()
  314 + } catch (err) {
  315 + console.error(err)
  316 + uni.showToast({ title: err?.msg || '提交失败,请重试', icon: 'none', duration:2000 })
  317 + } finally {
  318 + uni.hideLoading()
  319 + }
320 } 320 }
321 const handleGoWork = (item) => { 321 const handleGoWork = (item) => {
322 const isView = activeStatus.value 322 const isView = activeStatus.value
323 - uni.navigateTo({  
324 - url: `/pages-sub/daily/maintain-manage/now-list-page?planNo=${item.planNo}&planTypeId=${planTypeId.value}&businessType=${item.busiLine}&isView=${isView}`  
325 - }) 323 + uni.navigateTo({
  324 + url: `/pages-sub/daily/maintain-manage/now-list-page?planNo=${item.planNo}&planTypeId=${planTypeId.value}&businessType=${item.busiLine}&isView=${isView}`
  325 + })
326 } 326 }
327 const handleGoWorkLook = (item) => { 327 const handleGoWorkLook = (item) => {
328 const isView = activeStatus.value 328 const isView = activeStatus.value
329 - uni.navigateTo({  
330 - url: `/pages-sub/daily/maintain-manage/finish-plan-detail?planNo=${item.planNo}&planTypeId=${planTypeId.value}&businessType=${item.busiLine}&isView=${isView}`  
331 - }) 329 + uni.navigateTo({
  330 + url: `/pages-sub/daily/maintain-manage/finish-plan-detail?planNo=${item.planNo}&planTypeId=${planTypeId.value}&businessType=${item.busiLine}&isView=${isView}`
  331 + })
332 } 332 }
333 const handleEndTask = async (item) => { 333 const handleEndTask = async (item) => {
334 - currentEndTaskItem.value = item  
335 - endTaskModalShow.value = true 334 + currentEndTaskItem.value = item
  335 + endTaskModalShow.value = true
336 } 336 }
337 // 关闭结束任务弹窗 337 // 关闭结束任务弹窗
338 const handleEndTaskModalCancel = () => { 338 const handleEndTaskModalCancel = () => {
339 - endTaskModalShow.value = false  
340 - currentEndTaskItem.value = null 339 + endTaskModalShow.value = false
  340 + currentEndTaskItem.value = null
341 } 341 }
342 // ✅改造confirmEndTask:没有commitId先maintainCreate,和置为失效逻辑保持一致 342 // ✅改造confirmEndTask:没有commitId先maintainCreate,和置为失效逻辑保持一致
343 const confirmEndTask = async () => { 343 const confirmEndTask = async () => {
344 - const item = currentEndTaskItem.value  
345 - if (!item) {  
346 - uni.showToast({ title: '数据异常', icon: 'none', duration:2000 })  
347 - return  
348 - }  
349 - endTaskModalShow.value = false  
350 - uni.showLoading({ title: '提交中...', mask: true })  
351 - try {  
352 - const targetCommitId = item.commitId  
353 - // 没有进行中的上报说明本次还没作业:后端结束任务要求至少一条正常作业记录,  
354 - // 先建草稿再结束必定失败,还会留下一条永远「进行中」的脏草稿,这里直接拦下。  
355 - if (!targetCommitId) {  
356 - uni.hideLoading()  
357 - uni.showToast({ title: '请先添加作业记录后再结束任务', icon: 'none', duration: 2000 })  
358 - return  
359 - }  
360 - await finishPlan({ commitId: targetCommitId })  
361 - uni.hideLoading()  
362 - uni.showToast({ title: '结束任务成功', icon: 'success', duration:2000 })  
363 - await loadData()  
364 - pagingRef.value?.reload()  
365 - } catch (err) {  
366 - console.error('结束任务失败', err)  
367 - uni.hideLoading()  
368 - uni.showToast({ title: err?.msg || '结束任务失败,请重试', icon: 'none', duration:2000 })  
369 - } finally {  
370 - currentEndTaskItem.value = null 344 + const item = currentEndTaskItem.value
  345 + if (!item) {
  346 + uni.showToast({ title: '数据异常', icon: 'none', duration:2000 })
  347 + return
  348 + }
  349 + endTaskModalShow.value = false
  350 + uni.showLoading({ title: '提交中...', mask: true })
  351 + try {
  352 + const targetCommitId = item.commitId
  353 + // 没有进行中的上报说明本次还没作业:后端结束任务要求至少一条正常作业记录,
  354 + // 先建草稿再结束必定失败,还会留下一条永远「进行中」的脏草稿,这里直接拦下。
  355 + if (!targetCommitId) {
  356 + uni.hideLoading()
  357 + uni.showToast({ title: '请先添加作业记录后再结束任务', icon: 'none', duration: 2000 })
  358 + return
371 } 359 }
  360 + await finishPlan({ commitId: targetCommitId })
  361 + uni.hideLoading()
  362 + uni.showToast({ title: '结束任务成功', icon: 'success', duration:2000 })
  363 + await loadData()
  364 + pagingRef.value?.reload()
  365 + } catch (err) {
  366 + console.error('结束任务失败', err)
  367 + uni.hideLoading()
  368 + uni.showToast({ title: err?.msg || '结束任务失败,请重试', icon: 'none', duration:2000 })
  369 + } finally {
  370 + currentEndTaskItem.value = null
  371 + }
372 } 372 }
373 // 页面卸载清空,防止内存残留 373 // 页面卸载清空,防止内存残留
374 onUnload(() => { 374 onUnload(() => {
375 - allTotalData.value = []  
376 - originRawList = [] 375 + allTotalData.value = []
  376 + originRawList = []
377 }) 377 })
378 </script> 378 </script>
379 <style scoped lang="scss"> 379 <style scoped lang="scss">
380 .page-container { 380 .page-container {
381 - height: 100vh;  
382 - background-color: #F4F6FA; 381 + height: 100vh;
  382 + background-color: #F4F6FA;
383 } 383 }
384 .sticky-wrap { 384 .sticky-wrap {
385 - background: #fff;  
386 - border-bottom: 1rpx solid #E8EBF0; 385 + background: #fff;
  386 + border-bottom: 1rpx solid #E8EBF0;
387 } 387 }
388 /* 卡片列表:页面左右 24rpx、卡片之间 24rpx(设计稿 .body) 388 /* 卡片列表:页面左右 24rpx、卡片之间 24rpx(设计稿 .body)
389 * 顶部留白 = 吸顶 Tabs 高度 + 12px 间距,z-paging 内容从容器顶部起算, 389 * 顶部留白 = 吸顶 Tabs 高度 + 12px 间距,z-paging 内容从容器顶部起算,
390 * 不留这段会被吸顶 Tabs 盖住卡片标题(与原页面 padding-top:100rpx 等效) */ 390 * 不留这段会被吸顶 Tabs 盖住卡片标题(与原页面 padding-top:100rpx 等效) */
391 .card-list { 391 .card-list {
392 - padding: 112rpx 24rpx 24rpx;  
393 - display: flex;  
394 - flex-direction: column;  
395 - gap: 24rpx; 392 + padding: 112rpx 24rpx 24rpx;
  393 + display: flex;
  394 + flex-direction: column;
  395 + gap: 24rpx;
396 } 396 }
397 /* 卡片:12px 内边距 / 8px 圆角 / 卡片阴影(设计稿 .tcard) */ 397 /* 卡片:12px 内边距 / 8px 圆角 / 卡片阴影(设计稿 .tcard) */
398 .task-card { 398 .task-card {
399 - background: #fff;  
400 - border-radius: 16rpx;  
401 - padding: 24rpx;  
402 - box-shadow: 0 4rpx 16rpx rgba(17, 24, 39, 0.06);  
403 - display: flex;  
404 - flex-direction: column; 399 + background: #fff;
  400 + border-radius: 16rpx;
  401 + padding: 24rpx;
  402 + box-shadow: 0 4rpx 16rpx rgba(17, 24, 39, 0.06);
  403 + display: flex;
  404 + flex-direction: column;
405 } 405 }
406 /* 标题行:标题占满剩余宽度,状态标签靠右(设计稿 .tcard-head) */ 406 /* 标题行:标题占满剩余宽度,状态标签靠右(设计稿 .tcard-head) */
407 .card-head { 407 .card-head {
408 - display: flex;  
409 - align-items: center;  
410 - gap: 16rpx;  
411 - margin-bottom: 16rpx; 408 + display: flex;
  409 + align-items: center;
  410 + gap: 16rpx;
  411 + margin-bottom: 16rpx;
412 } 412 }
413 .plan-name { 413 .plan-name {
414 - flex: 1;  
415 - min-width: 0;  
416 - font-size: 32rpx;  
417 - color: #1F2937;  
418 - font-weight: 500;  
419 - line-height: 1.4; 414 + flex: 1;
  415 + min-width: 0;
  416 + font-size: 32rpx;
  417 + color: #1F2937;
  418 + font-weight: 500;
  419 + line-height: 1.4;
420 } 420 }
421 .info-row { 421 .info-row {
422 - display: flex;  
423 - align-items: center;  
424 - justify-content: space-between;  
425 - gap: 16rpx;  
426 - margin-bottom: 6rpx; 422 + display: flex;
  423 + align-items: center;
  424 + justify-content: space-between;
  425 + gap: 16rpx;
  426 + margin-bottom: 6rpx;
427 } 427 }
428 .info-label { 428 .info-label {
429 - font-size: 26rpx;  
430 - color: #9CA3AF;  
431 - flex-shrink: 0; 429 + font-size: 26rpx;
  430 + color: #9CA3AF;
  431 + flex-shrink: 0;
432 } 432 }
433 .info-value { 433 .info-value {
434 - flex: 1;  
435 - min-width: 0;  
436 - font-size: 26rpx;  
437 - color: #4B5563;  
438 - text-align: right; 434 + flex: 1;
  435 + min-width: 0;
  436 + font-size: 26rpx;
  437 + color: #4B5563;
  438 + text-align: right;
439 } 439 }
440 /* 操作区统一收底:上 16rpx 留白 + 分隔线(设计稿 .tcard-foot) */ 440 /* 操作区统一收底:上 16rpx 留白 + 分隔线(设计稿 .tcard-foot) */
441 .action-row { 441 .action-row {
442 - display: flex;  
443 - align-items: center;  
444 - justify-content: space-between;  
445 - gap: 16rpx;  
446 - margin-top: 16rpx;  
447 - padding-top: 16rpx;  
448 - border-top: 1rpx solid #E8EBF0; 442 + display: flex;
  443 + align-items: center;
  444 + justify-content: space-between;
  445 + gap: 16rpx;
  446 + margin-top: 16rpx;
  447 + padding-top: 16rpx;
  448 + border-top: 1rpx solid #E8EBF0;
449 } 449 }
450 .action-right { 450 .action-right {
451 - display: flex;  
452 - align-items: center;  
453 - gap: 16rpx;  
454 - margin-left: auto; 451 + display: flex;
  452 + align-items: center;
  453 + gap: 16rpx;
  454 + margin-left: auto;
455 } 455 }
456 // 置为失效(红字)/ 去作业(蓝)/ 去查看(灰)/ 结束任务(白底描边) 456 // 置为失效(红字)/ 去作业(蓝)/ 去查看(灰)/ 结束任务(白底描边)
457 // 尺寸与配色统一由全局 .btn-text-danger、.mini-btn 系列控制 457 // 尺寸与配色统一由全局 .btn-text-danger、.mini-btn 系列控制
@@ -459,42 +459,42 @@ onUnload(() =&gt; { @@ -459,42 +459,42 @@ onUnload(() =&gt; {
459 * 浅底(置为失效) / 描边(结束任务) / 实心(去作业) 459 * 浅底(置为失效) / 描边(结束任务) / 实心(去作业)
460 * 需 !important 覆盖全局 .mini-btn 的白字与 .btn-text-danger 等既有配色 */ 460 * 需 !important 覆盖全局 .mini-btn 的白字与 .btn-text-danger 等既有配色 */
461 .btn-brand-soft { 461 .btn-brand-soft {
462 - color: #3b9dff !important;  
463 - background-color: #EAF4FF !important; 462 + color: #3b9dff !important;
  463 + background-color: #EAF4FF !important;
464 } 464 }
465 465
466 .btn-brand-outline { 466 .btn-brand-outline {
467 - color: #3b9dff !important;  
468 - background-color: #ffffff !important;  
469 - border: 1rpx solid #3b9dff; 467 + color: #3b9dff !important;
  468 + background-color: #ffffff !important;
  469 + border: 1rpx solid #3b9dff;
470 } 470 }
471 471
472 .btn-brand-solid { 472 .btn-brand-solid {
473 - color: #ffffff !important;  
474 - background-color: #3b9dff !important; 473 + color: #ffffff !important;
  474 + background-color: #3b9dff !important;
475 } 475 }
476 .invalid-modal-content { 476 .invalid-modal-content {
477 - width: 100%;  
478 - box-sizing: border-box;  
479 - padding: 10rpx 0; 477 + width: 100%;
  478 + box-sizing: border-box;
  479 + padding: 10rpx 0;
480 } 480 }
481 481
482 /* 失效原因(必填):标签 + 输入域 */ 482 /* 失效原因(必填):标签 + 输入域 */
483 .invalid-modal-label { 483 .invalid-modal-label {
484 - display: flex;  
485 - align-items: center;  
486 - gap: 6rpx;  
487 - margin-bottom: 16rpx;  
488 - font-size: 28rpx;  
489 - color: #1F2937; 484 + display: flex;
  485 + align-items: center;
  486 + gap: 6rpx;
  487 + margin-bottom: 16rpx;
  488 + font-size: 28rpx;
  489 + color: #1F2937;
490 } 490 }
491 491
492 .invalid-modal-required { 492 .invalid-modal-required {
493 - color: #DC2626; 493 + color: #DC2626;
494 } 494 }
495 495
496 /* 失效凭证上传:与上方原因输入框保持同样的间距 */ 496 /* 失效凭证上传:与上方原因输入框保持同样的间距 */
497 .upload-wrap { 497 .upload-wrap {
498 - margin-top: 16rpx; 498 + margin-top: 16rpx;
499 } 499 }
500 </style> 500 </style>
pages-sub/problem/ai-manage/index.vue
@@ -151,9 +151,9 @@ @@ -151,9 +151,9 @@
151 <view class="u-body-item-title"> 151 <view class="u-body-item-title">
152 紧急程度:{{ uni.$dict.getDictLabel('workorder_pressing_type', item.pressingType) }} 152 紧急程度:{{ uni.$dict.getDictLabel('workorder_pressing_type', item.pressingType) }}
153 </view> 153 </view>
154 -<!-- <view>-->  
155 -<!-- <up-button type="primary" size="mini" @click="handleDetail(item)">工单详情</up-button>-->  
156 -<!-- </view>--> 154 + <!-- <view>-->
  155 + <!-- <up-button type="primary" size="mini" @click="handleDetail(item)">工单详情</up-button>-->
  156 + <!-- </view>-->
157 </view> 157 </view>
158 <view class="u-body-item u-flex"> 158 <view class="u-body-item u-flex">
159 <view class="u-body-item-title">工单状态:</view> 159 <view class="u-body-item-title">工单状态:</view>
pages-sub/problem/regional-order-manage/index.vue
@@ -62,9 +62,9 @@ @@ -62,9 +62,9 @@
62 > 62 >
63 <template #body> 63 <template #body>
64 <view class="card-body"> 64 <view class="card-body">
65 -<!-- <view v-if="activeTab !== 0" class="ml-10">-->  
66 -<!-- <up-button type="primary" size="mini" @click="handleDetail(item)">工单详情</up-button>-->  
67 -<!-- </view>--> 65 + <!-- <view v-if="activeTab !== 0" class="ml-10">-->
  66 + <!-- <up-button type="primary" size="mini" @click="handleDetail(item)">工单详情</up-button>-->
  67 + <!-- </view>-->
68 68
69 <view class="common-custom-btn " v-if="activeTab !== 0" style="--btn-top: 130px;" @click="handleDetail(item)"> 69 <view class="common-custom-btn " v-if="activeTab !== 0" style="--btn-top: 130px;" @click="handleDetail(item)">
70 工单详情 70 工单详情
@@ -89,13 +89,13 @@ @@ -89,13 +89,13 @@
89 89
90 <view class="u-body-item u-flex common-justify-between common-item-center"> 90 <view class="u-body-item u-flex common-justify-between common-item-center">
91 <view class="u-body-item-title">紧急程度:{{ uni.$dict.getDictLabel('workorder_pressing_type', item.pressingType) || '-' }}</view> 91 <view class="u-body-item-title">紧急程度:{{ uni.$dict.getDictLabel('workorder_pressing_type', item.pressingType) || '-' }}</view>
92 -<!-- <view class="u-line-1 u-body-value flex-1 text-right">-->  
93 -<!-- {{ uni.$dict.getDictLabel('workorder_pressing_type', item.pressingType) || '-' }}-->  
94 -<!-- </view>--> 92 + <!-- <view class="u-line-1 u-body-value flex-1 text-right">-->
  93 + <!-- {{ uni.$dict.getDictLabel('workorder_pressing_type', item.pressingType) || '-' }}-->
  94 + <!-- </view>-->
95 <!-- 只有 我发起的(1)、已办(2) 显示该行的详情按钮 --> 95 <!-- 只有 我发起的(1)、已办(2) 显示该行的详情按钮 -->
96 -<!-- <view v-if="activeTab !== 0" class="ml-10">-->  
97 -<!-- <up-button type="primary" size="mini" @click="handleDetail(item)">工单详情</up-button>-->  
98 -<!-- </view>--> 96 + <!-- <view v-if="activeTab !== 0" class="ml-10">-->
  97 + <!-- <up-button type="primary" size="mini" @click="handleDetail(item)">工单详情</up-button>-->
  98 + <!-- </view>-->
99 </view> 99 </view>
100 <view class="u-body-item u-flex"> 100 <view class="u-body-item u-flex">
101 <view class="u-body-item-title">工单状态:</view> 101 <view class="u-body-item-title">工单状态:</view>
pages-sub/problem/regional-order-manage/list-detail.vue
@@ -2,24 +2,24 @@ @@ -2,24 +2,24 @@
2 <view class="page-container"> 2 <view class="page-container">
3 <!-- 页面加载 --> 3 <!-- 页面加载 -->
4 <up-loading-page 4 <up-loading-page
5 - v-if="loading"  
6 - :loading="true"  
7 - title="加载中..."  
8 - color="#2563EB" 5 + v-if="loading"
  6 + :loading="true"
  7 + title="加载中..."
  8 + color="#2563EB"
9 ></up-loading-page> 9 ></up-loading-page>
10 10
11 <view v-else class="main-content" :class="'pb-rows-' + actionBarRows"> 11 <view v-else class="main-content" :class="'pb-rows-' + actionBarRows">
12 <!-- 顶部标签栏 --> 12 <!-- 顶部标签栏 -->
13 <up-sticky :bgColor="'#fff'"> 13 <up-sticky :bgColor="'#fff'">
14 <up-tabs 14 <up-tabs
15 - v-model="activeTopTab"  
16 - :list="topTabList"  
17 - :scrollable="false"  
18 - sticky  
19 - active-color="#2563EB"  
20 - inactive-color="#606266"  
21 - class="top-tabs"  
22 - @click="activeTopTabClick" 15 + v-model="activeTopTab"
  16 + :list="topTabList"
  17 + :scrollable="false"
  18 + sticky
  19 + active-color="#2563EB"
  20 + inactive-color="#606266"
  21 + class="top-tabs"
  22 + @click="activeTopTabClick"
23 ></up-tabs> 23 ></up-tabs>
24 </up-sticky> 24 </up-sticky>
25 25
@@ -68,17 +68,17 @@ @@ -68,17 +68,17 @@
68 </up-cell> 68 </up-cell>
69 69
70 <up-cell 70 <up-cell
71 - title="紧急程度"  
72 - :value="uni.$dict.getDictLabel('workorder_pressing_type', orderDetail.pressingType) || '--'"  
73 - align="middle" 71 + title="紧急程度"
  72 + :value="uni.$dict.getDictLabel('workorder_pressing_type', orderDetail.pressingType) || '--'"
  73 + align="middle"
74 ></up-cell> 74 ></up-cell>
75 75
76 <up-cell title="提交人" :value="orderDetail.userName || '--'" align="middle"></up-cell> 76 <up-cell title="提交人" :value="orderDetail.userName || '--'" align="middle"></up-cell>
77 77
78 <up-cell 78 <up-cell
79 - title="提交时间"  
80 - :value="timeFormat(orderDetail.createTime, 'yyyy-mm-dd hh:MM:ss') || '--'"  
81 - align="middle" 79 + title="提交时间"
  80 + :value="timeFormat(orderDetail.createTime, 'yyyy-mm-dd hh:MM:ss') || '--'"
  81 + align="middle"
82 ></up-cell> 82 ></up-cell>
83 83
84 <up-cell v-if="orderDetail.handleResult"> 84 <up-cell v-if="orderDetail.handleResult">
@@ -94,11 +94,11 @@ @@ -94,11 +94,11 @@
94 <template #value> 94 <template #value>
95 <view class="cell-content-wrap"> 95 <view class="cell-content-wrap">
96 <up-album 96 <up-album
97 - v-if="!!orderDetail.problemsImgs?.length"  
98 - :urls="orderDetail.problemsImgs.slice(0, 3)"  
99 - singleSize="70"  
100 - multipleSize="70"  
101 - :preview-full-image="true" 97 + v-if="!!orderDetail.problemsImgs?.length"
  98 + :urls="orderDetail.problemsImgs.slice(0, 3)"
  99 + singleSize="70"
  100 + multipleSize="70"
  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>
104 </view> 104 </view>
@@ -106,19 +106,19 @@ @@ -106,19 +106,19 @@
106 </up-cell> 106 </up-cell>
107 107
108 <up-cell 108 <up-cell
109 - v-if="orderDetail.expectedFinishDate"  
110 - title="希望完成时间"  
111 - :value="timeFormat(orderDetail.expectedFinishDate, 'yyyy-mm-dd hh:MM:ss')"  
112 - align="middle"  
113 - :border="false" 109 + v-if="orderDetail.expectedFinishDate"
  110 + title="希望完成时间"
  111 + :value="timeFormat(orderDetail.expectedFinishDate, 'yyyy-mm-dd hh:MM:ss')"
  112 + align="middle"
  113 + :border="false"
114 ></up-cell> 114 ></up-cell>
115 115
116 <up-cell 116 <up-cell
117 - v-if="orderDetail.finishDate"  
118 - title="工单完结时间"  
119 - :value="timeFormat(orderDetail.finishDate, 'yyyy-mm-dd hh:MM:ss')"  
120 - align="middle"  
121 - :border="false" 117 + v-if="orderDetail.finishDate"
  118 + title="工单完结时间"
  119 + :value="timeFormat(orderDetail.finishDate, 'yyyy-mm-dd hh:MM:ss')"
  120 + align="middle"
  121 + :border="false"
122 ></up-cell> 122 ></up-cell>
123 </up-cell-group> 123 </up-cell-group>
124 124
@@ -137,22 +137,22 @@ @@ -137,22 +137,22 @@
137 </up-cell> 137 </up-cell>
138 </up-cell-group> 138 </up-cell-group>
139 <up-tabs 139 <up-tabs
140 - @change="imgTabChange"  
141 - v-model="activeImgTab"  
142 - :list="imgTabList"  
143 - :scrollable="false"  
144 - active-color="#2563EB"  
145 - inactive-color="#606266"  
146 - class="img-tabs" 140 + @change="imgTabChange"
  141 + v-model="activeImgTab"
  142 + :list="imgTabList"
  143 + :scrollable="false"
  144 + active-color="#2563EB"
  145 + inactive-color="#606266"
  146 + class="img-tabs"
147 ></up-tabs> 147 ></up-tabs>
148 <view class="img-tab-content"> 148 <view class="img-tab-content">
149 <up-album 149 <up-album
150 - v-if="currentImgList.length"  
151 - :urls="currentImgList.slice(0, 3)"  
152 - :singleSize="70"  
153 - :multipleSize="70"  
154 - :preview-full-image="true"  
155 - class="img-album custom-album" 150 + v-if="currentImgList.length"
  151 + :urls="currentImgList.slice(0, 3)"
  152 + :singleSize="70"
  153 + :multipleSize="70"
  154 + :preview-full-image="true"
  155 + class="img-album custom-album"
156 ></up-album> 156 ></up-album>
157 <text v-else class="empty-img-text">养护员未上传图片</text> 157 <text v-else class="empty-img-text">养护员未上传图片</text>
158 </view> 158 </view>
@@ -162,18 +162,18 @@ @@ -162,18 +162,18 @@
162 <!-- 流程节点 Tab --> 162 <!-- 流程节点 Tab -->
163 <view v-show="activeTopTab === 1" class="process-content"> 163 <view v-show="activeTopTab === 1" class="process-content">
164 <up-steps 164 <up-steps
165 - v-if="processData.activityNodes && processData.activityNodes.length"  
166 - :list="processData.activityNodes"  
167 - :current="getCurrentStepIndex()"  
168 - direction="column"  
169 - active-color="#2563EB"  
170 - inactive-color="#909399"  
171 - class="vertical-steps" 165 + v-if="processData.activityNodes && processData.activityNodes.length"
  166 + :list="processData.activityNodes"
  167 + :current="getCurrentStepIndex()"
  168 + direction="column"
  169 + active-color="#2563EB"
  170 + inactive-color="#909399"
  171 + class="vertical-steps"
172 > 172 >
173 <template> 173 <template>
174 <up-steps-item 174 <up-steps-item
175 - v-for="(item, index) in processData.activityNodes"  
176 - :key="`${item.id}_${index}`" 175 + v-for="(item, index) in processData.activityNodes"
  176 + :key="`${item.id}_${index}`"
177 > 177 >
178 <template #content> 178 <template #content>
179 <view class="step-content-wrap"> 179 <view class="step-content-wrap">
@@ -199,12 +199,12 @@ @@ -199,12 +199,12 @@
199 </view> 199 </view>
200 <view class="step-album-wrap"> 200 <view class="step-album-wrap">
201 <up-album 201 <up-album
202 - v-if="item.tasks && item.tasks[0]?.attattmentUrls && item.tasks[0].attattmentUrls.length"  
203 - :urls="item.tasks[0].attattmentUrls.slice(0, 3)"  
204 - :singleSize="70"  
205 - :multipleSize="70"  
206 - :preview-full-image="true"  
207 - class="step-album" 202 + v-if="item.tasks && item.tasks[0]?.attattmentUrls && item.tasks[0].attattmentUrls.length"
  203 + :urls="item.tasks[0].attattmentUrls.slice(0, 3)"
  204 + :singleSize="70"
  205 + :multipleSize="70"
  206 + :preview-full-image="true"
  207 + class="step-album"
208 ></up-album> 208 ></up-album>
209 </view> 209 </view>
210 </view> 210 </view>
@@ -213,10 +213,10 @@ @@ -213,10 +213,10 @@
213 </template> 213 </template>
214 </up-steps> 214 </up-steps>
215 <up-empty 215 <up-empty
216 - v-else  
217 - mode="data"  
218 - title="暂无流程节点数据"  
219 - class="empty-process" 216 + v-else
  217 + mode="data"
  218 + title="暂无流程节点数据"
  219 + class="empty-process"
220 ></up-empty> 220 ></up-empty>
221 </view> 221 </view>
222 </view> 222 </view>
@@ -251,35 +251,35 @@ @@ -251,35 +251,35 @@
251 251
252 <!-- 回退弹窗 --> 252 <!-- 回退弹窗 -->
253 <up-modal 253 <up-modal
254 - :show="rejectModalShow"  
255 - title="回退原因"  
256 - :closeOnClickOverlay="false"  
257 - :showConfirmButton="true"  
258 - :showCancelButton="true"  
259 - @cancel="handleRejectModalCancel"  
260 - @confirm="confirmReject" 254 + :show="rejectModalShow"
  255 + title="回退原因"
  256 + :closeOnClickOverlay="false"
  257 + :showConfirmButton="true"
  258 + :showCancelButton="true"
  259 + @cancel="handleRejectModalCancel"
  260 + @confirm="confirmReject"
261 > 261 >
262 <view class="reject-modal-content"> 262 <view class="reject-modal-content">
263 <up-textarea 263 <up-textarea
264 - v-model.trim="rejectReason"  
265 - placeholder="请输入回退原因(必填)"  
266 - rows="6"  
267 - :count="200"  
268 - maxlength="200"  
269 - class="reject-textarea" 264 + v-model.trim="rejectReason"
  265 + placeholder="请输入回退原因(必填)"
  266 + rows="6"
  267 + :count="200"
  268 + maxlength="200"
  269 + class="reject-textarea"
270 /> 270 />
271 <view class="upload-wrap mt-20"> 271 <view class="upload-wrap mt-20">
272 <view class="upload-title">上传回退图片(选填)</view> 272 <view class="upload-title">上传回退图片(选填)</view>
273 <up-upload 273 <up-upload
274 - :file-list="rejectImgs.rawImgList.value || []"  
275 - @after-read="rejectImgs.uploadImgs"  
276 - @delete="rejectImgs.deleteImg"  
277 - multiple  
278 - width="70"  
279 - height="70"  
280 - :max-count="rejectImgs.uploadConfig.maxCount"  
281 - :upload-text="rejectImgs.uploadConfig.uploadText"  
282 - :size-type="rejectImgs.uploadConfig.sizeType" 274 + :file-list="rejectImgs.rawImgList.value || []"
  275 + @after-read="rejectImgs.uploadImgs"
  276 + @delete="rejectImgs.deleteImg"
  277 + multiple
  278 + width="70"
  279 + height="70"
  280 + :max-count="rejectImgs.uploadConfig.maxCount"
  281 + :upload-text="rejectImgs.uploadConfig.uploadText"
  282 + :size-type="rejectImgs.uploadConfig.sizeType"
283 /> 283 />
284 </view> 284 </view>
285 </view> 285 </view>
@@ -287,13 +287,13 @@ @@ -287,13 +287,13 @@
287 287
288 <!-- 验收弹窗 --> 288 <!-- 验收弹窗 -->
289 <up-modal 289 <up-modal
290 - :show="acceptModalShow"  
291 - title="验收"  
292 - :closeOnClickOverlay="false"  
293 - :showConfirmButton="true"  
294 - :showCancelButton="true"  
295 - @cancel="handleAcceptModalCancel"  
296 - @confirm="handleAcceptModalConfirm" 290 + :show="acceptModalShow"
  291 + title="验收"
  292 + :closeOnClickOverlay="false"
  293 + :showConfirmButton="true"
  294 + :showCancelButton="true"
  295 + @cancel="handleAcceptModalCancel"
  296 + @confirm="handleAcceptModalConfirm"
297 > 297 >
298 <view class="accept-modal-content"> 298 <view class="accept-modal-content">
299 <view class="radio-group-wrap"> 299 <view class="radio-group-wrap">
@@ -304,26 +304,26 @@ @@ -304,26 +304,26 @@
304 </view> 304 </view>
305 <view class="textarea-wrap mt-30"> 305 <view class="textarea-wrap mt-30">
306 <up-textarea 306 <up-textarea
307 - v-model.trim="acceptReason"  
308 - placeholder="请输入验收原因(必填,最多200字)"  
309 - :required="true"  
310 - maxlength="200"  
311 - rows="5"  
312 - count 307 + v-model.trim="acceptReason"
  308 + placeholder="请输入验收原因(必填,最多200字)"
  309 + :required="true"
  310 + maxlength="200"
  311 + rows="5"
  312 + count
313 /> 313 />
314 </view> 314 </view>
315 <view class="upload-wrap mt-20"> 315 <view class="upload-wrap mt-20">
316 <view class="upload-title">上传验收图片(选填)</view> 316 <view class="upload-title">上传验收图片(选填)</view>
317 <up-upload 317 <up-upload
318 - :file-list="acceptImgs.rawImgList.value || []"  
319 - @after-read="acceptImgs.uploadImgs"  
320 - @delete="acceptImgs.deleteImg"  
321 - multiple  
322 - width="70"  
323 - height="70"  
324 - :max-count="acceptImgs.uploadConfig.maxCount"  
325 - :upload-text="acceptImgs.uploadConfig.uploadText"  
326 - :size-type="acceptImgs.uploadConfig.sizeType" 318 + :file-list="acceptImgs.rawImgList.value || []"
  319 + @after-read="acceptImgs.uploadImgs"
  320 + @delete="acceptImgs.deleteImg"
  321 + multiple
  322 + width="70"
  323 + height="70"
  324 + :max-count="acceptImgs.uploadConfig.maxCount"
  325 + :upload-text="acceptImgs.uploadConfig.uploadText"
  326 + :size-type="acceptImgs.uploadConfig.sizeType"
327 /> 327 />
328 </view> 328 </view>
329 </view> 329 </view>
@@ -382,8 +382,8 @@ const callApprovalApi = async (params: any, taskKey: string) =&gt; { @@ -382,8 +382,8 @@ const callApprovalApi = async (params: any, taskKey: string) =&gt; {
382 382
383 const navToOrderPage = (path: string, query = {}) => { 383 const navToOrderPage = (path: string, query = {}) => {
384 const queryStr = Object.keys(query) 384 const queryStr = Object.keys(query)
385 - .map(k => `${k}=${encodeURIComponent(query[k])}`)  
386 - .join('&') 385 + .map(k => `${k}=${encodeURIComponent(query[k])}`)
  386 + .join('&')
387 const url = queryStr ? `${path}?${queryStr}` : path 387 const url = queryStr ? `${path}?${queryStr}` : path
388 uni.navigateTo({ url }) 388 uni.navigateTo({ url })
389 } 389 }
@@ -631,8 +631,8 @@ const activeTopTabClick = async (item: any) =&gt; { @@ -631,8 +631,8 @@ const activeTopTabClick = async (item: any) =&gt; {
631 if (res && res.activityNodes && res.activityNodes.length) { 631 if (res && res.activityNodes && res.activityNodes.length) {
632 // 过滤未开始(status = -1)的预测节点:退回后 BPM 会返回后续待处理节点,工单时间线只展示已发生/进行中的节点 632 // 过滤未开始(status = -1)的预测节点:退回后 BPM 会返回后续待处理节点,工单时间线只展示已发生/进行中的节点
633 const formatNodes = res.activityNodes 633 const formatNodes = res.activityNodes
634 - .filter(node => node.status !== -1)  
635 - .map(node => ({ ...node, title: node.name })) 634 + .filter(node => node.status !== -1)
  635 + .map(node => ({ ...node, title: node.name }))
636 processData.value = { ...res, activityNodes: formatNodes } 636 processData.value = { ...res, activityNodes: formatNodes }
637 } else { 637 } else {
638 processData.value = res 638 processData.value = res
@@ -671,8 +671,8 @@ const handleRenew = (item: any) =&gt; { @@ -671,8 +671,8 @@ const handleRenew = (item: any) =&gt; {
671 const tempKey = setOrderStorage(item, 'renew_order') 671 const tempKey = setOrderStorage(item, 'renew_order')
672 if (!tempKey) return 672 if (!tempKey) return
673 const url = USER_ROLES.includes('patrol_global') 673 const url = USER_ROLES.includes('patrol_global')
674 - ? '/pages-sub/problem/regional-order-manage/add-patrol-order'  
675 - : '/pages-sub/problem/regional-order-manage/add-order' 674 + ? '/pages-sub/problem/regional-order-manage/add-patrol-order'
  675 + : '/pages-sub/problem/regional-order-manage/add-order'
676 navToOrderPage(url, { isRenew: 1, tempKey }) 676 navToOrderPage(url, { isRenew: 1, tempKey })
677 } 677 }
678 678
@@ -874,8 +874,8 @@ const handleAcceptModalConfirm = async () =&gt; { @@ -874,8 +874,8 @@ const handleAcceptModalConfirm = async () =&gt; {
874 workerDataId: item.id, 874 workerDataId: item.id,
875 taskId: item.taskId, 875 taskId: item.taskId,
876 operateType: acceptRadioValue.value === '0' 876 operateType: acceptRadioValue.value === '0'
877 - ? nextStepMap[item.taskKey].operateTypePass  
878 - : nextStepMap[item.taskKey].operateTypeNoPass, 877 + ? nextStepMap[item.taskKey].operateTypePass
  878 + : nextStepMap[item.taskKey].operateTypeNoPass,
879 reason 879 reason
880 } 880 }
881 } 881 }
@@ -886,8 +886,8 @@ const handleAcceptModalConfirm = async () =&gt; { @@ -886,8 +886,8 @@ const handleAcceptModalConfirm = async () =&gt; {
886 taskId: item.taskId, 886 taskId: item.taskId,
887 workerDataId: item.id, 887 workerDataId: item.id,
888 operateType: acceptRadioValue.value === '0' 888 operateType: acceptRadioValue.value === '0'
889 - ? nextStepMap[item.taskKey].operateTypePass  
890 - : nextStepMap[item.taskKey].operateTypeNoPass, 889 + ? nextStepMap[item.taskKey].operateTypePass
  890 + : nextStepMap[item.taskKey].operateTypeNoPass,
891 reason, 891 reason,
892 agree: acceptRadioValue.value 892 agree: acceptRadioValue.value
893 } 893 }
pages-sub/problem/work-order-manage/order-detail.vue
@@ -95,7 +95,7 @@ @@ -95,7 +95,7 @@
95 </template> 95 </template>
96 </up-cell> 96 </up-cell>
97 97
98 - <up-cell title="重点巡检区域" :value="orderDetail.keyInspection==0?'否':'是'" align="middle"></up-cell> 98 + <up-cell title="重点巡检区域" :value="orderDetail.keyInspection==0?'否':'是'" align="middle"></up-cell>
99 99
100 <!-- 希望完成时间 --> 100 <!-- 希望完成时间 -->
101 <up-cell 101 <up-cell