Commit b0e2f1a9a61d35f68dde9920da8582b6d4fb1041

Authored by 刘淇
1 parent df24e712

快速工单和巡查计划样式优化

common/config/env.js
... ... @@ -3,6 +3,8 @@ const env = {
3 3 // 开发环境
4 4 development: {
5 5 baseUrl: 'https://test.jichengshanshui.com.cn:28302',
  6 + // https://test.jichengshanshui.com.cn:28302
  7 +
6 8 uploadUrl: 'https://test.jichengshanshui.com.cn:28302',
7 9 // baseApi:'admin-api',
8 10 // appApi:'app-api'
... ...
pages-sub/daily/maintain-manage/add-record.vue
1 1 <template>
2 2 <view class="page-container">
3   - <!-- 核心:将所有 up-form-item 包裹在同一个 up-form 内 -->
4 3 <view class="inspect-form-content commonPageLRpadding">
5 4 <up-form
6 5 label-position="left"
... ... @@ -42,32 +41,27 @@
42 41 ></up-upload>
43 42 </up-form-item>
44 43  
45   - <!-- 3. 完成进度(滑块)- 核心修改:min绑定initProgress -->
  44 + <!-- 3. 完成进度(滑块) -->
46 45 <up-form-item
47 46 label="完成进度"
48 47 prop="progress"
49   - required
  48 +
50 49 class="form-item"
51 50 >
52 51 <view class="progress-wrap">
53 52 <up-slider
54 53 v-model="inspectForm.progress"
55   - :min="0"
56   - :max="100"
57   - active-color="#1989fa"
58   - inactive-color="#e5e5e5"
59   - block-size="24"
60   - class="progress-slider"
61   - @change="handleProgressChange"
  54 + :min="initProgress"
  55 + :max="100"
  56 + active-color="#1989fa"
  57 + inactive-color="#e5e5e5"
  58 + block-size="24"
  59 + :showValue="true"
  60 + class="progress-slider"
  61 + @changing="handleProgressChange"
62 62 ></up-slider>
63   - <view class="progress-value">{{ inspectForm.progress }}%</view>
64   - <!-- 优化提示文案:动态显示初始进度值 -->
65   - <view class="progress-tips" v-if="inspectForm.progress <= initProgress">
66   - 进度不能低于或等于{{ initProgress }}%,请调整
67   - </view>
68 63 </view>
69 64 </up-form-item>
70   -
71 65 </up-form>
72 66 </view>
73 67  
... ... @@ -86,28 +80,23 @@
86 80 <script setup lang="ts">
87 81 import { ref } from 'vue'
88 82 import type { UniFormRef } from '@/uni_modules/uview-plus/types'
89   -// 定义ref供选项式API使用
90 83 const inspectFormRef = ref<UniFormRef>(null)
91 84 </script>
92 85  
93 86 <script lang="ts">
94   -import { uploadImages } from '@/common/utils/upload';
95   -import { maintainCreate } from "@/api/maintain-manage/maintain-manage";
  87 +import { uploadImages } from '@/common/utils/upload'
  88 +import { maintainCreate } from "@/api/maintain-manage/maintain-manage"
96 89  
97 90 export default {
98 91 data() {
99 92 return {
100   - // 图片列表
101 93 imagesList: [],
102   - // 从URL获取的初始进度值
103 94 initProgress: 0,
104   - // 巡查表单数据
105 95 inspectForm: {
106   - remark: '', // 巡查描述
107   - progress: 0 // 完成进度(0-100)
  96 + remark: '',
  97 + progress: 0
108 98 },
109   - paramsOptins: {}, // 接受参数
110   - // 表单校验规则
  99 + paramsOptins: {},
111 100 inspectFormRules: {
112 101 images: [
113 102 {
... ... @@ -115,10 +104,8 @@ export default {
115 104 message: '请上传图片',
116 105 trigger: 'change',
117 106 validator: (rule, value, callback) => {
118   - // 自定义校验规则:检查是否有成功上传的图片
119 107 const hasSuccessImg = this.imagesList.some(item => item.status === 'success')
120 108 const imgCount = this.imagesList.filter(item => item.status === 'success').length
121   -
122 109 if (!hasSuccessImg || imgCount < 1) {
123 110 callback(new Error('最少需要上传1张图片'))
124 111 } else if (imgCount > 3) {
... ... @@ -129,55 +116,71 @@ export default {
129 116 }
130 117 }
131 118 ],
132   - progress: [
133   - {
134   - type: 'number',
135   - required: true,
136   - message: '请设置完成进度',
137   - trigger: ['change'],
138   - validator: (rule, value, callback) => {
139   - // 自定义校验:进度必须大于初始进度值(兜底校验)
140   - if (value <= this.initProgress) {
141   - callback(new Error(`完成进度必须大于${this.initProgress}%`))
142   - } else {
143   - callback()
144   - }
145   - }
146   - }
147   - ]
  119 + // progress: [
  120 + // {
  121 + //
  122 + // required: true,
  123 + // message: '请设置完成进度',
  124 + // trigger: ['change'],
  125 + // validator: (rule, value, callback) => {
  126 + // // 第一步:校验是否为空/0
  127 + // if (!value && value !== 0) {
  128 + // callback(new Error('请设置完成进度'))
  129 + // }
  130 + // // 第二步:校验是否大于初始进度
  131 + // else if (value <= this.initProgress) {
  132 + // callback(new Error(`完成进度必须大于${this.initProgress}%`))
  133 + // }
  134 + // // 校验通过
  135 + // else {
  136 + // callback()
  137 + // }
  138 + // }
  139 + // }
  140 + // ]
148 141 }
149 142 }
150 143 },
151 144 onLoad(option) {
152 145 console.log('页面参数:', option)
153 146 this.paramsOptins = option
154   -
155   - // 从URL参数中获取进度值,默认0
156   - this.initProgress = option.finishPercent ? Number(option.finishPercent) : 0
157   - // 设置表单初始进度值(若初始进度>0,默认设为初始进度+1,避免刚进入就提示)
158   - this.inspectForm.progress = this.initProgress + 1 || 1
159   -
  147 + // 初始化初始进度
  148 + this.initProgress = option.finishPercent ? Number(option.finishPercent)+1 : 0
  149 + // 关键修复:初始进度值设为 初始进度+1,避免刚进入就触发校验失败
  150 + this.inspectForm.progress = this.initProgress
160 151 console.log('初始进度值:', this.initProgress)
161 152 },
162 153 onReady() {
163   - // 兼容微信小程序,通过setRules设置校验规则
164 154 this.$refs.inspectFormRef.setRules(this.inspectFormRules)
165 155 console.log('巡查表单规则初始化完成')
166 156 },
167 157 methods: {
168 158 /**
169   - * 新增:进度滑块拖动后校验(兜底,防止手动修改值)
  159 + * 进度滑块变化处理 - 核心优化:实时触发校验 + 状态更新
170 160 */
171   - handleProgressChange(val) {
172   - // 若拖动后值<=初始进度,强制重置为初始进度+1
173   - if (val <= this.initProgress) {
174   - this.inspectForm.progress = this.initProgress + 1
175   - uni.showToast({
176   - title: `进度不能低于${this.initProgress}%`,
177   - icon: 'none',
178   - duration: 1500
179   - })
180   - }
  161 + handleProgressChange(value) {
  162 + // // 1. 强制修正非法值(兜底)
  163 + // console.log(value)
  164 + // if (value <= this.initProgress) {
  165 + // console.log('123')
  166 + // this.inspectForm.progress = this.initProgress + 1
  167 + // uni.showToast({
  168 + // title: `进度不能低于${this.initProgress}%`,
  169 + // icon: 'none',
  170 + // duration: 1500
  171 + // })
  172 + // }
  173 + //
  174 + // // 2. 关键:手动触发progress字段的校验,实时更新提示状态
  175 + // this.$nextTick(async () => {
  176 + // try {
  177 + // // 触发单个字段校验
  178 + // await this.$refs.inspectFormRef.validateField('progress')
  179 + // } catch (err) {
  180 + // // 校验失败时uView会自动显示提示,此处无需额外处理
  181 + // console.log('进度校验失败:', err)
  182 + // }
  183 + // })
181 184 },
182 185  
183 186 /**
... ... @@ -186,7 +189,6 @@ export default {
186 189 deleteImg(event) {
187 190 console.log('删除图片事件:', event)
188 191 this.imagesList.splice(event.index, 1)
189   - // 删除图片后重新校验图片字段
190 192 this.$refs.inspectFormRef.validateField('images')
191 193 uni.showToast({ title: '图片删除成功', icon: 'success' })
192 194 },
... ... @@ -198,7 +200,6 @@ export default {
198 200 console.log('上传图片事件:', event)
199 201 const fileList = Array.isArray(event.file) ? event.file : [event.file]
200 202 const targetImgList = this.imagesList
201   -
202 203 const filePaths = fileList.map(item => item.url)
203 204 const tempItems = fileList.map(item => ({
204 205 ...item,
... ... @@ -242,7 +243,6 @@ export default {
242 243 uni.showToast({ title: `成功上传${fileList.length}张图片`, icon: 'success' })
243 244 }
244 245  
245   - // 上传完成后重新校验图片字段
246 246 this.$refs.inspectFormRef.validateField('images')
247 247 } catch (err) {
248 248 console.error('图片上传失败:', err)
... ... @@ -256,8 +256,6 @@ export default {
256 256 }
257 257 }
258 258 uni.showToast({ title: '图片上传失败,请重试', icon: 'none' })
259   -
260   - // 上传失败后重新校验图片字段
261 259 this.$refs.inspectFormRef.validateField('images')
262 260 }
263 261 },
... ... @@ -282,38 +280,28 @@ export default {
282 280 async submitInspect() {
283 281 console.log('当前完成进度:', this.inspectForm.progress)
284 282 try {
285   - // 先执行表单校验
286 283 await this.$refs.inspectFormRef.validate()
287 284 console.log('图片列表:', this.imagesList)
288 285  
289   - // 构造提交数据
290 286 const submitData = {
291   - // "batchNo": this.paramsOptins.batchNo,
292   - totalFinishPercent:this.inspectForm.progress,
  287 + totalFinishPercent: this.inspectForm.progress,
293 288 "planNo": this.paramsOptins.planNo,
294 289 "imgHost": "1",
295 290 "beginImg": this.getImgUrlList(this.imagesList),
296   - "commonUserList":[],
297   - // "userId": '',
298   - // "userName": '',
299   - "remark": this.inspectForm.remark // 备注中记录进度
  291 + "commonUserList": [],
  292 + "remark": this.inspectForm.remark
300 293 }
301 294  
302   - // 显示加载中
303 295 uni.showLoading({ title: '提交中...' })
304   -
305 296 await maintainCreate(submitData)
306   -
307 297 uni.hideLoading()
  298 +
308 299 uni.showToast({
309 300 title: '提交成功',
310 301 icon: 'success',
311 302 duration: 1000
312 303 })
313   - // uni.navigateTo({
314   - // url: `/pages-sub/daily/maintain-manage/add-record?finishState=${item.finishState}&planNo=${item.planNo}&finishPercent=${item.finishPercent}`
315   - // })
316   - // 延迟跳转(等待提示框显示完成)
  304 +
317 305 setTimeout(() => {
318 306 uni.redirectTo({
319 307 url: '/pages-sub/daily/maintain-manage/index'
... ... @@ -321,14 +309,8 @@ export default {
321 309 }, 1000)
322 310  
323 311 } catch (error) {
324   - // 隐藏加载框
325 312 uni.hideLoading()
326   -
327   - // 区分是表单校验失败还是接口调用失败
328   - if (Array.isArray(error)) {
329   - // 表单校验失败 - 静默处理(uView会自动提示)
330   - } else {
331   - // 接口调用失败
  313 + if (!Array.isArray(error)) {
332 314 console.error('巡查表单提交失败:', error)
333 315 uni.showToast({
334 316 title: '提交失败,请重试',
... ... @@ -343,36 +325,13 @@ export default {
343 325 </script>
344 326  
345 327 <style lang="scss" scoped>
346   -
347   -
348   -// 巡查表单内容容器
349 328 .inspect-form-content {
350 329 background: #fff;
351 330 padding: 20rpx;
352 331 margin-bottom: 20rpx;
353 332 }
354 333  
355   -// 进度滑块样式
356 334 .progress-wrap {
357   - width: 100%;
358   -
359   - .progress-slider {
360   - margin: 20rpx 0;
361   - }
362   -
363   - .progress-value {
364   - text-align: right;
365   - font-size: 28rpx;
366   - color: #333;
367   - margin-bottom: 10rpx;
368   - }
369   -
370   - .progress-tips {
371   - font-size: 24rpx;
372   - color: #ff4d4f;
373   - margin-top: 10rpx;
374   - }
  335 + width: 83%;
375 336 }
376   -
377   -
378 337 </style>
379 338 \ No newline at end of file
... ...
pages-sub/daily/maintain-manage/finish-plan-detail.vue
... ... @@ -10,8 +10,6 @@
10 10  
11 11 <!-- 内容容器 -->
12 12 <view v-else class="content-wrap">
13   -
14   -
15 13 <template v-for="(i, index) in orderDetail" :key="index">
16 14 <!-- 工单详情内容 -->
17 15 <up-cell-group :border="false" inset style="margin: 20rpx;">
... ... @@ -42,13 +40,13 @@
42 40 <!-- 4. 情况描述 -->
43 41 <up-cell
44 42 title="计划有效期"
45   - :value="`${timeFormat(i.beginTime,'yy-mm-dd hh:MM:ss')} 至 ${timeFormat(i. endTime,'yy-mm-dd hh:MM:ss')}`"
  43 + :value="`${timeFormat(i.beginTime,'yyyy-mm-dd')} 至 ${timeFormat(i. endTime,'yyyy-mm-dd')}`"
46 44 class="up-line-1"
47 45 align="middle"
48 46 ></up-cell>
49 47  
50 48 <!-- 5. 问题照片(核心修复:判断条件+空值处理) -->
51   - <up-cell title="照片" >
  49 + <up-cell title="照片">
52 50 <template #value>
53 51 <view class="cell-content-wrap">
54 52  
... ... @@ -71,15 +69,15 @@
71 69 :value="i.remark || '--'"
72 70 class="up-line-1"
73 71 align="middle"
74   - :border="false"
  72 +
75 73 ></up-cell>
76 74  
77 75 <up-cell
78 76 title="提交时间"
79   - :value="timeFormat(i.finishTime,'yy-mm-dd hh:MM:ss') || '--'"
  77 + :value="timeFormat(i.finishTime,'yyyy-mm-dd hh:MM:ss') || '--'"
80 78 class="up-line-1"
81 79 align="middle"
82   - :border="false"
  80 +
83 81 ></up-cell>
84 82  
85 83  
... ... @@ -99,34 +97,35 @@
99 97 </template>
100 98  
101 99 <script setup lang="ts">
102   -import { ref, reactive } from 'vue';
103   -import { detailList } from "@/api/maintain-manage/maintain-manage";
104   -import { onLoad, onShow } from '@dcloudio/uni-app';
105   -import { timeFormat } from '@/uni_modules/uview-plus';
106   -
  100 +import {ref} from 'vue';
  101 +import {detailList} from "@/api/maintain-manage/maintain-manage";
  102 +import {onLoad} from '@dcloudio/uni-app';
  103 +import {timeFormat} from '@/uni_modules/uview-plus';
107 104 // 状态管理
108 105 const loading = ref(true);
109 106 const orderDetail = ref([]);
110 107  
111 108  
112   -
113 109 /**
114 110 * 获取工单详情
115 111 */
116   -const getOrderDetail = async (planNo: string) => {
  112 +const getOrderDetail = async (plan_no: string) => {
117 113 try {
118 114 loading.value = true;
119   - const res = await detailList({ planNo });
  115 + const res = await detailList({plan_no});
120 116 console.log('接口返回:', res);
121 117 // 优化:确保图片数组为数组类型,避免非数组导致渲染错误
122   - orderDetail.value = {
123   - ...res,
124   - problemImgsList: Array.isArray(res.problemImgsList) ? res.problemImgsList : [],
125   - completeImgsList: Array.isArray(res.completeImgsList) ? res.completeImgsList : []
126   - };
  118 + // orderDetail.value
  119 + // orderDetail.value = {
  120 + // ...res,
  121 + // problemImgsList: Array.isArray(res.problemImgsList) ? res.problemImgsList : [],
  122 + // completeImgsList: Array.isArray(res.completeImgsList) ? res.completeImgsList : []
  123 + // };
  124 +
  125 + orderDetail.value = res;
127 126 } catch (error) {
128 127 console.error('获取工单详情失败:', error);
129   - uni.showToast({ title: '加载失败,请重试', icon: 'none' });
  128 + uni.showToast({title: '加载失败,请重试', icon: 'none'});
130 129 } finally {
131 130 loading.value = false;
132 131 }
... ... @@ -134,86 +133,24 @@ const getOrderDetail = async (planNo: string) =&gt; {
134 133  
135 134 // 页面加载
136 135 onLoad((options) => {
137   - const { planNo } = options;
  136 + const {planNo} = options;
138 137 if (planNo) {
139 138 getOrderDetail(planNo);
140 139 } else {
141 140 loading.value = false;
142   - uni.showToast({ title: '缺少工单ID', icon: 'none' });
  141 + uni.showToast({title: '缺少工单ID', icon: 'none'});
143 142 }
144 143 });
145 144 </script>
146 145  
147 146 <style scoped lang="scss">
148   -// 页面基础样式
149   -.u-page {
150   - min-height: 100vh;
151   - background-color: #f5f5f5;
152   - box-sizing: border-box;
153   -}
154 147  
155 148 // 内容容器
156 149 .content-wrap {
157 150 background: #fff;
158 151 width: 100%;
159 152 box-sizing: border-box;
160   - overflow-y: auto;
161   - min-height: calc(100vh - 40rpx);
162   -}
163   -
164   -
165   -
166   -// 空文本样式
167   -.empty-text {
168   - color: #999;
169   - font-size: 28rpx;
170   - line-height: 80rpx;
171   - display: block;
172   - text-align: left;
173   -}
174   -
175   -// 优化uview组件样式
176   -:deep(.up-cell-group) {
177   - --u-cell-group-background-color: #fff;
178   - --u-cell-group-border-radius: 12rpx;
179   - --u-cell-group-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
180   -}
181   -
182   -:deep(.up-cell) {
183   - --u-cell-title-font-size: 28rpx;
184   - --u-cell-value-font-size: 28rpx;
185   - --u-cell-title-color: #666;
186   - --u-cell-value-color: #333;
187   - --u-cell-padding: 20rpx 15rpx;
188   - --u-cell-border-color: #f5f5f5;
189   -}
190   -
191   -// 相册样式优化(关键:适配图片展示)
192   -:deep(.up-album) {
193   - width: 100%;
194   - box-sizing: border-box;
195   -}
196   -
197   -:deep(.up-album__list) {
198   - display: flex;
199   - flex-wrap: wrap;
200   - padding: 0;
201   - margin: 0;
202   -}
203   -
204   -:deep(.up-album__item) {
205   - width: calc(33.333% - 10rpx);
206   - height: 200rpx; // 固定图片高度,避免变形
207   - margin: 5rpx;
208   - border-radius: 8rpx;
209   - overflow: hidden;
210   - background-color: #f8f8f8;
211   -}
212   -
213   -:deep(.up-album__image) {
214   - width: 100%;
215   - height: 100%;
216   - object-fit: cover; // 图片裁剪填充,避免拉伸
  153 + margin-bottom: 20rpx;
217 154 }
218 155  
219 156  
... ...
pages-sub/daily/maintain-manage/pending-plan-detail.vue
... ... @@ -119,7 +119,8 @@ onShow(() =&gt; {
119 119 const getPlanDetail = async () => {
120 120 const queryData = {
121 121 planNo: planNo.value,
122   - planTypeId: planTypeId.value
  122 + planTypeId: planTypeId.value,
  123 + finishState:finishState.value
123 124 }
124 125 console.log(queryData)
125 126 const planInfoRes = await notFinish(queryData)
... ...
pages-sub/daily/maintain-manage/road-detail-list.vue
... ... @@ -50,12 +50,14 @@
50 50 :foot-border-top="false"
51 51 v-for="(item,index) in planList"
52 52 :key="`${item.planNo}_${index}`"
53   -
54 53 >
55 54 <!-- 自定义标题区域 -->
56 55 <template #head>
57 56 <view class="card-header">
58 57 <view class="common-card-title u-line-1">{{ item.planName || '无计划名称' }}</view>
  58 + <!-- 已失效标识 -->
  59 + <up-text type="error" v-if="item.finishState === '3'" text="错误" class="invalid-tag"></up-text>
  60 +<!-- <view v-if="item.finishState === '3'" class="invalid-tag">已失效</view>-->
59 61 </view>
60 62 </template>
61 63  
... ... @@ -80,8 +82,12 @@
80 82 size="mini"
81 83 @click="submitRecord(item)"
82 84 class="submit-record-btn"
  85 +
  86 + :disabled="item.finishState === '3'"
  87 + :class="{ 'disabled-btn': item.finishState === '3' }"
83 88 >
84   - 提交记录
  89 +
  90 + {{ item.finishState === '3' ? '补交记录' : '提交记录' }}
85 91 </up-button>
86 92 </view>
87 93 </view>
... ... @@ -120,7 +126,6 @@ const activeStatus = ref(&#39;1&#39;)
120 126 const searchValue = ref('')
121 127 const planList = ref([])
122 128 const pagingRef = ref(null)
123   -const loading = ref(false)
124 129 const roadId = ref('')
125 130 const finishState = ref('')
126 131 // 搜索占位符
... ... @@ -148,6 +153,10 @@ const handleSearch = () =&gt; {
148 153 pagingRef.value?.reload()
149 154 }
150 155 const submitRecord = (item) => {
  156 + // 已失效状态下直接返回,不执行跳转
  157 + if (item.finishState === '3') {
  158 + return
  159 + }
151 160 console.log('提交记录:', item.finishPercent)
152 161 if (item.finishPercent == 0) {
153 162 uni.navigateTo({
... ... @@ -161,7 +170,6 @@ const submitRecord = (item) =&gt; {
161 170 }
162 171 const queryList = async (pageNo, pageSize) => {
163 172 try {
164   - loading.value = true
165 173 const paramsData = {
166 174 pageNo: pageNo,
167 175 pageSize: pageSize,
... ... @@ -174,12 +182,10 @@ const queryList = async (pageNo, pageSize) =&gt; {
174 182 console.log(res)
175 183 const listData = res?.list || res || []
176 184 pagingRef.value?.complete(listData)
177   - loading.value = false
178 185 } catch (error) {
179 186 console.error('请求失败:', error)
180 187 uni.showToast({title: '加载失败,请重试', icon: 'none'})
181 188 pagingRef.value?.complete(false)
182   - loading.value = false
183 189 }
184 190 }
185 191 // ========== 生命周期 ==========
... ... @@ -187,9 +193,10 @@ onLoad((options) =&gt; {
187 193 getUrlParams(options)
188 194 })
189 195 onShow(() => {
190   - if (roadId.value) {
191   - pagingRef.value?.reload()
192   - }
  196 + // if (roadId.value) {
  197 + // pagingRef.value?.reload()
  198 + // }
  199 + pagingRef.value?.reload()
193 200 })
194 201  
195 202 </script>
... ... @@ -197,7 +204,6 @@ onShow(() =&gt; {
197 204 <style scoped lang="scss">
198 205 .page-container {
199 206 }
200   -
201 207 // 顶部吸顶区域样式
202 208 .sticky-header {
203 209 background-color: #ffffff;
... ... @@ -209,6 +215,21 @@ onShow(() =&gt; {
209 215 }
210 216 }
211 217  
  218 +// 卡片头部样式
  219 +.card-header {
  220 + display: flex;
  221 + justify-content: space-between;
  222 + align-items: center;
  223 +}
  224 +
  225 +// 禁用按钮样式
  226 +.disabled-btn {
  227 + background-color: #c0c4cc !important;
  228 + border-color: #c0c4cc !important;
  229 + color: #fff !important;
  230 + pointer-events: none; // 防止点击
  231 + opacity: 0.7;
  232 +}
212 233  
213 234  
214 235 </style>
215 236 \ No newline at end of file
... ...
pages-sub/daily/patrol-manage/add-patrol-record/index.vue renamed to pages-sub/daily/patrol-manage/add-patrol-record.vue
... ... @@ -40,7 +40,7 @@
40 40 del-color="#ff4d4f"
41 41 class="upload-wrap"
42 42 ></up-upload>
43   -<!-- <view class="tips">(最少1张,最多3张)</view>-->
  43 + <!-- <view class="tips">(最少1张,最多3张)</view>-->
44 44 </up-form-item>
45 45  
46 46 <!-- 3. 转为工单(单选框) -->
... ... @@ -286,7 +286,7 @@ export default {
286 286 // // 延迟跳转(等待提示框显示完成)
287 287 setTimeout(() => {
288 288 uni.redirectTo({
289   - url: '/pages-sub/patrol-manage/patrol-plan/index'
  289 + url: '/pages-sub/daily/patrol-manage/index'
290 290 })
291 291 }, 1000)
292 292  
... ...
pages-sub/daily/patrol-manage/finish-plan-detail/index.vue renamed to pages-sub/daily/patrol-manage/finish-plan-detail.vue
1 1 <template>
2   - <view class="u-page">
  2 + <view class="page-container">
3 3 <!-- 页面级加载组件 -->
4 4 <up-loading-page
5 5 v-if="loading"
... ... @@ -10,24 +10,25 @@
10 10  
11 11 <!-- 内容容器 -->
12 12 <view v-else class="content-wrap">
13   -
14   -
15 13 <template v-for="(i, index) in orderDetail" :key="index">
16 14 <!-- 工单详情内容 -->
17   - <up-cell-group :border="false" inset style="margin: 20rpx;">
18   - <!-- 1. 工单编号 -->
  15 + <up-cell-group :border="false" inset >
  16 + <!-- 1. 工单名称 -->
19 17 <up-cell
20   - :title="i.planName"
21   -
22   - class="up-line-1"
23 18 align="middle"
24   - ></up-cell>
  19 + >
  20 + <template #title>
  21 + <view class="up-line-1">{{i.planName || '--'}}</view>
  22 + </template>
  23 +<!-- <template #value>-->
  24 +<!-- <view class="up-line-1">{{orderDetail.planName || '&#45;&#45;'}}</view>-->
  25 +<!-- </template>-->
  26 + </up-cell>
25 27  
26 28 <!-- 2. 工单位置 -->
27 29 <up-cell
28 30 title="计划编码"
29 31 :value="i.planNo || '--'"
30   - class="up-line-1"
31 32 align="middle"
32 33 ></up-cell>
33 34  
... ... @@ -35,20 +36,18 @@
35 36 <up-cell
36 37 title="养护周期"
37 38 :value="`${i.rate}${uni.$dict.getDictLabel('cycle_id_type', i.cycleId)}`"
38   - class="up-line-1"
39 39 align="middle"
40 40 ></up-cell>
41 41  
42 42 <!-- 4. 情况描述 -->
43 43 <up-cell
44 44 title="计划有效期"
45   - :value="`${timeFormat(i.beginTime,'yy-mm-dd hh:MM:ss')} 至 ${timeFormat(i. endTime,'yy-mm-dd hh:MM:ss')}`"
46   - class="up-line-1"
  45 + :value="`${timeFormat(i.beginTime,'yyyy-mm-dd')} 至 ${timeFormat(i. endTime,'yyyy-mm-dd')}`"
47 46 align="middle"
48 47 ></up-cell>
49 48  
50 49 <!-- 5. 问题照片(核心修复:判断条件+空值处理) -->
51   - <up-cell title="照片" >
  50 + <up-cell title="照片">
52 51 <template #value>
53 52 <view class="cell-content-wrap">
54 53  
... ... @@ -67,26 +66,26 @@
67 66  
68 67 <!-- 7. 处理结果 -->
69 68 <up-cell
70   - title="巡查描述"
71   - :value="i.remark || '--'"
72   - class="up-line-1"
73 69 align="middle"
74   - :border="false"
75   - ></up-cell>
  70 + >
  71 + <template #title>
  72 + <view style="min-width: 200rpx">巡查描述</view>
  73 + </template>
  74 + <template #value>
  75 + <view class="up-line-1">{{i.remark || '--'}}</view>
  76 + </template>
  77 + </up-cell>
76 78  
77 79 <up-cell
78 80 title="提交时间"
79   - :value="timeFormat(i.finishTime,'yy-mm-dd hh:MM:ss') || '--'"
80   - class="up-line-1"
  81 + :value="timeFormat(i.finishTime,'yyyy-mm-dd hh:MM:ss') || '--'"
81 82 align="middle"
82   - :border="false"
83   - ></up-cell>
84 83  
  84 + ></up-cell>
85 85  
86 86 <up-cell
87 87 title="提交人"
88 88 :value="i.userName || '--'"
89   - class="up-line-1"
90 89 align="middle"
91 90 :border="false"
92 91 ></up-cell>
... ... @@ -99,10 +98,10 @@
99 98 </template>
100 99  
101 100 <script setup lang="ts">
102   -import { ref, reactive } from 'vue';
103   -import { inspectioDetailByPlanno } from "@/api/patrol-manage/patrol-plan";
104   -import { onLoad, onShow } from '@dcloudio/uni-app';
105   -import { timeFormat } from '@/uni_modules/uview-plus';
  101 +import {ref} from 'vue';
  102 +import {inspectioDetailByPlanno} from "@/api/patrol-manage/patrol-plan";
  103 +import {onLoad} from '@dcloudio/uni-app';
  104 +import {timeFormat} from '@/uni_modules/uview-plus';
106 105 // 状态管理
107 106 const loading = ref(true);
108 107 const orderDetail = ref([]);
... ... @@ -114,17 +113,13 @@ const orderDetail = ref([]);
114 113 const getOrderDetail = async (plan_no: string) => {
115 114 try {
116 115 loading.value = true;
117   - const res = await inspectioDetailByPlanno({ plan_no });
  116 + const res = await inspectioDetailByPlanno({plan_no});
118 117 console.log('接口返回:', res);
119   - // 优化:确保图片数组为数组类型,避免非数组导致渲染错误
120   - orderDetail.value = {
121   - ...res,
122   - problemImgsList: Array.isArray(res.problemImgsList) ? res.problemImgsList : [],
123   - completeImgsList: Array.isArray(res.completeImgsList) ? res.completeImgsList : []
124   - };
  118 +
  119 + orderDetail.value = res;
125 120 } catch (error) {
126 121 console.error('获取工单详情失败:', error);
127   - uni.showToast({ title: '加载失败,请重试', icon: 'none' });
  122 + uni.showToast({title: '加载失败,请重试', icon: 'none'});
128 123 } finally {
129 124 loading.value = false;
130 125 }
... ... @@ -132,86 +127,24 @@ const getOrderDetail = async (plan_no: string) =&gt; {
132 127  
133 128 // 页面加载
134 129 onLoad((options) => {
135   - const { planNo } = options;
  130 + const {planNo} = options;
136 131 if (planNo) {
137 132 getOrderDetail(planNo);
138 133 } else {
139 134 loading.value = false;
140   - uni.showToast({ title: '缺少工单ID', icon: 'none' });
  135 + uni.showToast({title: '缺少工单ID', icon: 'none'});
141 136 }
142 137 });
143 138 </script>
144 139  
145 140 <style scoped lang="scss">
146   -// 页面基础样式
147   -.u-page {
148   - min-height: 100vh;
149   - background-color: #f5f5f5;
150   - box-sizing: border-box;
151   -}
152 141  
153 142 // 内容容器
154 143 .content-wrap {
155 144 background: #fff;
156 145 width: 100%;
157 146 box-sizing: border-box;
158   - overflow-y: auto;
159   - min-height: calc(100vh - 40rpx);
160   -}
161   -
162   -
163   -
164   -// 空文本样式
165   -.empty-text {
166   - color: #999;
167   - font-size: 28rpx;
168   - line-height: 80rpx;
169   - display: block;
170   - text-align: left;
171   -}
172   -
173   -// 优化uview组件样式
174   -:deep(.up-cell-group) {
175   - --u-cell-group-background-color: #fff;
176   - --u-cell-group-border-radius: 12rpx;
177   - --u-cell-group-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
178   -}
179   -
180   -:deep(.up-cell) {
181   - --u-cell-title-font-size: 28rpx;
182   - --u-cell-value-font-size: 28rpx;
183   - --u-cell-title-color: #666;
184   - --u-cell-value-color: #333;
185   - --u-cell-padding: 20rpx 15rpx;
186   - --u-cell-border-color: #f5f5f5;
187   -}
188   -
189   -// 相册样式优化(关键:适配图片展示)
190   -:deep(.up-album) {
191   - width: 100%;
192   - box-sizing: border-box;
193   -}
194   -
195   -:deep(.up-album__list) {
196   - display: flex;
197   - flex-wrap: wrap;
198   - padding: 0;
199   - margin: 0;
200   -}
201   -
202   -:deep(.up-album__item) {
203   - width: calc(33.333% - 10rpx);
204   - height: 200rpx; // 固定图片高度,避免变形
205   - margin: 5rpx;
206   - border-radius: 8rpx;
207   - overflow: hidden;
208   - background-color: #f8f8f8;
209   -}
210   -
211   -:deep(.up-album__image) {
212   - width: 100%;
213   - height: 100%;
214   - object-fit: cover; // 图片裁剪填充,避免拉伸
  147 + margin-bottom: 20rpx;
215 148 }
216 149  
217 150  
... ...
pages-sub/daily/patrol-manage/patrol-plan/index.vue renamed to pages-sub/daily/patrol-manage/index.vue
1 1 <template>
2 2 <view class="page-container">
3 3 <!-- 顶部固定区域:Tabs + 搜索框 -->
4   - <view class="top-fixed">
  4 + <up-sticky>
  5 + <view class="sticky-header">
5 6 <u-tabs
6 7 :list="tabList"
7 8 :is-scroll="false"
... ... @@ -31,50 +32,69 @@
31 32 style="margin: 20rpx 20rpx 0"
32 33 ></up-search>
33 34 </view>
34   -
  35 + </up-sticky>
35 36  
36 37 <z-paging
37   - ref="paging"
  38 + ref="pagingRef"
38 39 v-model="planList"
39 40 @query="queryList"
40   -
  41 + :auto-show-system-loading="true"
41 42 >
42 43 <template #empty>
43 44 <empty-view/>
44 45 </template>
45 46 <!-- 计划卡片列表 -->
46   - <view class="card-list">
  47 + <view class="common-card-list" style="padding-top: 94px;">
  48 +
  49 + <up-card
  50 + :border="false"
  51 + :foot-border-top="false"
  52 + :head-border-bottom="false"
  53 + v-for="(item,index) in planList"
  54 + :key="`${item.batchNo}_${index}`"
  55 + :show-head="false"
  56 + >
  57 + <template #body>
  58 + <view class="card-body">
  59 + <view class="u-body-item u-flex">
  60 + <view class="u-body-item-title">道路名称:</view>
  61 + <view class="u-line-1 u-body-value">{{ item.roadName || '-' }}</view>
  62 + </view>
47 63  
48   - <view class="plan-card" v-for="(item, index) in planList" :key="item.batchNo">
49   - <view class="card-content">
50   - <view class="row-item">
51   - <text class="label">道路名称:</text>
52   - <text class="value up-line-1">{{ item.roadName }}</text>
53   - </view>
54   - <view class="row-item">
55   - <text class="label">所属街道:</text>
56   - <text class="value up-line-1">{{ item.streetName }}</text>
57   - </view>
58   - <view class="row-item flex-between">
59   - <view>
60   - <text class="label">养护级别:</text>
61   - <text class="value">{{uni.$dict.getDictLabel('conserve_level', item.levelId)}}</text>
  64 + <view class="u-body-item u-flex">
  65 + <view class="u-body-item-title">所属街道:</view>
  66 + <view class="u-line-1 u-body-value">{{ item.streetName }}
  67 + </view>
62 68 </view>
63   - <text class="detail-btn" @click="gotoDetail(item)">计划明细</text>
64   - </view>
65   - <view class="row-item">
66   - <text class="label">计划类型:</text>
67 69  
68   - <text class="value up-line-1"> {{uni.$dict.getDictLabel('inspection_maintain_type', item.planTypeId)}}</text>
69   - </view>
70   - <view class="row-item">
71   - <text class="label">计划时间:</text>
72   -<!-- <text class="value up-line-1">{{ formatPlanTime(item.beginTime, item.endTime) }}</text>-->
73   - <text class="value up-line-1">{{ timeFormat(item.beginTime,'yyyy-mm-dd')}} 至 {{ timeFormat(item.endTime,'yyyy-mm-dd')}} </text>
  70 + <view class="u-body-item u-flex common-item-center common-justify-between">
  71 + <view class="u-body-item-title">养护级别: {{uni.$dict.getDictLabel('conserve_level', item.levelId) || '-'}}</view>
  72 + <view class="u-line-1">
  73 + <up-button
  74 + type="primary"
  75 + size="mini"
  76 + @click="gotoDetail(item)"
  77 + class="submit-record-btn"
  78 + >
  79 + 计划明细
  80 + </up-button>
  81 + </view>
  82 + </view>
74 83  
  84 + <view class="u-body-item u-flex">
  85 + <view class="u-body-item-title">计划类型:</view>
  86 + <view class="u-line-1 u-body-value">{{uni.$dict.getDictLabel('inspection_maintain_type', item.planTypeId)}}</view>
  87 + </view>
  88 +
  89 + <view class="u-body-item u-flex">
  90 + <view class="u-body-item-title">计划时间:</view>
  91 + <view class="u-line-1 u-body-value">{{ timeFormat(item.beginTime, 'yyyy-mm-dd') || '-' }} 至
  92 + {{ timeFormat(item.endTime, 'yyyy-mm-dd') || '-' }}
  93 + </view>
  94 + </view>
75 95 </view>
76   - </view>
77   - </view>
  96 + </template>
  97 + </up-card>
78 98 </view>
79 99  
80 100 </z-paging>
... ... @@ -92,16 +112,15 @@ const tabList = ref([
92 112 {name: '已失效', id: '3'},
93 113 {name: '已完成', id: '2'}
94 114 ]);
95   -
  115 +const pagingRef = ref(null)
96 116 const activeTab = ref('1');
97 117 // 搜索相关
98 118 const searchValue = ref('');
99 119 // 分页相关
100   -const pageNo = ref(1);
101   -const pageSize = ref(10);
  120 +// const pageNo = ref(1);
  121 +// const pageSize = ref(10);
102 122  
103 123 const planList = ref([]);
104   -const paging = ref(null);
105 124  
106 125  
107 126 // Tab切换
... ... @@ -110,17 +129,17 @@ const handleTabChange = (val) =&gt; {
110 129 console.log(activeTab.value)
111 130 activeTab.value = val.id
112 131 searchValue.value = ''
113   - paging.value.reload()
  132 + pagingRef.value.reload()
114 133 };
115 134 // 搜索/清空搜索
116 135 const handleSearch = () => {
117 136 // searchValue.value = '';
118 137 console.log(searchValue.value)
119   - paging.value.reload()
  138 + pagingRef.value.reload()
120 139 };
121 140 const handleSearchClear = () => {
122 141 // searchValue.value = ''
123   - paging.value.reload()
  142 + pagingRef.value.reload()
124 143 };
125 144 // 加载数据
126 145 const queryList = async (pageNo, pageSize) => {
... ... @@ -134,97 +153,42 @@ const queryList = async (pageNo, pageSize) =&gt; {
134 153 console.log('请求参数:', params);
135 154 const res = await inspectionPlanPage(params);
136 155 console.log('接口返回:', res);
137   - paging.value.complete(res.list);
  156 + pagingRef.value.complete(res.list);
138 157 } catch (error) {
139 158 console.error('加载失败:', error);
140 159 // 修复点4:加载失败调用complete(false)
141   - paging.value?.complete(false);
  160 + pagingRef.value?.complete(false);
142 161 uni.showToast({title: '加载失败,请重试', icon: 'none'});
143 162 }
144 163 };
145 164 // 跳转明细
146 165 const gotoDetail = (item) => {
147 166 uni.navigateTo({
148   - url: `/pages-sub/daily/patrol-manage/pending-plan-detail/index?batchNo=${item.batchNo}&status=${activeTab.value}`
  167 + url: `/pages-sub/daily/patrol-manage/pending-plan-detail?batchNo=${item.batchNo}&status=${activeTab.value}`
149 168 });
150 169 };
151 170 // 修复点5:优化页面生命周期逻辑
152 171 onLoad(() => {
153   - // auto=true时,z-paging会自动触发query,此处可省略手动调用;若需强制初始化,可加:
154   - // paging.value?.triggerQuery();
  172 + // auto=true时,z-pagingRef会自动触发query,此处可省略手动调用;若需强制初始化,可加:
  173 + // pagingRef.value?.triggerQuery();
155 174 });
156 175 // 仅在页面从明细页返回时,若有数据则刷新当前tab数据(避免干扰上拉加载)
157 176 onShow(() => {
  177 + pagingRef.value?.reload()
158 178 });
159 179 </script>
160 180  
161 181 <style scoped lang="scss">
162   -/* 样式保持不变,仅补充z-paging容器高度 */
163 182 .page-container {
164   - min-height: 100vh;
165   - background-color: #f8f8f8;
166   -}
167   -
168   -.top-fixed {
169   - position: fixed;
170   - top: 0;
171   - left: 0;
172   - right: 0;
173   - z-index: 999;
174   - background-color: #fff;
175   - padding-bottom: 10rpx;
176   - box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
177   -}
178 183  
179   -/* 修复:确保列表容器不被顶部遮挡,且z-paging能识别滚动区域 */
180   -.card-list {
181   - padding: 170rpx 20rpx 20rpx;
182   - /* 关键:给z-paging足够的滚动空间 */
183   -}
184   -
185   -.plan-card {
186   - background-color: #fff;
187   - border-radius: 12rpx;
188   - padding: 20rpx;
189   - margin-bottom: 15rpx;
190   - box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.03);
191   -}
192   -
193   -.card-content {
194   - display: flex;
195   - flex-direction: column;
196   - gap: 12rpx;
197   -}
198   -
199   -.row-item {
200   - display: flex;
201   - align-items: center;
202   - font-size: 28rpx;
203   - line-height: 1.5;
204   -}
205   -
206   -.flex-between {
207   - display: flex;
208   - justify-content: space-between;
209   - align-items: center;
210   -}
211   -
212   -.label {
213   - color: #999;
214   - width: 140rpx;
215   - flex-shrink: 0;
216   -}
217   -
218   -.value {
219   - color: #333;
220   - flex: 1;
221 184 }
  185 +.sticky-header {
  186 + background-color: #ffffff;
  187 + padding-bottom: 10rpx;
  188 + border-bottom: 1px solid #eee;
222 189  
223   -.detail-btn {
224   - color: #1989fa;
225   - font-size: 26rpx;
226   - padding: 0 10rpx;
  190 + .search-input {
  191 + margin: 20rpx 20rpx 10rpx !important;
  192 + }
227 193 }
228   -
229   -
230 194 </style>
231 195 \ No newline at end of file
... ...
pages-sub/daily/patrol-manage/pending-plan-detail/index.vue renamed to pages-sub/daily/patrol-manage/pending-plan-detail.vue
1 1 <template>
2   - <view class="pending-plan-detail">
3   - <!-- 计划详情卡片 -->
4   - <view class="detail-card" v-for="i in planInfo" :key="i.planNo">
5   - <!-- 标题行 -->
6   - <view class="detail-item">
7   - <text class="label">计划名称:</text>
8   - <text class="value up-line-1">{{ i.planName || '-' }}</text>
9   - </view>
10   -
11   - <!-- 计划编码行 -->
12   - <view class="detail-item">
13   - <text class="label">计划编码:</text>
14   - <text class="value up-line-1">{{ i.planNo || '-' }}</text>
15   - </view>
16   -
17   - <!-- 养护周期行 -->
18   - <view class="detail-item">
19   - <text class="label">养护周期:</text>
20   - <text class="value up-line-1">{{ i.rate || '-' }} {{ uni.$dict.getDictLabel('cycle_id_type', i.cycleId) }}
21   - </text>
22   - </view>
23   - <!-- cycle_id_type-->
24   - <!-- 计划完成次数行 -->
25   - <view class="detail-item">
26   - <text class="label">计划完成次数:</text>
27   - <text class="value up-line-1">{{ i.planNum || 0 }} 次</text>
28   - </view>
29   -
30   - <!-- 已完成次数行 + 查看记录按钮 -->
31   - <view class="detail-item flex-between">
32   - <view class="left-wrap">
33   - <text class="label">已完成次数:</text>
34   - <text class="value up-line-1">{{ planInfo.i || 0 }} 次</text>
35   - </view>
36   - <!-- 查看记录按钮(限制宽度+紧凑样式) -->
37   -
38   - <up-button
39   - v-if="i.planFinishNum>0"
40   - type="primary"
41   - size="mini"
42   - @click="gotoFinishPlanDetail(i)"
43   - :style="{ width: '80px', height: '28px', fontSize: '14px', borderRadius: 4 }"
44   - >
45   - 查看记录
46   - </up-button>
47   - </view>
48   -
49   - <!-- 计划有效期行 -->
50   - <view class="detail-item">
51   - <text class="label">计划有效期:</text>
52   - <!-- <text class="value up-line-1">{{ planInfo && planInfo.validTime ? planInfo.validTime : '-' }}</text>-->
53   - <text class="value up-line-1">{{ timeFormat(i.beginTime, 'yyyy-mm-dd') }} 至
54   - {{ timeFormat(i.endTime, 'yyyy-mm-dd') }}
55   - </text>
56   - </view>
  2 + <view class="page-container">
  3 +
  4 + <view class="common-card-list" style=" ">
  5 + <up-card
  6 + :border="false"
  7 + :foot-border-top="false"
  8 + v-for="(item,index) in planInfo"
  9 + :key="`${item.planNo}_${index}`"
  10 + >
  11 + <!-- 自定义标题区域 -->
  12 + <template #head>
  13 + <view class="card-header">
  14 + <view class="common-card-title u-line-1">{{ item.planName || '无计划名称' }}</view>
  15 + <!-- 已失效标识 -->
  16 + <up-text type="error" v-if="item.finishState === '3'" text="错误" class="invalid-tag">已失效</up-text>
  17 + <!-- <view v-if="item.finishState === '3'" class="invalid-tag">已失效</view>-->
  18 + </view>
  19 + </template>
  20 +
  21 + <template #body>
  22 + <view class="card-body">
  23 + <view class="u-body-item u-flex">
  24 + <view class="u-body-item-title">计划编码:</view>
  25 + <view class="u-line-1 u-body-value">{{ item.planNo || '-' }}</view>
  26 + </view>
  27 + <view class="u-body-item u-flex">
  28 + <view class="u-body-item-title">养护周期:</view>
  29 + <view class="u-line-1 u-body-value">{{ item.rate || '-' }}
  30 + {{ uni.$dict.getDictLabel('cycle_id_type', item.cycleId) }}
  31 + </view>
  32 + </view>
  33 +
  34 + <view class="u-body-item u-flex common-item-center common-justify-between">
  35 + <view class="u-body-item-title">计划完成次数: {{ item.planNum || 0 }}</view>
  36 + <view class="u-line-1">
  37 + <up-button
  38 + v-if="item.finishState === '3'"
  39 + type="primary"
  40 + size="mini"
  41 + @click="gotoFinishPlanDetail(item)"
  42 + class="submit-record-btn"
  43 + :disabled="true"
  44 + >
  45 + 补交记录
  46 + </up-button>
  47 +
  48 + <up-button
  49 + v-if="item.finishState !== '3' && item.planFinishNum>0"
  50 + type="primary"
  51 + size="mini"
  52 + @click="gotoFinishPlanDetail(item)"
  53 + class="submit-record-btn"
  54 + >
  55 + 提交记录
  56 + </up-button>
  57 + </view>
  58 + </view>
  59 +
  60 + <view class="u-body-item u-flex">
  61 + <view class="u-body-item-title">已完成次数:</view>
  62 + <view class="u-line-1 u-body-value">{{ item.planFinishNum || 0 }}</view>
  63 + </view>
  64 +
  65 + <view class="u-body-item u-flex">
  66 + <view class="u-body-item-title">计划有效期:</view>
  67 + <view class="u-line-1 u-body-value">{{ timeFormat(item.beginTime, 'yyyy-mm-dd') || '-' }} 至
  68 + {{ timeFormat(item.endTime, 'yyyy-mm-dd') || '-' }}
  69 + </view>
  70 + </view>
  71 + </view>
  72 + </template>
  73 + </up-card>
57 74 </view>
58 75  
  76 +
59 77 <!-- 底部新增记录按钮 status=3-->
60 78 <view class="fixed-bottom-btn-wrap" v-if="finishState==1">
61 79 <up-button
... ... @@ -111,7 +129,7 @@ const getPlanDetail = async () =&gt; {
111 129 // 跳转到已完成计划明细
112 130 const gotoFinishPlanDetail = (i) => {
113 131 uni.navigateTo({
114   - url: `/pages-sub/daily/patrol-manage/finish-plan-detail/index?planNo=${i.planNo}`
  132 + url: `/pages-sub/daily/patrol-manage/finish-plan-detail?planNo=${i.planNo}`
115 133  
116 134  
117 135 });
... ... @@ -119,57 +137,11 @@ const gotoFinishPlanDetail = (i) =&gt; {
119 137 // 新增记录
120 138 const addNewRecord = () => {
121 139 uni.navigateTo({
122   - url: `/pages-sub/daily/patrol-manage/add-patrol-record/index?planNo=${planInfo.value[0].planNo}&batchNo=${batchNo.value}`,
  140 + url: `/pages-sub/daily/patrol-manage/add-patrol-record?planNo=${planInfo.value[0].planNo}&batchNo=${batchNo.value}`,
123 141 });
124 142 };
125 143 </script>
126 144  
127 145 <style scoped lang="scss">
128   -.pending-plan-detail {
129   -
130   -}
131   -
132   -.detail-card {
133   - padding: 20rpx;
134   - background-color: #fff;
135   - margin-bottom: 20px;
136   -}
137   -
138   -.detail-item {
139   - display: flex;
140   - align-items: center;
141   - font-size: 28rpx;
142   - line-height: 1.8;
143   - padding: 10rpx 0;
144   - border-bottom: 1px solid #f5f5f5;
145   -
146   - &:last-child {
147   - border-bottom: none;
148   - }
149   -}
150   -
151   -.flex-between {
152   - display: flex;
153   - justify-content: space-between;
154   - align-items: center;
155   -
156   - .left-wrap {
157   - display: flex;
158   - align-items: center;
159   - flex: 1; // 占满剩余空间,按钮靠右
160   - }
161   -}
162   -
163   -.label {
164   - color: #999;
165   - width: 200rpx;
166   - flex-shrink: 0;
167   -}
168   -
169   -.value {
170   - color: #333;
171   - flex: 1;
172   - word-break: break-all;
173   -}
174 146  
175 147 </style>
176 148 \ No newline at end of file
... ...
pages-sub/daily/quick-order/index.vue
1 1 <template>
2   - <view class="u-page">
  2 + <view class="page-container">
3 3 <!-- 顶部固定搜索栏 -->
4 4 <up-sticky>
5 5 <view class="search-header">
... ... @@ -37,36 +37,62 @@
37 37 ref="paging"
38 38 v-model="orderList"
39 39 @query="queryList"
40   - :top="100"
41   - :bottom="120"
  40 + :auto-show-system-loading="true"
42 41 >
43 42 <template #empty>
44 43 <empty-view/>
45 44 </template>
46 45  
47   - <!-- 修复:新增列表容器,配置顶部内边距 -->
48   - <view class="order-list">
49   - <view class="order-card" v-for="item in orderList" :key="item.orderNo">
50   - <view class="order-item up-line-1">工单编号:{{ item.orderNo }}</view>
51   - <view class="order-item up-line-1">工单位置:{{ item.roadName || '未填写' }}</view>
52   - <view class="order-item up-line-1">工单名称:{{ item.orderName || '未填写' }}</view>
53   - <view class="order-item up-line-1">情况描述:{{ item.remark || '无' }}</view>
54   - <view class="order-footer">
55   - <view class="submit-time up-line-1">提交时间:{{ timeFormat(item.createTime, 'yyyy-mm-dd hh:MM:ss') }}</view>
56   - <up-button
57   - type="primary"
58   - size="mini"
59   - @click="handleDetail(item)"
60   - :style="{ width: '80px', height: '28px', fontSize: '14px', borderRadius: 4 }"
61   - >
62   - 工单详情
63   - </up-button>
64   - </view>
65   - </view>
  46 + <view class="common-card-list" style=" padding-top: 100rpx;">
  47 + <up-card
  48 + :border="false"
  49 + :foot-border-top="false"
  50 + v-for="(item,index) in orderList"
  51 + :key="`${item.orderNo}_${index}`"
  52 + :show-head="false"
  53 + >
  54 +
  55 + <template #body>
  56 + <view class="card-body">
  57 + <view class="u-body-item u-flex">
  58 + <view class="u-body-item-title">工单编号:</view>
  59 + <view class="u-line-1 u-body-value">{{ item.orderNo || '-' }}</view>
  60 + </view>
  61 + <view class="u-body-item u-flex">
  62 + <view class="u-body-item-title">工单位置:</view>
  63 + <view class="u-line-1 u-body-value">{{ item.roadName || '-' }}</view>
  64 + </view>
  65 +
  66 + <view class="u-body-item u-flex ">
  67 + <view class="u-body-item-title">工单名称:</view>
  68 + <view class="u-line-1 u-body-value"> {{ item.orderName || '未填写' }}</view>
  69 + </view>
  70 +
  71 + <view class="u-body-item u-flex">
  72 + <view class="u-body-item-title">情况描述:</view>
  73 + <view class="u-line-1 u-body-value">{{ item.remark || '无' }}</view>
  74 + </view>
  75 +
  76 + <view class="u-body-item u-flex common-item-center common-justify-between">
  77 + <view class="u-body-item-title u-body-value">提交时间:{{ timeFormat(item.createTime, 'yyyy-mm-dd hh:MM:ss') }}</view>
  78 + <view class="">
  79 + <up-button
  80 + type="primary"
  81 + size="mini"
  82 + @click="handleDetail(item)"
  83 +
  84 + >
  85 + 工单详情
  86 + </up-button>
  87 + </view>
  88 +
  89 + </view>
  90 + </view>
  91 + </template>
  92 + </up-card>
66 93 </view>
67 94 </z-paging>
68 95  
69   - <!-- 修复:补充底部按钮样式层级 -->
70 96 <view class="fixed-bottom-btn-wrap">
71 97 <up-button type="primary" size="large" @click="handleAddOrder">
72 98 新增工单
... ... @@ -76,12 +102,9 @@
76 102 </template>
77 103  
78 104 <script setup>
79   -import { ref, computed } from 'vue';
  105 +import { ref } from 'vue';
80 106 import { workorderPage } from "@/api/quick-order/quick-order";
81 107 import { timeFormat } from '@/uni_modules/uview-plus';
82   -// ========== 修复1:声明所有核心响应式变量 ==========
83   -// 顶部/底部高度(rpx)
84   -// 排序相关:适配up-select的格式
85 108 const selectedSortValue = ref(1);
86 109 // 1 位置 2 工单名称 3 情况描述 4 工单编号
87 110 const sortOptions = ref([
... ... @@ -91,16 +114,13 @@ const sortOptions = ref([
91 114 {name: '编号', id: 4},
92 115 ]);
93 116 // 分页相关(核心:声明orderList)
94   -const pageNo = ref(1);
95   -const pageSize = ref(10);
96 117 const paging = ref(null);
97 118 const orderList = ref([]); // 修复:新增列表变量
98 119 // 搜索相关
99 120 const searchValue = ref('');
100   -// ========== 修复3:适配z-paging回调参数 ==========
  121 +// ========== 适配z-paging回调参数 ==========
101 122 const queryList = async (pageNo, pageSize) => {
102 123 try {
103   - // 修复:z-paging的query回调参数是对象 {pageNo, pageSize}
104 124 const apiParams = {
105 125 searchContent: searchValue.value.trim() || '',
106 126 pageNo: pageNo,
... ... @@ -143,8 +163,6 @@ const handleAddOrder = () =&gt; {
143 163 </script>
144 164  
145 165 <style scoped lang="scss">
146   -
147   -
148 166 // 顶部搜索栏
149 167 .search-header {
150 168 display: flex;
... ... @@ -168,48 +186,10 @@ const handleAddOrder = () =&gt; {
168 186 font-size: 28rpx;
169 187 }
170 188 }
171   -
172 189 .search-input-wrap {
173 190 flex: 3;
174 191 }
175 192 }
176 193  
177   -// 修复:列表容器样式(核心)
178   -.order-list {
179   - padding: 120rpx 20rpx 20rpx; // 顶部内边距避开搜索栏
180   - box-sizing: border-box;
181   -}
182   -
183   -// 工单卡片样式
184   -.order-card {
185   - background-color: #fff;
186   - border-radius: 12rpx;
187   - padding: 24rpx;
188   - margin-bottom: 20rpx;
189   - box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
190   -
191   - .order-item {
192   - font-size: 28rpx;
193   - color: #333;
194   - line-height: 48rpx;
195   - margin-bottom: 8rpx;
196   - }
197   -
198   - .order-footer {
199   - display: flex;
200   - justify-content: space-between;
201   - align-items: center;
202   -
203   - .submit-time {
204   - flex: 1;
205   - overflow: hidden;
206   - text-overflow: ellipsis;
207   - white-space: nowrap;
208   - font-size: 26rpx;
209   - color: #666;
210   - }
211   -
212   - }
213   -}
214 194  
215 195 </style>
216 196 \ No newline at end of file
... ...
pages-sub/daily/quick-order/order-detail.vue
1 1 <template>
2   - <view class="u-page">
  2 + <view class="page-container">
3 3 <!-- 页面级加载组件 -->
4 4 <up-loading-page
5 5 v-if="loading"
... ... @@ -11,14 +11,12 @@
11 11 <!-- 内容容器 -->
12 12 <view v-else class="content-wrap">
13 13 <!-- 空状态 -->
14   - <view v-if="!Object.keys(orderDetail).length" class="empty-wrap">
15   - <text class="empty-icon">📄</text>
16   - <text class="empty-text">暂无工单详情</text>
17   - <text class="empty-subtext">请检查工单ID是否正确</text>
  14 + <view v-if="!Object.keys(orderDetail).length" >
  15 + <empty-view />
18 16 </view>
19 17  
20 18 <!-- 工单详情内容 -->
21   - <up-cell-group :border="false" inset style="margin: 20rpx;" v-else>
  19 + <up-cell-group :border="false" inset v-else>
22 20 <!-- 1. 工单编号 -->
23 21 <up-cell
24 22 title="工单编号"
... ... @@ -29,11 +27,16 @@
29 27  
30 28 <!-- 2. 工单位置 -->
31 29 <up-cell
32   - title="工单位置"
33   - :value="orderDetail.roadName || '--'"
34   - class="up-line-1"
35 30 align="middle"
36   - ></up-cell>
  31 + >
  32 + <template #title>
  33 + <view style="min-width: 200rpx">工单位置</view>
  34 + </template>
  35 + <template #value>
  36 + <view class="up-line-1">{{orderDetail.roadName || '--'}}</view>
  37 + </template>
  38 +
  39 + </up-cell>
37 40  
38 41 <!-- 3. 工单名称 -->
39 42 <up-cell
... ... @@ -45,11 +48,15 @@
45 48  
46 49 <!-- 4. 情况描述 -->
47 50 <up-cell
48   - title="情况描述"
49   - :value="orderDetail.remark || '--'"
50   - class="up-line-1"
51 51 align="middle"
52   - ></up-cell>
  52 + >
  53 + <template #title>
  54 + <view style="min-width: 200rpx">情况描述</view>
  55 + </template>
  56 + <template #value>
  57 + <view class="up-line-1">{{orderDetail.remark || '--'}}</view>
  58 + </template>
  59 + </up-cell>
53 60  
54 61 <!-- 5. 问题照片(核心修复:判断条件+空值处理) -->
55 62 <up-cell title="问题照片" >
... ... @@ -87,12 +94,16 @@
87 94  
88 95 <!-- 7. 处理结果 -->
89 96 <up-cell
90   - title="处理结果"
91   - :value="orderDetail.handleResult || '--'"
92   - class="up-line-1"
93 97 align="middle"
94 98 :border="false"
95   - ></up-cell>
  99 + >
  100 + <template #title>
  101 + <view style="min-width: 200rpx">处理结果</view>
  102 + </template>
  103 + <template #value>
  104 + <view class="up-line-1">{{orderDetail.handleResult || '--'}}</view>
  105 + </template>
  106 + </up-cell>
96 107 </up-cell-group>
97 108 </view>
98 109 </view>
... ... @@ -102,6 +113,7 @@
102 113 import { ref, reactive } from 'vue';
103 114 import { inspectionPlanDetail } from "@/api/quick-order/quick-order";
104 115 import { onLoad, onShow } from '@dcloudio/uni-app';
  116 +import EmptyView from "../../../components/empty-view/empty-view.vue";
105 117  
106 118 // 状态管理
107 119 const loading = ref(true);
... ... @@ -145,9 +157,7 @@ onLoad((options) =&gt; {
145 157 <style scoped lang="scss">
146 158 // 页面基础样式
147 159 .u-page {
148   - min-height: 100vh;
149   - background-color: #f5f5f5;
150   - box-sizing: border-box;
  160 +
151 161 }
152 162  
153 163 // 内容容器
... ... @@ -155,93 +165,9 @@ onLoad((options) =&gt; {
155 165 background: #fff;
156 166 width: 100%;
157 167 box-sizing: border-box;
158   - overflow-y: auto;
159   - min-height: calc(100vh - 40rpx);
160   -}
161   -
162   -
163   -
164   -// 空文本样式
165   -.empty-text {
166   - color: #999;
167   - font-size: 28rpx;
168   - line-height: 80rpx;
169   - display: block;
170   - text-align: left;
171   -}
172   -
173   -// 优化uview组件样式
174   -:deep(.up-cell-group) {
175   - --u-cell-group-background-color: #fff;
176   - --u-cell-group-border-radius: 12rpx;
177   - --u-cell-group-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
178   -}
179   -
180   -:deep(.up-cell) {
181   - --u-cell-title-font-size: 28rpx;
182   - --u-cell-value-font-size: 28rpx;
183   - --u-cell-title-color: #666;
184   - --u-cell-value-color: #333;
185   - --u-cell-padding: 20rpx 15rpx;
186   - --u-cell-border-color: #f5f5f5;
187   -}
188   -
189   -// 相册样式优化(关键:适配图片展示)
190   -:deep(.up-album) {
191   - width: 100%;
192   - box-sizing: border-box;
193 168 }
194 169  
195   -:deep(.up-album__list) {
196   - display: flex;
197   - flex-wrap: wrap;
198   - padding: 0;
199   - margin: 0;
200   -}
201 170  
202   -:deep(.up-album__item) {
203   - width: calc(33.333% - 10rpx);
204   - height: 200rpx; // 固定图片高度,避免变形
205   - margin: 5rpx;
206   - border-radius: 8rpx;
207   - overflow: hidden;
208   - background-color: #f8f8f8;
209   -}
210 171  
211   -:deep(.up-album__image) {
212   - width: 100%;
213   - height: 100%;
214   - object-fit: cover; // 图片裁剪填充,避免拉伸
215   -}
216   -
217   -// 原生空状态样式
218   -.empty-wrap {
219   - margin-top: 200rpx;
220   - text-align: center;
221   -}
222   -
223   -.empty-icon {
224   - font-size: 80rpx;
225   - display: block;
226   - margin-bottom: 20rpx;
227   - color: #ddd;
228   -}
229 172  
230   -.empty-text {
231   - font-size: 28rpx;
232   - color: #999;
233   - display: block;
234   -}
235   -
236   -.empty-subtext {
237   - font-size: 24rpx;
238   - color: #ccc;
239   - margin-top: 10rpx;
240   - display: block;
241   -}
242   -
243   -// 加载组件样式
244   -:deep(.up-loading-page) {
245   - margin-top: 100rpx;
246   -}
247 173 </style>
248 174 \ No newline at end of file
... ...
pages.json
... ... @@ -31,13 +31,13 @@
31 31 "root": "pages-sub/daily",
32 32 "pages": [
33 33 {
34   - "path": "patrol-manage/patrol-plan/index",
  34 + "path": "patrol-manage/index",
35 35 "style": {
36 36 "navigationBarTitleText": "巡查计划"
37 37 }
38 38 },
39 39 {
40   - "path": "patrol-manage/pending-plan-detail/index",
  40 + "path": "patrol-manage/pending-plan-detail",
41 41 "style": {
42 42 "navigationBarTitleText": "计划明细",
43 43 "enablePullDownRefresh": false
... ... @@ -45,7 +45,7 @@
45 45 },
46 46  
47 47 {
48   - "path": "patrol-manage/finish-plan-detail/index",
  48 + "path": "patrol-manage/finish-plan-detail",
49 49 "style": {
50 50 "navigationBarTitleText": "已完成计划明细",
51 51 "enablePullDownRefresh": false
... ... @@ -53,7 +53,7 @@
53 53 },
54 54  
55 55 {
56   - "path": "patrol-manage/add-patrol-record/index",
  56 + "path": "patrol-manage/add-patrol-record",
57 57 "style": {
58 58 "navigationBarTitleText": "添加巡查记录",
59 59 "enablePullDownRefresh": false
... ...