Commit fb13622a3643603c9449e18ebda47ffb311d9b5c

Authored by 刘淇
1 parent 834a3df1

养护计划列表 样式 差去一个卡片的头部

... ... @@ -48,6 +48,35 @@ page {
48 48 height: 100%;
49 49 }
50 50  
  51 +// 卡片列表样式
  52 +.common-card-list {
  53 + .common-card-title {
  54 +
  55 + }
  56 +
  57 + .u-body-item {
  58 + margin-bottom: 16rpx;
  59 + &:last-child {
  60 + margin-bottom: 0;
  61 + }
  62 + }
  63 +
  64 + .u-body-value {
  65 + flex: 1
  66 + }
  67 +}
  68 +
  69 +
  70 +// 通用样式
  71 +.common-item-center {
  72 + align-items: center;
  73 +}
  74 +
  75 +.common-justify-between {
  76 + justify-content: space-between;
  77 +}
  78 +
  79 +
51 80 // 底部按钮样式
52 81 .fixed-bottom-btn-wrap {
53 82 position: fixed;
... ...
api/maintain-manage/maintain-manage.js
... ... @@ -29,9 +29,28 @@ export const getRoadDetails = (params) => {
29 29 };
30 30  
31 31 /**
32   - * 巡查计划完成详情
  32 + * 新增养护计划
33 33 * @returns {Promise}
34 34 */
35   -export const inspectionCreate = (data) => {
36   - return get('/app-api/app/garden/inspection-plan-commit/create',data);
  35 +export const maintainCreate = (data) => {
  36 + return post('/app-api/app/garden/maintain-plan-commit/create',data);
37 37 };
  38 +
  39 +/**
  40 + * 未完成养护计划
  41 + * @returns {Promise}
  42 + */
  43 +export const notFinish = (data) => {
  44 + return post('/app-api/app/garden/maintain-plan-detail/get/not-finish',data);
  45 +};
  46 +
  47 +
  48 +/**
  49 + * 计划详情
  50 + * @returns {Promise}
  51 + */
  52 +export const detailList = (data) => {
  53 + return post('/app-api/app/garden/maintain-plan-commit/page',data);
  54 +};
  55 +
  56 +
... ...
pages-sub/daily/maintain-manage/add-record.vue 0 → 100644
  1 +<template>
  2 + <view class="u-page">
  3 + <!-- 核心:将所有 up-form-item 包裹在同一个 up-form 内 -->
  4 + <view class="inspect-form-content commonPageLRpadding">
  5 + <up-form
  6 + label-position="left"
  7 + :model="inspectForm"
  8 + ref="inspectFormRef"
  9 + labelWidth="140rpx"
  10 + >
  11 + <!-- 1. 巡查描述(文本域) -->
  12 + <up-form-item
  13 + prop="content"
  14 + class="form-item"
  15 + >
  16 + <up-textarea
  17 + v-model="inspectForm.remark"
  18 + placeholder="请输入巡查描述"
  19 + maxlength="200"
  20 + count
  21 + ></up-textarea>
  22 + </up-form-item>
  23 +
  24 + <!-- 2. 上传图片 -->
  25 + <up-form-item
  26 + label="上传图片"
  27 + prop="images"
  28 + required
  29 + border-bottom
  30 + class="form-item"
  31 + >
  32 + <up-upload
  33 + :file-list="imagesList"
  34 + @after-read="(event) => uploadImgs(event)"
  35 + @delete="(event) => deleteImg(event)"
  36 + @on-exceed="handleExceed"
  37 + multiple
  38 + :max-count="3"
  39 + upload-text="选择图片"
  40 + del-color="#ff4d4f"
  41 + class="upload-wrap"
  42 + ></up-upload>
  43 + </up-form-item>
  44 +
  45 + <!-- 3. 完成进度(滑块) -->
  46 + <up-form-item
  47 + label="完成进度"
  48 + prop="progress"
  49 + required
  50 + class="form-item"
  51 + >
  52 + <view class="progress-wrap">
  53 + <up-slider
  54 + v-model="inspectForm.progress"
  55 + :min="initProgress"
  56 + :max="100"
  57 +
  58 + active-color="#1989fa"
  59 + inactive-color="#e5e5e5"
  60 + block-size="24"
  61 + class="progress-slider"
  62 + ></up-slider>
  63 + <view class="progress-value">{{ inspectForm.progress }}%</view>
  64 + <view class="progress-tips" v-if="inspectForm.progress <= initProgress">
  65 + 进度低于等于{{ initProgress }}%,无法调整
  66 + </view>
  67 + </view>
  68 + </up-form-item>
  69 +
  70 + </up-form>
  71 + </view>
  72 +
  73 + <!-- 底部提交按钮 -->
  74 + <view class="fixed-bottom-btn-wrap">
  75 + <up-button
  76 + type="primary"
  77 + text="提交"
  78 + @click="submitInspect"
  79 + :style="{ width: '100%', height: '88rpx', fontSize: '32rpx', borderRadius: 0 }"
  80 + ></up-button>
  81 + </view>
  82 + </view>
  83 +</template>
  84 +
  85 +<script setup lang="ts">
  86 +import { ref } from 'vue'
  87 +import type { UniFormRef } from '@/uni_modules/uview-plus/types'
  88 +// 定义ref供选项式API使用
  89 +const inspectFormRef = ref<UniFormRef>(null)
  90 +</script>
  91 +
  92 +<script lang="ts">
  93 +import { uploadImages } from '@/common/utils/upload';
  94 +import { maintainCreate } from "@/api/maintain-manage/maintain-manage";
  95 +
  96 +export default {
  97 + data() {
  98 + return {
  99 + // 图片列表
  100 + imagesList: [],
  101 + // 从URL获取的初始进度值
  102 + initProgress: 0,
  103 + // 巡查表单数据
  104 + inspectForm: {
  105 + remark: '', // 巡查描述
  106 + progress: 0 // 完成进度(0-100)
  107 + },
  108 + paramsOptins: {}, // 接受参数
  109 + // 表单校验规则
  110 + inspectFormRules: {
  111 + images: [
  112 + {
  113 + required: true,
  114 + message: '请上传图片',
  115 + trigger: 'change',
  116 + validator: (rule, value, callback) => {
  117 + // 自定义校验规则:检查是否有成功上传的图片
  118 + const hasSuccessImg = this.imagesList.some(item => item.status === 'success')
  119 + const imgCount = this.imagesList.filter(item => item.status === 'success').length
  120 +
  121 + if (!hasSuccessImg || imgCount < 1) {
  122 + callback(new Error('最少需要上传1张图片'))
  123 + } else if (imgCount > 3) {
  124 + callback(new Error('最多只能上传3张图片'))
  125 + } else {
  126 + callback()
  127 + }
  128 + }
  129 + }
  130 + ],
  131 + progress: [
  132 + {
  133 + type: 'number',
  134 + required: true,
  135 + message: '请设置完成进度',
  136 + trigger: ['change'],
  137 + validator: (rule, value, callback) => {
  138 + // 自定义校验:进度必须大于初始进度值
  139 + if (value <= this.initProgress) {
  140 + callback(new Error(`完成进度必须大于${this.initProgress}%`))
  141 + } else {
  142 + callback()
  143 + }
  144 + }
  145 + }
  146 + ]
  147 + }
  148 + }
  149 + },
  150 + onLoad(option) {
  151 + console.log('页面参数:', option)
  152 + this.paramsOptins = option
  153 +
  154 + // 从URL参数中获取进度值,默认0
  155 + this.initProgress = option.progress ? Number(option.progress) : 0
  156 + // 设置表单初始进度值
  157 + this.inspectForm.progress = this.initProgress
  158 +
  159 + console.log('初始进度值:', this.initProgress)
  160 + },
  161 + onReady() {
  162 + // 兼容微信小程序,通过setRules设置校验规则
  163 + this.$refs.inspectFormRef.setRules(this.inspectFormRules)
  164 + console.log('巡查表单规则初始化完成')
  165 + },
  166 + methods: {
  167 + /**
  168 + * 删除图片
  169 + */
  170 + deleteImg(event) {
  171 + console.log('删除图片事件:', event)
  172 + this.imagesList.splice(event.index, 1)
  173 + // 删除图片后重新校验图片字段
  174 + this.$refs.inspectFormRef.validateField('images')
  175 + uni.showToast({ title: '图片删除成功', icon: 'success' })
  176 + },
  177 +
  178 + /**
  179 + * 上传图片
  180 + */
  181 + async uploadImgs(event) {
  182 + console.log('上传图片事件:', event)
  183 + const fileList = Array.isArray(event.file) ? event.file : [event.file]
  184 + const targetImgList = this.imagesList
  185 +
  186 + const filePaths = fileList.map(item => item.url)
  187 + const tempItems = fileList.map(item => ({
  188 + ...item,
  189 + status: 'uploading',
  190 + message: '上传中'
  191 + }))
  192 + const startIndex = targetImgList.length
  193 + targetImgList.push(...tempItems)
  194 +
  195 + try {
  196 + const uploadResultUrls = await uploadImages({
  197 + filePaths: filePaths,
  198 + ignoreError: true
  199 + })
  200 + console.log('上传成功的URL列表:', uploadResultUrls)
  201 +
  202 + uploadResultUrls.forEach((url, index) => {
  203 + if (targetImgList[startIndex + index]) {
  204 + targetImgList.splice(startIndex + index, 1, {
  205 + ...fileList[index],
  206 + status: 'success',
  207 + message: '',
  208 + url: url
  209 + })
  210 + }
  211 + })
  212 +
  213 + if (uploadResultUrls.length < fileList.length) {
  214 + const failCount = fileList.length - uploadResultUrls.length
  215 + for (let i = uploadResultUrls.length; i < fileList.length; i++) {
  216 + if (targetImgList[startIndex + i]) {
  217 + targetImgList.splice(startIndex + i, 1, {
  218 + ...fileList[i],
  219 + status: 'failed',
  220 + message: '上传失败'
  221 + })
  222 + }
  223 + }
  224 + uni.showToast({ title: `成功上传${uploadResultUrls.length}张,失败${failCount}张`, icon: 'none' })
  225 + } else {
  226 + uni.showToast({ title: `成功上传${fileList.length}张图片`, icon: 'success' })
  227 + }
  228 +
  229 + // 上传完成后重新校验图片字段
  230 + this.$refs.inspectFormRef.validateField('images')
  231 + } catch (err) {
  232 + console.error('图片上传失败:', err)
  233 + for (let i = 0; i < fileList.length; i++) {
  234 + if (targetImgList[startIndex + i]) {
  235 + targetImgList.splice(startIndex + i, 1, {
  236 + ...fileList[i],
  237 + status: 'failed',
  238 + message: '上传失败'
  239 + })
  240 + }
  241 + }
  242 + uni.showToast({ title: '图片上传失败,请重试', icon: 'none' })
  243 +
  244 + // 上传失败后重新校验图片字段
  245 + this.$refs.inspectFormRef.validateField('images')
  246 + }
  247 + },
  248 +
  249 + /**
  250 + * 处理图片超出数量限制
  251 + */
  252 + handleExceed() {
  253 + uni.showToast({ title: '最多只能上传3张图片', icon: 'none' })
  254 + },
  255 +
  256 + /**
  257 + * 提取图片URL数组
  258 + */
  259 + getImgUrlList(imgList) {
  260 + return imgList.filter(item => item.status === 'success').map(item => item.url)
  261 + },
  262 +
  263 + /**
  264 + * 提交巡查表单
  265 + */
  266 + async submitInspect() {
  267 + console.log('当前完成进度:', this.inspectForm.progress)
  268 + try {
  269 + // 先执行表单校验
  270 + await this.$refs.inspectFormRef.validate()
  271 + console.log('图片列表:', this.imagesList)
  272 +
  273 + // 构造提交数据
  274 + const submitData = {
  275 + // "batchNo": this.paramsOptins.batchNo,
  276 + totalFinishPercent:this.inspectForm.progress,
  277 + "planNo": this.paramsOptins.planNo,
  278 + "imgHost": "1",
  279 + "beginImg": this.getImgUrlList(this.imagesList),
  280 + "commonUserList":[],
  281 + // "userId": '',
  282 + // "userName": '',
  283 + "remark": this.inspectForm.remark // 备注中记录进度
  284 + }
  285 +
  286 + // 显示加载中
  287 + uni.showLoading({ title: '提交中...' })
  288 +
  289 + await maintainCreate(submitData)
  290 +
  291 + uni.hideLoading()
  292 + uni.showToast({
  293 + title: '提交成功',
  294 + icon: 'success',
  295 + duration: 1000
  296 + })
  297 + // uni.navigateTo({
  298 + // url: `/pages-sub/daily/maintain-manage/add-record?finishState=${item.finishState}&planNo=${item.planNo}&finishPercent=${item.finishPercent}`
  299 + // })
  300 + // 延迟跳转(等待提示框显示完成)
  301 + setTimeout(() => {
  302 + uni.redirectTo({
  303 + url: '/pages-sub/daily/maintain-manage/road-detail-list'
  304 + })
  305 + }, 1000)
  306 +
  307 + } catch (error) {
  308 + // 隐藏加载框
  309 + uni.hideLoading()
  310 +
  311 + // 区分是表单校验失败还是接口调用失败
  312 + if (Array.isArray(error)) {
  313 + // 表单校验失败 - 静默处理(uView会自动提示)
  314 + } else {
  315 + // 接口调用失败
  316 + console.error('巡查表单提交失败:', error)
  317 + uni.showToast({
  318 + title: '提交失败,请重试',
  319 + icon: 'none',
  320 + duration: 2000
  321 + })
  322 + }
  323 + }
  324 + }
  325 + }
  326 +}
  327 +</script>
  328 +
  329 +<style lang="scss" scoped>
  330 +// 全局页面样式
  331 +.u-page {
  332 + background-color: #f5f5f5;
  333 + min-height: 100vh;
  334 +}
  335 +
  336 +// 巡查表单内容容器
  337 +.inspect-form-content {
  338 + background: #fff;
  339 + padding: 20rpx;
  340 + margin-bottom: 20rpx;
  341 +}
  342 +
  343 +// 进度滑块样式
  344 +.progress-wrap {
  345 + width: 100%;
  346 +
  347 + .progress-slider {
  348 + margin: 20rpx 0;
  349 + }
  350 +
  351 + .progress-value {
  352 + text-align: right;
  353 + font-size: 28rpx;
  354 + color: #333;
  355 + margin-bottom: 10rpx;
  356 + }
  357 +
  358 + .progress-tips {
  359 + font-size: 24rpx;
  360 + color: #ff4d4f;
  361 + margin-top: 10rpx;
  362 + }
  363 +}
  364 +
  365 +// 表单项目间距
  366 +.form-item {
  367 + margin-bottom: 20rpx;
  368 +}
  369 +
  370 +
  371 +</style>
0 372 \ No newline at end of file
... ...
pages-sub/daily/maintain-manage/finish-plan-detail.vue 0 → 100644
  1 +<template>
  2 + <view class="u-page">
  3 + <!-- 页面级加载组件 -->
  4 + <up-loading-page
  5 + v-if="loading"
  6 + :loading="true"
  7 + title="加载中..."
  8 + color="#3c9cff"
  9 + ></up-loading-page>
  10 +
  11 + <!-- 内容容器 -->
  12 + <view v-else class="content-wrap">
  13 +
  14 +
  15 + <template v-for="(i, index) in orderDetail" :key="index">
  16 + <!-- 工单详情内容 -->
  17 + <up-cell-group :border="false" inset style="margin: 20rpx;">
  18 + <!-- 1. 工单编号 -->
  19 + <up-cell
  20 + :title="i.planName"
  21 +
  22 + class="up-line-1"
  23 + align="middle"
  24 + ></up-cell>
  25 +
  26 + <!-- 2. 工单位置 -->
  27 + <up-cell
  28 + title="计划编码"
  29 + :value="i.planNo || '--'"
  30 + class="up-line-1"
  31 + align="middle"
  32 + ></up-cell>
  33 +
  34 + <!-- 3. 工单名称 -->
  35 + <up-cell
  36 + title="养护周期"
  37 + :value="`${i.rate}${uni.$dict.getDictLabel('cycle_id_type', i.cycleId)}`"
  38 + class="up-line-1"
  39 + align="middle"
  40 + ></up-cell>
  41 +
  42 + <!-- 4. 情况描述 -->
  43 + <up-cell
  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"
  47 + align="middle"
  48 + ></up-cell>
  49 +
  50 + <!-- 5. 问题照片(核心修复:判断条件+空值处理) -->
  51 + <up-cell title="照片" >
  52 + <template #value>
  53 + <view class="cell-content-wrap">
  54 +
  55 + <!-- 修复1:正确判断problemImgsList,补充空数组默认值 -->
  56 + <up-album
  57 + v-if="!!i.imgList?.length"
  58 + :urls="i.imgList || []"
  59 + singleSize="70"
  60 + :preview-full-image="true"
  61 +
  62 + ></up-album>
  63 + <text v-else class="empty-text">暂无问题照片</text>
  64 + </view>
  65 + </template>
  66 + </up-cell>
  67 +
  68 + <!-- 7. 处理结果 -->
  69 + <up-cell
  70 + title="巡查描述"
  71 + :value="i.remark || '--'"
  72 + class="up-line-1"
  73 + align="middle"
  74 + :border="false"
  75 + ></up-cell>
  76 +
  77 + <up-cell
  78 + title="提交时间"
  79 + :value="timeFormat(i.finishTime,'yy-mm-dd hh:MM:ss') || '--'"
  80 + class="up-line-1"
  81 + align="middle"
  82 + :border="false"
  83 + ></up-cell>
  84 +
  85 +
  86 + <up-cell
  87 + title="提交人"
  88 + :value="i.userName || '--'"
  89 + class="up-line-1"
  90 + align="middle"
  91 + :border="false"
  92 + ></up-cell>
  93 + </up-cell-group>
  94 + </template>
  95 +
  96 +
  97 + </view>
  98 + </view>
  99 +</template>
  100 +
  101 +<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 +
  107 +// 状态管理
  108 +const loading = ref(true);
  109 +const orderDetail = ref([]);
  110 +
  111 +
  112 +
  113 +/**
  114 + * 获取工单详情
  115 + */
  116 +const getOrderDetail = async (planNo: string) => {
  117 + try {
  118 + loading.value = true;
  119 + const res = await detailList({ planNo });
  120 + console.log('接口返回:', res);
  121 + // 优化:确保图片数组为数组类型,避免非数组导致渲染错误
  122 + orderDetail.value = {
  123 + ...res,
  124 + problemImgsList: Array.isArray(res.problemImgsList) ? res.problemImgsList : [],
  125 + completeImgsList: Array.isArray(res.completeImgsList) ? res.completeImgsList : []
  126 + };
  127 + } catch (error) {
  128 + console.error('获取工单详情失败:', error);
  129 + uni.showToast({ title: '加载失败,请重试', icon: 'none' });
  130 + } finally {
  131 + loading.value = false;
  132 + }
  133 +};
  134 +
  135 +// 页面加载
  136 +onLoad((options) => {
  137 + const { planNo } = options;
  138 + if (planNo) {
  139 + getOrderDetail(planNo);
  140 + } else {
  141 + loading.value = false;
  142 + uni.showToast({ title: '缺少工单ID', icon: 'none' });
  143 + }
  144 +});
  145 +</script>
  146 +
  147 +<style scoped lang="scss">
  148 +// 页面基础样式
  149 +.u-page {
  150 + min-height: 100vh;
  151 + background-color: #f5f5f5;
  152 + box-sizing: border-box;
  153 +}
  154 +
  155 +// 内容容器
  156 +.content-wrap {
  157 + background: #fff;
  158 + width: 100%;
  159 + 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; // 图片裁剪填充,避免拉伸
  217 +}
  218 +
  219 +
  220 +</style>
0 221 \ No newline at end of file
... ...
pages-sub/daily/maintain-manage/index.vue
1 1 <template>
2   - <view class="main-container">
  2 + <view class="page-container">
3 3 <!-- 吸顶区域 -->
4 4 <up-sticky>
5 5 <view class="sticky-wrap">
... ... @@ -50,84 +50,122 @@
50 50 ref="pagingRef"
51 51 v-model="currentList"
52 52 @query="fetchData"
53   - :top="200"
54   - :bottom="20"
55   - :page-size="pageSize"
  53 + :auto-show-system-loading="true"
56 54 >
57 55 <!-- 空数据提示 -->
58 56 <template #empty>
59 57 <empty-view/>
60 58 </template>
61 59  
62   - <!-- 加载中提示(z-paging内置,可自定义) -->
63   - <template #loading>
64   - <view class="loading-tip">
65   - <up-loading-page text="加载中..."></up-loading-page>
66   - </view>
67   - </template>
68   -
69   - <!-- 列表内容 -->
70   - <view class="content-wrap">
71 60 <!-- 道路类型卡片 -->
72   - <view v-if="activeType === '道路'" class="card-list">
73   - <view
74   - class="card-item"
75   - v-for="(item, index) in currentList"
76   - :key="index"
  61 + <view v-if="activeType === '道路'" class="common-card-list" style="padding-top: 144px;">
  62 +
  63 + <up-card
  64 + :border="false"
  65 + :foot-border-top="false"
  66 + :head-border-bottom="false"
  67 + v-for="(item,index) in currentList"
  68 + :key="`${item.planNo}_${index}`"
  69 + :show-header="false"
77 70 >
78   - <view class="card-content">
79   - <view class="card-text up-line-1">
80   - <span class="field-name">道路名称:</span>{{ item.roadName || '-' }}
81   - </view>
82   - <view class="card-text up-line-1">
83   - <span class="field-name">所属街道:</span>{{ item.streetName || '-' }}
84   - </view>
85   - <!-- 养护级别行增加计划明细按钮 -->
86   - <view class="card-text up-line-1">
87   - <span class="field-name">养护级别:</span>{{uni.$dict.getDictLabel('conserve_level', item.levelId) || '-'}}
88   - <view class="inline-action" @click="goToDetail(item)">
89   - 计划明细
  71 + <template #body>
  72 + <view class="card-body">
  73 + <view class="u-body-item u-flex">
  74 + <view class="u-body-item-title">道路名称:</view>
  75 + <view class="u-line-1 u-body-value">{{ item.roadName || '-' }}</view>
  76 + </view>
  77 +
  78 + <view class="u-body-item u-flex">
  79 + <view class="u-body-item-title">所属街道:</view>
  80 + <view class="u-line-1 u-body-value">{{ item.streetName }}
  81 + </view>
  82 + </view>
  83 +
  84 + <view class="u-body-item u-flex common-item-center common-justify-between">
  85 + <view class="u-body-item-title">养护级别: {{uni.$dict.getDictLabel('conserve_level', item.levelId) || '-'}}</view>
  86 + <view class="u-line-1">
  87 + <up-button
  88 + type="primary"
  89 + size="mini"
  90 + @click="goToDetail(item)"
  91 + class="submit-record-btn"
  92 + >
  93 + 计划明细
  94 + </up-button>
  95 + </view>
  96 + </view>
  97 +
  98 + <view class="u-body-item u-flex">
  99 + <view class="u-body-item-title">计划时间:</view>
  100 + <view class="u-line-1 u-body-value">{{ timeFormat(item.beginTime, 'yyyy-mm-dd') || '-' }} 至
  101 + {{ timeFormat(item.endTime, 'yyyy-mm-dd') || '-' }}
  102 + </view>
90 103 </view>
91 104 </view>
92   - <view class="card-text up-line-1">
93   - <span class="field-name">计划时间:</span>{{ timeFormat(item.beginTime,'yyyy-mm-dd') || '-'}} 至 {{ timeFormat(item.endTime,'yyyy-mm-dd') || '-'}}
94   - </view>
95   - </view>
96   - </view>
  105 + </template>
  106 + </up-card>
97 107 </view>
98 108  
99 109 <!-- 其他养护类型卡片(补植/浇水等) -->
100   - <view v-else class="card-list">
101   - <view
102   - class="card-item"
103   - v-for="(item, index) in currentList"
104   - :key="index"
  110 + <view v-else class="common-card-list" style="padding-top: 144px;">
  111 +
  112 + <up-card
  113 + :border="false"
  114 + :foot-border-top="false"
  115 + v-for="(item,index) in currentList"
  116 + :key="`${item.planNo}_${index}`"
  117 +
105 118 >
106   - <view class="card-content">
107   - <view class="card-text up-line-1 font-bold">{{ item.planName || '-' }}</view>
108   - <view class="card-text up-line-1">
109   - <span class="field-name">计划编码:</span>{{ item.planNo || '-' }}
110   - </view>
111   - <view class="card-text up-line-1">
112   - <span class="field-name">养护周期:</span>{{ item.rate || '-' }} {{ uni.$dict.getDictLabel('cycle_id_type', item.cycleId) }}
113   - </view>
114   - <view class="card-text up-line-1">
115   - <span class="field-name">计划完成次数:</span>{{ item.planNum || 0 }}
  119 + <!-- 自定义标题区域 -->
  120 + <template #head>
  121 + <view class="card-header">
  122 + <view class="common-card-title u-line-1">{{ item.planName || '无计划名称' }}</view>
116 123 </view>
117   - <!-- 已完成次数行增加提交记录按钮 -->
118   - <view class="card-text up-line-1">
119   - <span class="field-name">完成比较:</span>{{ item.finishPercent || 0 }}%
120   - <view class="inline-action submit-btn" @click="submitRecord(item)">
121   - 提交记录
  124 + </template>
  125 +
  126 + <template #body>
  127 + <view class="card-body">
  128 + <view class="u-body-item u-flex">
  129 + <view class="u-body-item-title">计划编码:</view>
  130 + <view class="u-line-1 u-body-value">{{ item.planNo || '-' }}</view>
  131 + </view>
  132 + <view class="u-body-item u-flex">
  133 + <view class="u-body-item-title">养护周期:</view>
  134 + <view class="u-line-1 u-body-value">{{ item.rate || '-' }}
  135 + {{ uni.$dict.getDictLabel('cycle_id_type', item.cycleId) }}
  136 + </view>
  137 + </view>
  138 +
  139 + <view class="u-body-item u-flex common-item-center common-justify-between">
  140 + <view class="u-body-item-title">计划完成次数: {{ item.planNum || 0 }}</view>
  141 + <view class="u-line-1">
  142 + <up-button
  143 + type="primary"
  144 + size="mini"
  145 + @click="submitRecord(item)"
  146 + class="submit-record-btn"
  147 + >
  148 + 提交记录
  149 + </up-button>
  150 + </view>
  151 + </view>
  152 +
  153 + <view class="u-body-item u-flex">
  154 + <view class="u-body-item-title">已完成比例:</view>
  155 + <view class="u-line-1 u-body-value">{{ item.finishPercent || 0 }}%</view>
  156 + </view>
  157 +
  158 + <view class="u-body-item u-flex">
  159 + <view class="u-body-item-title">计划有效期:</view>
  160 + <view class="u-line-1 u-body-value">{{ timeFormat(item.beginTime, 'yyyy-mm-dd') || '-' }} 至
  161 + {{ timeFormat(item.endTime, 'yyyy-mm-dd') || '-' }}
  162 + </view>
122 163 </view>
123 164 </view>
124   - <view class="card-text up-line-1">
125   - <span class="field-name">计划有效期:</span> {{timeFormat(item.beginTime,'yy-mm-dd hh:MM:ss')}} 至 {{timeFormat(item.endTime,'yy-mm-dd hh:MM:ss')}}
126   - </view>
127   - </view>
128   - </view>
  165 + </template>
  166 + </up-card>
  167 +
129 168 </view>
130   - </view>
131 169 </z-paging>
132 170 </view>
133 171 </template>
... ... @@ -298,7 +336,7 @@ onLoad(() =&gt; {
298 336  
299 337 // 内容区域样式
300 338 .content-wrap {
301   - padding: 20rpx;
  339 + padding:200rpx 20rpx 20rpx;
302 340 box-sizing: border-box;
303 341 }
304 342  
... ... @@ -361,21 +399,5 @@ onLoad(() =&gt; {
361 399 }
362 400 }
363 401  
364   -// 空数据提示
365   -.empty-tip {
366   - display: flex;
367   - justify-content: center;
368   - align-items: center;
369   - height: 300rpx;
370   - font-size: 28rpx;
371   - color: #999;
372   -}
373 402  
374   -// 加载中提示
375   -.loading-tip {
376   - display: flex;
377   - justify-content: center;
378   - align-items: center;
379   - height: 300rpx;
380   -}
381 403 </style>
382 404 \ No newline at end of file
... ...
pages-sub/daily/maintain-manage/pending-plan-detail.vue 0 → 100644
  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 + type="primary"
  40 + size="mini"
  41 + @click="gotoFinishPlanDetail(i)"
  42 + :style="{ width: '80px', height: '28px', fontSize: '14px', borderRadius: 4 }"
  43 + >
  44 + 查看记录
  45 + </up-button>
  46 + </view>
  47 +
  48 + <!-- 计划有效期行 -->
  49 + <view class="detail-item">
  50 + <text class="label">计划有效期:</text>
  51 + <!-- <text class="value up-line-1">{{ planInfo && planInfo.validTime ? planInfo.validTime : '-' }}</text>-->
  52 + <text class="value up-line-1">{{ timeFormat(i.beginTime, 'yyyy-mm-dd') }} 至
  53 + {{ timeFormat(i.endTime, 'yyyy-mm-dd') }}
  54 + </text>
  55 + </view>
  56 + </view>
  57 +
  58 + <!-- 底部新增记录按钮 status=3-->
  59 + <view class="fixed-bottom-btn-wrap" v-if="finishState==1">
  60 + <up-button
  61 + type="primary"
  62 + size="default"
  63 + @click="addNewRecord"
  64 + :style="{ width: '100%', height: '88rpx', fontSize: '32rpx', borderRadius: 0 }"
  65 + >
  66 + 新增记录
  67 + </up-button>
  68 + </view>
  69 + </view>
  70 +</template>
  71 +
  72 +<script setup>
  73 +import { timeFormat } from '@/uni_modules/uview-plus';
  74 +import { ref } from 'vue';
  75 +import { onLoad, onShow } from '@dcloudio/uni-app';
  76 +import { notFinish } from "@/api/maintain-manage/maintain-manage";
  77 +
  78 +// 响应式数据定义
  79 +const planInfo = ref([]);
  80 +const batchNo = ref('')
  81 +const planNo = ref('')
  82 +const finishState = ref('')
  83 +const planTypeId = ref('')
  84 +
  85 +
  86 +
  87 +// 页面加载接收参数
  88 +onLoad((options) => {
  89 + planNo.value = options.planNo;
  90 + finishState.value = options.status
  91 + planTypeId.value = options.planTypeId
  92 +});
  93 +// 页面显示时请求数据
  94 +onShow(() => {
  95 + if (!planNo.value) {
  96 + uni.showToast({
  97 + title: '计划ID不存在',
  98 + icon: 'none'
  99 + });
  100 + return;
  101 + }
  102 + getPlanDetail();
  103 +});
  104 +const getPlanDetail = async () => {
  105 + const queryData = {
  106 + planNo: planNo.value,
  107 + planTypeId:planTypeId.value
  108 + }
  109 + console.log(queryData)
  110 + const planInfoRes = await notFinish(queryData)
  111 + planInfo.value = planInfoRes
  112 + console.log(planInfoRes)
  113 +};
  114 +// 跳转到已完成计划明细
  115 +const gotoFinishPlanDetail = (i) => {
  116 + uni.navigateTo({
  117 + // url: `/pages-sub/daily/maintain-manage/finish-plan-detail?planNo=${i.planNo}`
  118 + });
  119 +};
  120 +// 新增记录
  121 +const addNewRecord = () => {
  122 + uni.navigateTo({
  123 + url: `/pages-sub/daily/maintain-manage/add-record/index?planNo=${planInfo.value[0].planNo}&batchNo=${batchNo.value}`,
  124 + });
  125 +};
  126 +</script>
  127 +
  128 +<style scoped lang="scss">
  129 +.pending-plan-detail {
  130 +
  131 +}
  132 +
  133 +.detail-card {
  134 + padding: 20rpx;
  135 + background-color: #fff;
  136 + margin-bottom: 20px;
  137 +}
  138 +
  139 +.detail-item {
  140 + display: flex;
  141 + align-items: center;
  142 + font-size: 28rpx;
  143 + line-height: 1.8;
  144 + padding: 10rpx 0;
  145 + border-bottom: 1px solid #f5f5f5;
  146 +
  147 + &:last-child {
  148 + border-bottom: none;
  149 + }
  150 +}
  151 +
  152 +.flex-between {
  153 + display: flex;
  154 + justify-content: space-between;
  155 + align-items: center;
  156 +
  157 + .left-wrap {
  158 + display: flex;
  159 + align-items: center;
  160 + flex: 1; // 占满剩余空间,按钮靠右
  161 + }
  162 +}
  163 +
  164 +.label {
  165 + color: #999;
  166 + width: 200rpx;
  167 + flex-shrink: 0;
  168 +}
  169 +
  170 +.value {
  171 + color: #333;
  172 + flex: 1;
  173 + word-break: break-all;
  174 +}
  175 +
  176 +</style>
0 177 \ No newline at end of file
... ...
pages-sub/daily/maintain-manage/record-detail-list.vue 0 → 100644
  1 +<template>
  2 + <view class="u-page">
  3 + <!-- 页面级加载组件 -->
  4 + <up-loading-page
  5 + v-if="loading"
  6 + :loading="true"
  7 + title="加载中..."
  8 + color="#3c9cff"
  9 + ></up-loading-page>
  10 +
  11 + <!-- 内容容器 -->
  12 + <view v-else class="content-wrap">
  13 +
  14 +
  15 + <template v-for="(i, index) in orderDetail" :key="index">
  16 + <!-- 工单详情内容 -->
  17 + <up-cell-group :border="false" inset style="margin: 20rpx;">
  18 + <!-- 1. 工单编号 -->
  19 + <up-cell
  20 + :title="i.planName"
  21 +
  22 + class="up-line-1"
  23 + align="middle"
  24 + ></up-cell>
  25 +
  26 + <!-- 2. 工单位置 -->
  27 + <up-cell
  28 + title="计划编码"
  29 + :value="i.planNo || '--'"
  30 + class="up-line-1"
  31 + align="middle"
  32 + ></up-cell>
  33 +
  34 + <!-- 3. 工单名称 -->
  35 + <up-cell
  36 + title="养护周期"
  37 + :value="`${i.rate}${uni.$dict.getDictLabel('cycle_id_type', i.cycleId)}`"
  38 + class="up-line-1"
  39 + align="middle"
  40 + ></up-cell>
  41 +
  42 + <!-- 4. 情况描述 -->
  43 + <up-cell
  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"
  47 + align="middle"
  48 + ></up-cell>
  49 +
  50 + <!-- 5. 问题照片(核心修复:判断条件+空值处理) -->
  51 + <up-cell title="照片" >
  52 + <template #value>
  53 + <view class="cell-content-wrap">
  54 +
  55 + <!-- 修复1:正确判断problemImgsList,补充空数组默认值 -->
  56 + <up-album
  57 + v-if="!!i.imgList?.length"
  58 + :urls="i.imgList || []"
  59 + singleSize="70"
  60 + :preview-full-image="true"
  61 +
  62 + ></up-album>
  63 + <text v-else class="empty-text">暂无问题照片</text>
  64 + </view>
  65 + </template>
  66 + </up-cell>
  67 +
  68 + <!-- 7. 处理结果 -->
  69 + <up-cell
  70 + title="巡查描述"
  71 + :value="i.remark || '--'"
  72 + class="up-line-1"
  73 + align="middle"
  74 + :border="false"
  75 + ></up-cell>
  76 +
  77 + <up-cell
  78 + title="提交时间"
  79 + :value="timeFormat(i.finishTime,'yy-mm-dd hh:MM:ss') || '--'"
  80 + class="up-line-1"
  81 + align="middle"
  82 + :border="false"
  83 + ></up-cell>
  84 +
  85 +
  86 + <up-cell
  87 + title="提交人"
  88 + :value="i.userName || '--'"
  89 + class="up-line-1"
  90 + align="middle"
  91 + :border="false"
  92 + ></up-cell>
  93 + </up-cell-group>
  94 + </template>
  95 +
  96 +
  97 + </view>
  98 + </view>
  99 +</template>
  100 +
  101 +<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';
  106 +// 状态管理
  107 +const loading = ref(true);
  108 +const orderDetail = ref([]);
  109 +
  110 +
  111 +/**
  112 + * 获取工单详情
  113 + */
  114 +const getOrderDetail = async (plan_no: string) => {
  115 + try {
  116 + loading.value = true;
  117 + const res = await inspectioDetailByPlanno({ plan_no });
  118 + 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 + };
  125 + } catch (error) {
  126 + console.error('获取工单详情失败:', error);
  127 + uni.showToast({ title: '加载失败,请重试', icon: 'none' });
  128 + } finally {
  129 + loading.value = false;
  130 + }
  131 +};
  132 +
  133 +// 页面加载
  134 +onLoad((options) => {
  135 + const { planNo } = options;
  136 + if (planNo) {
  137 + getOrderDetail(planNo);
  138 + } else {
  139 + loading.value = false;
  140 + uni.showToast({ title: '缺少工单ID', icon: 'none' });
  141 + }
  142 +});
  143 +</script>
  144 +
  145 +<style scoped lang="scss">
  146 +// 页面基础样式
  147 +.u-page {
  148 + min-height: 100vh;
  149 + background-color: #f5f5f5;
  150 + box-sizing: border-box;
  151 +}
  152 +
  153 +// 内容容器
  154 +.content-wrap {
  155 + background: #fff;
  156 + width: 100%;
  157 + 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; // 图片裁剪填充,避免拉伸
  215 +}
  216 +
  217 +
  218 +</style>
0 219 \ No newline at end of file
... ...
pages-sub/daily/maintain-manage/road-detail-list.vue
... ... @@ -38,210 +38,164 @@
38 38 ref="pagingRef"
39 39 v-model="planList"
40 40 @query="queryList"
41   - :top="140"
  41 + :auto-show-system-loading="true"
42 42 >
43 43 <!-- 空数据插槽 -->
44 44 <template #empty>
45   - <view class="empty-container">
46   - <up-empty mode="list" text="暂无相关计划数据"></up-empty>
47   - </view>
  45 + <empty-view/>
48 46 </template>
  47 + <view class="common-card-list" style=" padding-top: 170rpx;">
  48 + <up-card
  49 + :border="false"
  50 + :foot-border-top="false"
  51 + v-for="(item,index) in planList"
  52 + :key="`${item.planNo}_${index}`"
49 53  
50   - <!-- 列表内容 -->
51   - <view class="card-list">
52   - <view
53   - class="plan-card"
54   - v-for="(item, index) in planList"
55   - :key="index"
56 54 >
57   - <view class="card-header">
58   - <text class="plan-name">{{ item.planName || '未命名计划' }}</text>
59   -<!-- <text class="plan-status" :class="getStatusClass(item.status)">{{ getStatusText(item.status) }}</text>-->
60   - </view>
61   - <view class="card-body">
62   - <view class="info-item">
63   - <text class="label">计划编码:</text>
64   - <text class="value">{{ item.planNo || '-' }}</text>
  55 + <!-- 自定义标题区域 -->
  56 + <template #head>
  57 + <view class="card-header">
  58 + <view class="common-card-title u-line-1">{{ item.planName || '无计划名称' }}</view>
65 59 </view>
66   - <view class="info-item">
67   - <text class="label">养护周期:</text>
68   - <text class="value">{{ item.rate || '-' }} {{ uni.$dict.getDictLabel('cycle_id_type', item.cycleId) }}</text>
  60 + </template>
  61 +
  62 + <template #body>
  63 + <view class="card-body">
  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.planNo || '-' }}</view>
  67 + </view>
  68 + <view class="u-body-item u-flex">
  69 + <view class="u-body-item-title">养护周期:</view>
  70 + <view class="u-line-1 u-body-value">{{ item.rate || '-' }}
  71 + {{ uni.$dict.getDictLabel('cycle_id_type', item.cycleId) }}
  72 + </view>
  73 + </view>
  74 +
  75 + <view class="u-body-item u-flex common-item-center common-justify-between">
  76 + <view class="u-body-item-title">计划完成次数: {{ item.planNum || 0 }}</view>
  77 + <view class="u-line-1">
  78 + <up-button
  79 + type="primary"
  80 + size="mini"
  81 + @click="submitRecord(item)"
  82 + class="submit-record-btn"
  83 + >
  84 + 提交记录
  85 + </up-button>
  86 + </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">{{ item.finishPercent || 0 }}%</view>
  92 + </view>
  93 +
  94 + <view class="u-body-item u-flex">
  95 + <view class="u-body-item-title">计划有效期:</view>
  96 + <view class="u-line-1 u-body-value">{{ timeFormat(item.beginTime, 'yyyy-mm-dd') || '-' }} 至
  97 + {{ timeFormat(item.endTime, 'yyyy-mm-dd') || '-' }}
  98 + </view>
  99 + </view>
69 100 </view>
70   - <view class="info-item">
71   - <text class="label">计划完成次数:</text>
72   - <text class="value">{{ item.planNum || 0 }}</text>
73   - </view>
74   - <view class="info-item">
75   - <text class="label">已完成比例:</text>
76   - <text class="value">{{ item.finishPercent || 0 }}%</text>
77   - </view>
78   - <view class="info-item">
79   - <text class="label">计划有效期:</text>
80   - <text class="value">{{ timeFormat(item.beginTime,'yyyy-mm-dd') || '-'}} 至 {{ timeFormat(item.endTime,'yyyy-mm-dd') || '-'}}</text>
81   - </view>
82   - </view>
83   - <view class="card-footer">
84   - <up-button
85   - type="primary"
86   - size="mini"
87   - @click="handleDetail(item)"
88   - >
89   - 查看详情
90   - </up-button>
91   - </view>
92   - </view>
  101 + </template>
  102 + </up-card>
93 103 </view>
94 104 </z-paging>
95 105 </view>
96 106 </template>
97 107  
98 108 <script setup>
99   -import { ref, computed, onMounted } from 'vue'
  109 +import { ref } from 'vue'
100 110 import { onLoad, onShow } from '@dcloudio/uni-app'
101 111 import { timeFormat } from '@/uni_modules/uview-plus'
102 112 import { getRoadDetails } from "@/api/maintain-manage/maintain-manage";
103   -
104 113 // ========== 基础数据定义 ==========
105   -// 状态Tabs数据
106 114 const statusTabs = ref([
107   - { name: '待完成', id: '1' },
108   - { name: '已失效', id: '3' },
109   - { name: '已完成', id: '2' }
  115 + {name: '待完成', id: '1'},
  116 + {name: '已失效', id: '3'},
  117 + {name: '已完成', id: '2'}
110 118 ])
111   -
112   -// 响应式数据
113   -const activeStatus = ref('1') // 当前选中的状态
114   -const searchValue = ref('') // 搜索框值
115   -const planList = ref([]) // 计划列表(绑定z-paging)
116   -const pagingRef = ref(null) // z-paging实例
117   -const loading = ref(false) // 加载状态
118   -
119   -// URL参数存储
120   -const roadId = ref('') // 从URL获取的roadId
121   -const finishState = ref('') // 从URL获取的finish_state
122   -
  119 +const activeStatus = ref('1')
  120 +const searchValue = ref('')
  121 +const planList = ref([])
  122 +const pagingRef = ref(null)
  123 +const loading = ref(false)
  124 +const roadId = ref('')
  125 +const finishState = ref('')
123 126 // 搜索占位符
124   -const searchPlaceholder = computed(() => {
125   - return '请输入计划名称'
126   -})
127   -
  127 +const searchPlaceholder = ref('请输入计划名称')
128 128 // ========== 方法定义 ==========
129   -// 从URL获取参数
130 129 const getUrlParams = (options) => {
131   - // 1. 修复:URL中是roadId(驼峰),不是road_id
132 130 if (options?.roadId) {
133 131 roadId.value = options.roadId
134   - console.log('从URL获取的roadId:', roadId.value) // 打印验证
  132 + console.log('从URL获取的roadId:', roadId.value)
135 133 }
136   -
137 134 if (options?.finish_state) {
138 135 finishState.value = options.finish_state
139   - // 同步更新Tabs选中状态
140 136 activeStatus.value = options.finish_state
141 137 console.log('从URL获取的finish_state:', finishState.value)
142 138 }
143 139 }
144   -
145   -// 状态切换
146 140 const handleStatusChange = (item) => {
147 141 console.log('切换状态:', item)
148 142 activeStatus.value = item.id
149   - // 更新finishState值
150 143 finishState.value = item.id
151   - // 重置分页并刷新
152 144 pagingRef.value?.reload()
153 145 }
154   -
155   -// 搜索处理
156 146 const handleSearch = () => {
157 147 console.log('搜索关键词:', searchValue.value)
158   - // 重置分页并刷新
159 148 pagingRef.value?.reload()
160 149 }
161   -
162   -// 获取状态文本
163   -const getStatusText = (status) => {
164   - const statusMap = {
165   - '1': '待完成',
166   - '2': '已完成',
167   - '3': '已失效'
  150 +const submitRecord = (item) => {
  151 + console.log('提交记录:', item.finishPercent)
  152 + if (item.finishPercent == 0) {
  153 + uni.navigateTo({
  154 + url: `/pages-sub/daily/maintain-manage/add-record?finishState=${item.finishState}&planNo=${item.planNo}&finishPercent=${item.finishPercent}`
  155 + })
  156 + } else {
  157 + uni.navigateTo({
  158 + url: `/pages-sub/daily/maintain-manage/pending-plan-detail?finishState=${item.finishState}&planNo=${item.planNo}&finishPercent=${item.finishPercent}&planTypeId=${item.planTypeId}`
  159 + })
168 160 }
169   - return statusMap[status] || '未知状态'
170 161 }
171   -
172   -// 获取状态样式类
173   -const getStatusClass = (status) => {
174   - const classMap = {
175   - '1': 'status-pending',
176   - '2': 'status-completed',
177   - '3': 'status-invalid'
178   - }
179   - return classMap[status] || ''
180   -}
181   -
182   -// 查看详情
183   -const handleDetail = (item) => {
184   - uni.navigateTo({
185   - url: `/pages/planDetail/planDetail?planId=${item.id || ''}`
186   - })
187   -}
188   -
189   -// 分页请求数据(z-paging回调)
190 162 const queryList = async (pageNo, pageSize) => {
191 163 try {
192 164 loading.value = true
193   -
194   - // 构造请求参数:优先使用URL参数
195 165 const paramsData = {
196 166 pageNo: pageNo,
197 167 pageSize: pageSize,
198   - road_id: roadId.value, // 现在能拿到正确的roadId了
199   - finish_state: finishState.value || activeStatus.value,
  168 + roadId: roadId.value,
  169 + finishState: finishState.value || activeStatus.value,
200 170 planName: searchValue.value.trim()
201 171 }
202   -
203   - console.log('请求参数:', paramsData) // 验证road_id是否有值
  172 + console.log('请求参数:', paramsData)
204 173 const res = await getRoadDetails(paramsData)
205 174 console.log(res)
206   - // 兼容不同的接口返回格式
207 175 const listData = res?.list || res || []
208   -
209   - // 告知z-paging数据加载完成
210 176 pagingRef.value?.complete(listData)
211 177 loading.value = false
212 178 } catch (error) {
213 179 console.error('请求失败:', error)
214   - uni.showToast({ title: '加载失败,请重试', icon: 'none' })
  180 + uni.showToast({title: '加载失败,请重试', icon: 'none'})
215 181 pagingRef.value?.complete(false)
216 182 loading.value = false
217 183 }
218 184 }
219   -
220   -// ========== 生命周期修复 ==========
221   -// 2. 修复:只有onLoad才会接收页面跳转的options参数
  185 +// ========== 生命周期 ==========
222 186 onLoad((options) => {
223   - // 页面首次加载时获取URL参数
224 187 getUrlParams(options)
225   - // 初始化数据
226   - pagingRef.value?.reload()
227 188 })
228   -
229 189 onShow(() => {
230   - // 可选:页面再次显示时刷新(比如从详情页返回)
231   - // if (roadId.value) { // 有roadId才刷新
232   - // pagingRef.value?.reload()
233   - // }
  190 + if (roadId.value) {
  191 + pagingRef.value?.reload()
  192 + }
234 193 })
235 194  
236   -onMounted(() => {
237   - // 可选:初始化其他逻辑
238   -})
239 195 </script>
240 196  
241 197 <style scoped lang="scss">
242 198 .page-container {
243   - min-height: 100vh;
244   - background-color: #f8f8f8;
245 199 }
246 200  
247 201 // 顶部吸顶区域样式
... ... @@ -250,106 +204,11 @@ onMounted(() =&gt; {
250 204 padding-bottom: 10rpx;
251 205 border-bottom: 1px solid #eee;
252 206  
253   - // 状态Tabs样式
254   - .status-tabs {
255   - margin: 10rpx 0 0 0;
256   - }
257   -
258   - // 搜索框样式
259 207 .search-input {
260 208 margin: 20rpx 20rpx 10rpx !important;
261 209 }
262 210 }
263 211  
264   -// 卡片列表样式
265   -.card-list {
266   - padding: 0 20rpx;
267   - display: flex;
268   - flex-direction: column;
269   - gap: 20rpx;
270   -}
271   -
272   -// 计划卡片样式
273   -.plan-card {
274   - background-color: #ffffff;
275   - border-radius: 12rpx;
276   - padding: 24rpx;
277   - box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
278 212  
279   - // 卡片头部
280   - .card-header {
281   - display: flex;
282   - justify-content: space-between;
283   - align-items: center;
284   - margin-bottom: 20rpx;
285   - padding-bottom: 12rpx;
286   - border-bottom: 1px solid #f5f5f5;
287 213  
288   - .plan-name {
289   - font-size: 30rpx;
290   - font-weight: 600;
291   - color: #333;
292   - }
293   -
294   - .plan-status {
295   - font-size: 24rpx;
296   - padding: 4rpx 12rpx;
297   - border-radius: 20rpx;
298   -
299   - // 状态样式
300   - &.status-pending {
301   - background-color: #fff7e6;
302   - color: #ff9f1c;
303   - }
304   -
305   - &.status-completed {
306   - background-color: #e8f8f5;
307   - color: #00b42a;
308   - }
309   -
310   - &.status-invalid {
311   - background-color: #f5f5f5;
312   - color: #999;
313   - }
314   - }
315   - }
316   -
317   - // 卡片内容
318   - .card-body {
319   - display: flex;
320   - flex-direction: column;
321   - gap: 16rpx;
322   - margin-bottom: 20rpx;
323   -
324   - .info-item {
325   - display: flex;
326   - align-items: center;
327   - font-size: 28rpx;
328   -
329   - .label {
330   - color: #999;
331   - flex-shrink: 0;
332   - }
333   -
334   - .value {
335   - color: #333;
336   - flex: 1;
337   - }
338   - }
339   - }
340   -
341   - // 卡片底部
342   - .card-footer {
343   - display: flex;
344   - justify-content: flex-end;
345   - }
346   -}
347   -
348   -// 空数据样式
349   -.empty-container {
350   - display: flex;
351   - justify-content: center;
352   - align-items: center;
353   - height: 400rpx;
354   -}
355 214 </style>
356 215 \ No newline at end of file
... ...
pages.json
... ... @@ -92,9 +92,28 @@
92 92 {
93 93 "path": "maintain-manage/road-detail-list",
94 94 "style": { "navigationBarTitleText": "道路明细列表" }
  95 + },
  96 +
  97 + {
  98 + "path": "maintain-manage/add-record",
  99 + "style": { "navigationBarTitleText": "新增养护记录" }
  100 + },
  101 + {
  102 + "path": "maintain-manage/pending-plan-detail",
  103 + "style": { "navigationBarTitleText": "计划明细" }
  104 + },
  105 +
  106 + {
  107 + "path": "maintain-manage/record-detail-list",
  108 + "style": { "navigationBarTitleText": "养护记录明细" }
  109 + },
  110 + {
  111 + "path": "maintain-manage/finish-plan-detail",
  112 + "style": { "navigationBarTitleText": "记录详情" }
95 113 }
96 114  
97 115  
  116 +
98 117 ]
99 118 },
100 119 {
... ...