Commit de549a920959426bdc260891219ead7efa4dd37f
1 parent
b055b398
养护。动态表单
Showing
7 changed files
with
302 additions
and
151 deletions
api/common.js
| ... | ... | @@ -47,6 +47,35 @@ export const getAllCompanyList = (params) => { |
| 47 | 47 | }; |
| 48 | 48 | |
| 49 | 49 | |
| 50 | +/** | |
| 51 | + * 拉取字段配置 | |
| 52 | + * @param {Object} params {`businessType`、`bizType`、`workTypeId`} | |
| 53 | + * @returns {Promise} | |
| 54 | + */ | |
| 55 | +export const getByType = (params) => { | |
| 56 | + return get('/app-api/app/garden/work-field-config/get-by-type', params); | |
| 57 | +}; | |
| 58 | + | |
| 59 | +/** | |
| 60 | + * 拉取枚举选项 用于 `fieldType=3`(枚举)且 `options` 为空(即非静态来源)时获取可选项。 | |
| 61 | + * @param {Object} params {} | |
| 62 | + * @returns {Promise} | |
| 63 | + */ | |
| 64 | +export const getOptionsByCode = (params) => { | |
| 65 | + return get('/app-api/app/garden/work-field-config/options', params); | |
| 66 | +}; | |
| 67 | + | |
| 68 | +/** | |
| 69 | + * 拉取拉取物料列表 用于`fieldType=6`(物料)字段,列出可领物料及库存。 | |
| 70 | + * @param {Object} params {} | |
| 71 | + * @returns {Promise} | |
| 72 | + */ | |
| 73 | +export const getMaterialsByCode = (params) => { | |
| 74 | + return get('/app-api/app/garden/work-field-config/materials', params); | |
| 75 | +}; | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 50 | 79 | |
| 51 | 80 | |
| 52 | 81 | ... | ... |
common/config/env.js
| ... | ... | @@ -2,10 +2,10 @@ |
| 2 | 2 | const env = { |
| 3 | 3 | // 开发环境 |
| 4 | 4 | development: { |
| 5 | - // baseUrl: 'https://test.jichengshanshui.com.cn:28302', | |
| 5 | + baseUrl: 'https://test.jichengshanshui.com.cn:28302', | |
| 6 | 6 | // https://test.jichengshanshui.com.cn:28302 |
| 7 | 7 | |
| 8 | - baseUrl: 'http://192.168.1.111:48081', | |
| 8 | + // baseUrl: 'http://192.168.1.111:48081', | |
| 9 | 9 | |
| 10 | 10 | uploadUrl: 'https://test.jichengshanshui.com.cn:28302', |
| 11 | 11 | // baseApi:'admin-api', |
| ... | ... | @@ -23,7 +23,7 @@ const env = { |
| 23 | 23 | // 获取当前环境 |
| 24 | 24 | const getEnv = () => { |
| 25 | 25 | |
| 26 | - const currentEnv = 'production'; | |
| 26 | + const currentEnv = 'development'; | |
| 27 | 27 | |
| 28 | 28 | return currentEnv; |
| 29 | 29 | }; | ... | ... |
pages-sub/daily/maintain-manage/add-record.vue
| 1 | 1 | <template> |
| 2 | 2 | <view class="page-container"> |
| 3 | 3 | <view class="inspect-form-content commonPageLRpadding"> |
| 4 | - <up-form | |
| 5 | - label-position="left" | |
| 6 | - :model="inspectForm" | |
| 7 | - ref="inspectFormRef" | |
| 8 | - labelWidth="140rpx" | |
| 9 | - > | |
| 4 | + <up-form label-position="left" :model="inspectForm" ref="inspectFormRef" label-width="140rpx"> | |
| 5 | + <!-- ========== 动态表单区域 ========== --> | |
| 6 | + <template v-for="item in dynamicFields" :key="item.fieldCode"> | |
| 7 | + <up-form-item :label="item.fieldName" :prop="item.fieldCode" :required="item.required === 1" class="form-item" | |
| 8 | + @click="(item.fieldType === 3 || item.fieldType === 6) && item.multiple === 0 && openActionSheet(item)"> | |
| 9 | + <!-- type 1 数值:u-number-box,最多2位小数,min=0,max取item.length --> | |
| 10 | + <view v-if="item.fieldType === 1" class="number-box-wrap"> | |
| 11 | + <u-number-box v-model="inspectForm[item.fieldCode]" min="1" :step="1" | |
| 12 | + :max="item.length ? 10 ** Number(item.length) - 1 : null" | |
| 13 | + :placeholder="`请输入${item.fieldName}${item.unit} `" @change="valChange(item)" class="large-number-box"> | |
| 14 | + </u-number-box> | |
| 15 | + <text class="unit-text" v-if="item.unit">{{ item.unit }}</text> | |
| 16 | + </view> | |
| 17 | + <!-- type 2 文本 --> | |
| 18 | + <up-input v-else-if="item.fieldType === 2" v-model="inspectForm[item.fieldCode]" | |
| 19 | + :maxlength="item.length || 50" :placeholder="`请输入${item.fieldName}`"></up-input> | |
| 20 | + <!-- type3 枚举:多选 multiple=1 使用复选框组 --> | |
| 21 | + <u-checkbox-group v-else-if="item.fieldType === 3 && item.multiple === 1" | |
| 22 | + v-model="inspectForm[item.fieldCode]"> | |
| 23 | + <u-checkbox v-for="opt in item.selectOptions" :key="opt.value" :label="opt.label" :name="opt.label"> | |
| 24 | + | |
| 25 | + </u-checkbox> | |
| 26 | + </u-checkbox-group> | |
| 27 | + <!-- type3 枚举:单选 用up-action-sheet 底部选择 --> | |
| 28 | + <up-input v-else-if="item.fieldType === 3" v-model="labelMap[item.fieldCode]" readonly | |
| 29 | + disabled-color="#ffffff" :placeholder="`请选择${item.fieldName}`" border="none"> | |
| 30 | + <template #right> | |
| 31 | + <up-icon name="arrow-right" size="16"></up-icon> | |
| 32 | + </template> | |
| 33 | + </up-input> | |
| 34 | + <!-- type4 日期时间 --> | |
| 35 | + <view v-else-if="item.fieldType === 4" @click.stop="openDatePicker(item)" class="date-input-wrap"> | |
| 36 | + <up-input v-model="inspectForm[item.fieldCode]" disabled placeholder="点击选择时间"></up-input> | |
| 37 | + </view> | |
| 38 | + <!-- type5 布尔单选 是/否 【重点修复】增加空label=""占位项 --> | |
| 39 | + <up-radio-group v-else-if="item.fieldType === 5" v-model="inspectForm[item.fieldCode]"> | |
| 40 | + <up-radio label="是" name="是"></up-radio> | |
| 41 | + <up-radio label="否" name="否"></up-radio> | |
| 42 | + </up-radio-group> | |
| 43 | + <!-- type6 物料选择:up-action-sheet 底部选择 --> | |
| 44 | + <up-input v-else-if="item.fieldType === 6" v-model="labelMap[item.fieldCode]" readonly | |
| 45 | + disabled-color="#ffffff" :placeholder="`请选择${item.fieldName}`" border="none"> | |
| 46 | + <template #right> | |
| 47 | + <up-icon name="arrow-right" size="16"></up-icon> | |
| 48 | + </template> | |
| 49 | + </up-input> | |
| 50 | + </up-form-item> | |
| 51 | + </template> | |
| 52 | + <!-- ========== 动态表单结束 ========== --> | |
| 10 | 53 | <!-- 1. 养护描述(文本域) --> |
| 11 | - <up-form-item | |
| 12 | - prop="remark" | |
| 13 | - class="form-item" | |
| 14 | - > | |
| 15 | - <up-textarea | |
| 16 | - v-model.trim="inspectForm.remark" | |
| 17 | - placeholder="请输入养护描述" | |
| 18 | - maxlength="200" | |
| 19 | - count | |
| 20 | - ></up-textarea> | |
| 54 | + <up-form-item prop="remark" class="form-item"> | |
| 55 | + <up-textarea v-model.trim="inspectForm.remark" placeholder="请输入养护描述" maxlength="200" count></up-textarea> | |
| 21 | 56 | </up-form-item> |
| 22 | - | |
| 23 | 57 | <!-- 2. 上传图片 --> |
| 24 | - <up-form-item | |
| 25 | - label="上传图片" | |
| 26 | - prop="images" | |
| 27 | - required | |
| 28 | - | |
| 29 | - class="form-item" | |
| 30 | - > | |
| 31 | - <up-upload | |
| 32 | - :file-list="imagesList" | |
| 33 | - @after-read="(event) => uploadImgs(event)" | |
| 34 | - @delete="(event) => deleteImg(event)" | |
| 35 | - @on-exceed="handleExceed" | |
| 36 | - multiple | |
| 37 | - :max-count="3" | |
| 38 | - upload-text="选择图片" | |
| 39 | - del-color="#ff4d4f" | |
| 40 | - class="upload-wrap" | |
| 41 | - ></up-upload> | |
| 58 | + <up-form-item label="上传图片" prop="images" required class="form-item"> | |
| 59 | + <up-upload :file-list="imagesList" @after-read="(event) => uploadImgs(event)" | |
| 60 | + @delete="(event) => deleteImg(event)" @on-exceed="handleExceed" multiple :max-count="3" upload-text="选择图片" | |
| 61 | + del-color="#ff4d4f" class="upload-wrap"></up-upload> | |
| 42 | 62 | </up-form-item> |
| 43 | - | |
| 44 | -<!-- <!– 3. 完成进度(滑块) –>--> | |
| 45 | -<!-- <up-form-item--> | |
| 46 | -<!-- label="完成进度"--> | |
| 47 | -<!-- prop="progress"--> | |
| 48 | - | |
| 49 | -<!-- class="form-item"--> | |
| 50 | -<!-- >--> | |
| 51 | -<!-- <view class="progress-wrap">--> | |
| 52 | -<!-- <up-slider--> | |
| 53 | -<!-- v-model="inspectForm.progress"--> | |
| 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 | -<!-- ></up-slider>--> | |
| 63 | -<!-- </view>--> | |
| 64 | -<!-- </up-form-item>--> | |
| 65 | 63 | </up-form> |
| 66 | 64 | </view> |
| 67 | - | |
| 68 | 65 | <!-- 底部提交按钮 --> |
| 69 | 66 | <view class="fixed-bottom-btn-wrap"> |
| 70 | - <up-button | |
| 71 | - type="primary" | |
| 72 | - text="提交" | |
| 73 | - @click="submitInspect" | |
| 74 | - :style="{ width: '100%', height: '88rpx', fontSize: '32rpx', borderRadius: 0 }" | |
| 75 | - ></up-button> | |
| 67 | + <up-button type="primary" text="提交" @click="submitInspect" | |
| 68 | + style="width: 100%; height: 88rpx; font-size:32rpx; border-radius: 0;"></up-button> | |
| 76 | 69 | </view> |
| 70 | + <!-- uview-plus 日期时间选择器(全局复用) --> | |
| 71 | + <up-datetime-picker :show="datePickerShow" v-model="datePickerValue" mode="datetime" close-on-click-overlay | |
| 72 | + @confirm="onDateConfirm" @cancel="onDateClose" @close="onDateClose"></up-datetime-picker> | |
| 73 | + <!-- ActionSheet 底部选择弹窗 --> | |
| 74 | + <up-action-sheet :show="actionSheet.show" :actions="actionSheet.options" @select="onActionSheetSelect" | |
| 75 | + @close="actionSheet.show = false" cancel-text="取消"></up-action-sheet> | |
| 77 | 76 | </view> |
| 78 | 77 | </template> |
| 79 | 78 | |
| 80 | -<script setup lang="ts"> | |
| 81 | -import { ref } from 'vue' | |
| 82 | -import type { UniFormRef } from '@/uni_modules/uview-plus/types' | |
| 83 | -const inspectFormRef = ref<UniFormRef>(null) | |
| 84 | -</script> | |
| 85 | - | |
| 86 | 79 | <script lang="ts"> |
| 87 | 80 | import { uploadImages } from '@/common/utils/upload' |
| 88 | 81 | import { maintainCreate } from "@/api/maintain-manage/maintain-manage" |
| 89 | - | |
| 82 | +import { getByType, getOptionsByCode, getMaterialsByCode } from "@/api/common" | |
| 90 | 83 | export default { |
| 91 | 84 | data() { |
| 92 | 85 | return { |
| ... | ... | @@ -94,8 +87,9 @@ export default { |
| 94 | 87 | initProgress: 0, |
| 95 | 88 | inspectForm: { |
| 96 | 89 | remark: '', |
| 97 | - // progress: 0 | |
| 98 | 90 | }, |
| 91 | + // ========== 新增:用来存放展示文本label的映射对象 ========== | |
| 92 | + labelMap: {}, | |
| 99 | 93 | paramsOptins: {}, |
| 100 | 94 | inspectFormRules: { |
| 101 | 95 | images: [ |
| ... | ... | @@ -116,78 +110,200 @@ export default { |
| 116 | 110 | } |
| 117 | 111 | } |
| 118 | 112 | ], |
| 119 | - | |
| 113 | + }, | |
| 114 | + // 动态字段列表 | |
| 115 | + dynamicFields: [] as any[], | |
| 116 | + // 日期时间选择器 | |
| 117 | + datePickerShow: false, | |
| 118 | + datePickerValue: Number(new Date()), | |
| 119 | + currentDateFieldCode: '', | |
| 120 | + // actionSheet配置 | |
| 121 | + actionSheet: { | |
| 122 | + show: false, | |
| 123 | + fieldCode: '', // 当前操作的字段 | |
| 124 | + options: [] as any[], | |
| 125 | + fieldItem: null // 保存当前点击的field对象,用于后面查找label | |
| 120 | 126 | } |
| 121 | 127 | } |
| 122 | 128 | }, |
| 123 | 129 | onLoad(option) { |
| 124 | 130 | console.log('页面参数:', option) |
| 125 | 131 | this.paramsOptins = option |
| 126 | - | |
| 127 | - | |
| 132 | + const { businessType, planTypeId } = option | |
| 133 | + this.loadDynamicFields(businessType, planTypeId) | |
| 128 | 134 | }, |
| 129 | 135 | onReady() { |
| 130 | 136 | this.$refs.inspectFormRef.setRules(this.inspectFormRules) |
| 131 | 137 | console.log('巡查表单规则初始化完成') |
| 132 | 138 | }, |
| 133 | 139 | methods: { |
| 140 | + // number-box数值变更回调 | |
| 141 | + valChange(item) { | |
| 142 | + // 数值修改后触发表单校验 | |
| 143 | + this.$refs.inspectFormRef.validateField(item.fieldCode) | |
| 144 | + }, | |
| 145 | + // ========== 日期时间相关方法 ========== | |
| 146 | + openDatePicker(field) { | |
| 147 | + console.log('打开日期选择器', field) | |
| 148 | + this.currentDateFieldCode = field.fieldCode | |
| 149 | + const val = this.inspectForm[field.fieldCode] | |
| 150 | + this.datePickerValue = val ? new Date(val).getTime() : Number(new Date()) | |
| 151 | + this.datePickerShow = true | |
| 152 | + uni.hideKeyboard() | |
| 153 | + }, | |
| 154 | + onDateConfirm(e) { | |
| 155 | + const ts = e.value | |
| 156 | + const d = new Date(ts) | |
| 157 | + const y = d.getFullYear() | |
| 158 | + const m = String(d.getMonth() + 1).padStart(2, '0') | |
| 159 | + const day = String(d.getDate()).padStart(2, '0') | |
| 160 | + const h = String(d.getHours()).padStart(2, '0') | |
| 161 | + const mi = String(d.getMinutes()).padStart(2, '0') | |
| 162 | + const s = String(d.getSeconds()).padStart(2, '0') | |
| 163 | + this.inspectForm[this.currentDateFieldCode] = `${y}-${m}-${day} ${h}:${mi}:${s}` | |
| 164 | + this.datePickerShow = false | |
| 165 | + this.$refs.inspectFormRef.validateField(this.currentDateFieldCode) | |
| 166 | + }, | |
| 167 | + onDateClose() { | |
| 168 | + this.datePickerShow = false | |
| 169 | + }, | |
| 134 | 170 | /** |
| 135 | - * 进度滑块变化处理 - 核心优化:实时触发校验 + 状态更新 | |
| 171 | + * 打开底部选择弹窗 actionSheet | |
| 136 | 172 | */ |
| 173 | + openActionSheet(item: any) { | |
| 174 | + console.log('12312'); | |
| 175 | + this.actionSheet.fieldCode = item.fieldCode | |
| 176 | + this.actionSheet.fieldItem = item | |
| 177 | + // 把selectOptions / materialOptions 转为 actionSheet 需要格式 {name, value} | |
| 178 | + let sourceOptions = item.fieldType === 3 ? item.selectOptions : item.materialOptions | |
| 179 | + this.actionSheet.options = (sourceOptions || []).map(opt => { | |
| 180 | + return { | |
| 181 | + name: opt.label, | |
| 182 | + value: opt.value | |
| 183 | + } | |
| 184 | + }) | |
| 185 | + this.actionSheet.show = true | |
| 186 | + }, | |
| 187 | + /** | |
| 188 | + * actionSheet选中回调 | |
| 189 | + */ | |
| 190 | + onActionSheetSelect(selectedItem: any) { | |
| 191 | + const fieldItem = this.actionSheet.fieldItem | |
| 192 | + const fieldCode = this.actionSheet.fieldCode | |
| 193 | + // 1. 表单保存value,提交后端 | |
| 194 | + this.inspectForm[fieldCode] = selectedItem.value | |
| 195 | + // 2. labelMap保存label,给input展示 | |
| 196 | + this.labelMap[fieldCode] = selectedItem.name | |
| 197 | + this.actionSheet.show = false | |
| 198 | + // 选中后触发表单校验 | |
| 199 | + this.$refs.inspectFormRef.validateField(fieldCode) | |
| 200 | + }, | |
| 201 | + /** | |
| 202 | + * 加载动态字段 | |
| 203 | + */ | |
| 204 | + async loadDynamicFields(businessType: string, workTypeId: string) { | |
| 205 | + if (!businessType || !workTypeId) { | |
| 206 | + uni.showToast({ title: '缺少业务参数', icon: 'none' }) | |
| 207 | + return | |
| 208 | + } | |
| 209 | + const bizType = 3 | |
| 210 | + try { | |
| 211 | + const res = await getByType({ | |
| 212 | + businessType, | |
| 213 | + workTypeId, | |
| 214 | + bizType | |
| 215 | + }) | |
| 216 | + let fields = res.fields || [] | |
| 217 | + fields.sort((a, b) => a.sort - b.sort) | |
| 218 | + if (fields.length === 0) { | |
| 219 | + uni.showToast({ title: '暂无需填报项', icon: 'none' }) | |
| 220 | + this.dynamicFields = [] | |
| 221 | + return | |
| 222 | + } | |
| 223 | + for (const field of fields) { | |
| 224 | + // type3多选checkbox,初始值为空数组,其余字段空字符串 | |
| 225 | + if (field.fieldType === 3 && field.multiple === 1) { | |
| 226 | + this.$set(this.inspectForm, field.fieldCode, []) | |
| 227 | + } else { | |
| 228 | + this.$set(this.inspectForm, field.fieldCode, '') | |
| 229 | + } | |
| 230 | + // 初始化展示label为空 | |
| 231 | + this.$set(this.labelMap, field.fieldCode, '') | |
| 137 | 232 | |
| 138 | - | |
| 233 | + if (field.required === 1) { | |
| 234 | + const msg = field.fieldType === 5 ? `请选择${field.fieldName}` : `请填写${field.fieldName}` | |
| 235 | + this.inspectFormRules[field.fieldCode] = [ | |
| 236 | + { required: true, message: msg, trigger: 'change' } | |
| 237 | + ] | |
| 238 | + } | |
| 239 | + // type3 枚举:优先使用field.options,有则不请求getOptionsByCode | |
| 240 | + if (field.fieldType === 3) { | |
| 241 | + if (field.options && Array.isArray(field.options) && field.options.length > 0) { | |
| 242 | + field.selectOptions = field.options | |
| 243 | + } else { | |
| 244 | + console.log('12312') | |
| 245 | + const dictRes = await getOptionsByCode({ | |
| 246 | + businessType, | |
| 247 | + bizType, | |
| 248 | + workTypeId, | |
| 249 | + fieldCode: field.fieldCode | |
| 250 | + }) | |
| 251 | + field.selectOptions = dictRes.map(item => ({ label: item.label, value: item.value })) | |
| 252 | + } | |
| 253 | + } | |
| 254 | + // type6 物料选项 | |
| 255 | + if (field.fieldType === 6) { | |
| 256 | + const matRes = await getMaterialsByCode({ | |
| 257 | + businessType, | |
| 258 | + bizType, | |
| 259 | + workTypeId, | |
| 260 | + fieldCode: field.fieldCode | |
| 261 | + }) | |
| 262 | + field.materialOptions = matRes.map(item => ({ label: item.materialName, value: item.materialId })) | |
| 263 | + } | |
| 264 | + } | |
| 265 | + this.dynamicFields = fields | |
| 266 | + this.$nextTick(() => { | |
| 267 | + this.$refs.inspectFormRef.setRules(this.inspectFormRules) | |
| 268 | + }) | |
| 269 | + } catch (err) { | |
| 270 | + console.error('获取动态表单字段失败:', err) | |
| 271 | + uni.showToast({ title: '加载表单配置失败', icon: 'none' }) | |
| 272 | + } | |
| 273 | + }, | |
| 139 | 274 | /** |
| 140 | 275 | * 删除图片 |
| 141 | 276 | */ |
| 142 | 277 | deleteImg(event) { |
| 143 | - console.log('删除图片事件:', event) | |
| 144 | 278 | this.imagesList.splice(event.index, 1) |
| 145 | 279 | this.$refs.inspectFormRef.validateField('images') |
| 146 | 280 | uni.showToast({ title: '图片删除成功', icon: 'success' }) |
| 147 | 281 | }, |
| 148 | - | |
| 149 | 282 | /** |
| 150 | 283 | * 上传图片 |
| 151 | 284 | */ |
| 152 | 285 | async uploadImgs(event) { |
| 153 | - console.log('上传图片事件:', event) | |
| 154 | 286 | const fileList = Array.isArray(event.file) ? event.file : [event.file] |
| 155 | 287 | const targetImgList = this.imagesList |
| 156 | 288 | const filePaths = fileList.map(item => item.url) |
| 157 | - const tempItems = fileList.map(item => ({ | |
| 158 | - ...item, | |
| 159 | - status: 'uploading', | |
| 160 | - message: '上传中' | |
| 161 | - })) | |
| 289 | + const tempItems = fileList.map(item => ({ ...item, status: 'uploading', message: '上传中' })) | |
| 162 | 290 | const startIndex = targetImgList.length |
| 163 | 291 | targetImgList.push(...tempItems) |
| 164 | - | |
| 165 | 292 | try { |
| 166 | - const uploadResultUrls = await uploadImages({ | |
| 167 | - filePaths: filePaths, | |
| 168 | - ignoreError: true | |
| 169 | - }) | |
| 170 | - console.log('上传成功的URL列表:', uploadResultUrls) | |
| 171 | - | |
| 293 | + const uploadResultUrls = await uploadImages({ filePaths, ignoreError: true }) | |
| 172 | 294 | uploadResultUrls.forEach((url, index) => { |
| 173 | 295 | if (targetImgList[startIndex + index]) { |
| 174 | 296 | targetImgList.splice(startIndex + index, 1, { |
| 175 | - ...fileList[index], | |
| 176 | - status: 'success', | |
| 177 | - message: '', | |
| 178 | - url: url | |
| 297 | + ...fileList[index], status: 'success', message: '', url | |
| 179 | 298 | }) |
| 180 | 299 | } |
| 181 | 300 | }) |
| 182 | - | |
| 183 | 301 | if (uploadResultUrls.length < fileList.length) { |
| 184 | 302 | const failCount = fileList.length - uploadResultUrls.length |
| 185 | 303 | for (let i = uploadResultUrls.length; i < fileList.length; i++) { |
| 186 | 304 | if (targetImgList[startIndex + i]) { |
| 187 | 305 | targetImgList.splice(startIndex + i, 1, { |
| 188 | - ...fileList[i], | |
| 189 | - status: 'failed', | |
| 190 | - message: '上传失败' | |
| 306 | + ...fileList[i], status: 'failed', message: '上传失败' | |
| 191 | 307 | }) |
| 192 | 308 | } |
| 193 | 309 | } |
| ... | ... | @@ -195,16 +311,13 @@ export default { |
| 195 | 311 | } else { |
| 196 | 312 | uni.showToast({ title: `成功上传${fileList.length}张图片`, icon: 'success' }) |
| 197 | 313 | } |
| 198 | - | |
| 199 | 314 | this.$refs.inspectFormRef.validateField('images') |
| 200 | 315 | } catch (err) { |
| 201 | 316 | console.error('图片上传失败:', err) |
| 202 | 317 | for (let i = 0; i < fileList.length; i++) { |
| 203 | 318 | if (targetImgList[startIndex + i]) { |
| 204 | 319 | targetImgList.splice(startIndex + i, 1, { |
| 205 | - ...fileList[i], | |
| 206 | - status: 'failed', | |
| 207 | - message: '上传失败' | |
| 320 | + ...fileList[i], status: 'failed', message: '上传失败' | |
| 208 | 321 | }) |
| 209 | 322 | } |
| 210 | 323 | } |
| ... | ... | @@ -212,63 +325,38 @@ export default { |
| 212 | 325 | this.$refs.inspectFormRef.validateField('images') |
| 213 | 326 | } |
| 214 | 327 | }, |
| 215 | - | |
| 216 | - /** | |
| 217 | - * 处理图片超出数量限制 | |
| 218 | - */ | |
| 219 | 328 | handleExceed() { |
| 220 | 329 | uni.showToast({ title: '最多只能上传3张图片', icon: 'none' }) |
| 221 | 330 | }, |
| 222 | - | |
| 223 | - /** | |
| 224 | - * 提取图片URL数组 | |
| 225 | - */ | |
| 226 | 331 | getImgUrlList(imgList) { |
| 227 | 332 | return imgList.filter(item => item.status === 'success').map(item => item.url) |
| 228 | 333 | }, |
| 229 | - | |
| 230 | 334 | /** |
| 231 | 335 | * 提交巡查表单 |
| 232 | 336 | */ |
| 233 | 337 | async submitInspect() { |
| 234 | - // console.log('当前完成进度:', this.inspectForm.progress) | |
| 235 | 338 | try { |
| 236 | 339 | await this.$refs.inspectFormRef.validate() |
| 237 | - console.log('图片列表:', this.imagesList) | |
| 238 | - | |
| 239 | 340 | const submitData = { |
| 240 | - "planNo": this.paramsOptins.planNo, | |
| 241 | - "imgHost": "1", | |
| 242 | - "beginImg": this.getImgUrlList(this.imagesList), | |
| 243 | - "commonUserList": [], | |
| 244 | - "remark": this.inspectForm.remark.trim() | |
| 341 | + planNo: this.paramsOptins.planNo, | |
| 342 | + imgHost: "1", | |
| 343 | + beginImg: this.getImgUrlList(this.imagesList), | |
| 344 | + commonUserList: [], | |
| 345 | + remark: this.inspectForm.remark.trim(), | |
| 346 | + ...this.inspectForm | |
| 245 | 347 | } |
| 246 | - | |
| 247 | 348 | uni.showLoading({ title: '提交中...' }) |
| 248 | 349 | await maintainCreate(submitData) |
| 249 | 350 | uni.hideLoading() |
| 250 | - | |
| 251 | - uni.showToast({ | |
| 252 | - title: '提交成功', | |
| 253 | - icon: 'success', | |
| 254 | - duration: 1000 | |
| 255 | - }) | |
| 256 | - | |
| 351 | + uni.showToast({ title: '提交成功', icon: 'success', duration: 1000 }) | |
| 257 | 352 | setTimeout(() => { |
| 258 | - uni.reLaunch({ | |
| 259 | - url: '/pages-sub/daily/maintain-manage/index' | |
| 260 | - }) | |
| 353 | + uni.reLaunch({ url: '/pages-sub/daily/maintain-manage/index' }) | |
| 261 | 354 | }, 1000) |
| 262 | - | |
| 263 | 355 | } catch (error) { |
| 264 | 356 | uni.hideLoading() |
| 265 | 357 | if (!Array.isArray(error)) { |
| 266 | 358 | console.error('巡查表单提交失败:', error) |
| 267 | - uni.showToast({ | |
| 268 | - title: '提交失败,请重试', | |
| 269 | - icon: 'none', | |
| 270 | - duration: 2000 | |
| 271 | - }) | |
| 359 | + uni.showToast({ title: '提交失败,请重试', icon: 'none', duration: 2000 }) | |
| 272 | 360 | } |
| 273 | 361 | } |
| 274 | 362 | } |
| ... | ... | @@ -277,14 +365,45 @@ export default { |
| 277 | 365 | </script> |
| 278 | 366 | |
| 279 | 367 | <style lang="scss" scoped> |
| 368 | +.page-container { | |
| 369 | + padding-bottom: 120rpx; | |
| 370 | +} | |
| 280 | 371 | .inspect-form-content { |
| 281 | 372 | background: #fff; |
| 282 | 373 | padding: 20rpx; |
| 283 | 374 | margin-bottom: 20rpx; |
| 284 | 375 | } |
| 285 | - | |
| 286 | -.progress-wrap { | |
| 287 | - width: 83%; | |
| 376 | +.date-input-wrap { | |
| 377 | + width: 100%; | |
| 378 | +} | |
| 379 | +.fixed-bottom-btn-wrap { | |
| 380 | + position: fixed; | |
| 381 | + bottom: 0; | |
| 382 | + left: 0; | |
| 383 | + width: 100%; | |
| 384 | + padding: 20rpx; | |
| 385 | + box-sizing: border-box; | |
| 386 | + background-color: #fff; | |
| 387 | +} | |
| 388 | +// 放大u-number-box输入框 | |
| 389 | +.large-number-box { | |
| 390 | + :deep(.u-number-box__input) { | |
| 391 | + width: 264rpx !important; | |
| 392 | + height: 72rpx; | |
| 393 | + font-size: 32rpx; | |
| 394 | + } | |
| 395 | + :deep(.u-number-box__btn) { | |
| 396 | + width: 64rpx; | |
| 397 | + height: 72rpx; | |
| 398 | + } | |
| 399 | +} | |
| 400 | +.number-box-wrap { | |
| 401 | + display: flex; | |
| 402 | + align-items: center; | |
| 403 | + gap: 16rpx; | |
| 404 | + .unit-text { | |
| 405 | + font-size: 28rpx; | |
| 406 | + color: #333; | |
| 407 | + } | |
| 288 | 408 | } |
| 289 | 409 | </style> |
| 290 | - | ... | ... |
pages-sub/daily/maintain-manage/index.vue
| ... | ... | @@ -309,7 +309,7 @@ const fetchData = async (pageNo, pageSize) => { |
| 309 | 309 | // 跳转到计划明细页面 |
| 310 | 310 | const goToDetail = (item) => { |
| 311 | 311 | uni.navigateTo({ |
| 312 | - url: `/pages-sub/daily/maintain-manage/road-detail-list?roadId=${item.roadId}&finish_state=${item.finishState || ''}` | |
| 312 | + url: `/pages-sub/daily/maintain-manage/road-detail-list?roadId=${item.roadId}&finish_state=${item.finishState || ''} &businessType=${item.busiLine}` | |
| 313 | 313 | }) |
| 314 | 314 | } |
| 315 | 315 | |
| ... | ... | @@ -318,11 +318,11 @@ const submitRecord = (item) => { |
| 318 | 318 | console.log('提交记录:', item) |
| 319 | 319 | if (item.planFinishNum == 0) { // 去新增 |
| 320 | 320 | uni.navigateTo({ |
| 321 | - url: `/pages-sub/daily/maintain-manage/add-record?finishState=${item.finishState}&planNo=${item.planNo}` | |
| 321 | + url: `/pages-sub/daily/maintain-manage/add-record?finishState=${item.finishState}&planNo=${item.planNo} &businessType=${item.busiLine}` | |
| 322 | 322 | }) |
| 323 | 323 | } else { |
| 324 | 324 | uni.navigateTo({ |
| 325 | - url: `/pages-sub/daily/maintain-manage/pending-plan-detail?finishState=${item.finishState}&planNo=${item.planNo}&planTypeId=${item.planTypeId}` | |
| 325 | + url: `/pages-sub/daily/maintain-manage/pending-plan-detail?finishState=${item.finishState}&planNo=${item.planNo}&planTypeId=${item.planTypeId} &businessType=${item.busiLine}` | |
| 326 | 326 | }) |
| 327 | 327 | } |
| 328 | 328 | ... | ... |
pages-sub/daily/maintain-manage/pending-plan-detail.vue
| ... | ... | @@ -97,12 +97,15 @@ const batchNo = ref('') |
| 97 | 97 | const planNo = ref('') |
| 98 | 98 | const finishState = ref('') |
| 99 | 99 | const planTypeId = ref('') |
| 100 | +const businessType = ref('') | |
| 101 | + | |
| 100 | 102 | |
| 101 | 103 | // 页面加载接收参数(逻辑完全保留) |
| 102 | 104 | onLoad((options) => { |
| 103 | 105 | planNo.value = options.planNo; |
| 104 | 106 | finishState.value = options.finishState |
| 105 | 107 | planTypeId.value = options.planTypeId |
| 108 | + businessType.value = options.businessType | |
| 106 | 109 | }); |
| 107 | 110 | |
| 108 | 111 | // 页面显示时请求数据(逻辑完全保留) |
| ... | ... | @@ -140,7 +143,7 @@ const gotoFinishPlanDetail = (i) => { |
| 140 | 143 | // 新增记录(逻辑完全保留) |
| 141 | 144 | const addNewRecord = () => { |
| 142 | 145 | uni.navigateTo({ |
| 143 | - url: `/pages-sub/daily/maintain-manage/add-record?planNo=${planNo.value}`, | |
| 146 | + url: `/pages-sub/daily/maintain-manage/add-record?planNo=${planNo.value}&planTypeId=${planTypeId.value}&businessType=${businessType.value}`, | |
| 144 | 147 | }); |
| 145 | 148 | }; |
| 146 | 149 | </script> | ... | ... |
pages-sub/daily/maintain-manage/road-detail-list.vue
| ... | ... | @@ -179,11 +179,11 @@ const submitRecord = (item) => { |
| 179 | 179 | console.log('提交记录:', item.planFinishNum) |
| 180 | 180 | if (item.planFinishNum == 0) { |
| 181 | 181 | uni.navigateTo({ |
| 182 | - url: `/pages-sub/daily/maintain-manage/add-record?finishState=${item.finishState}&planNo=${item.planNo}` | |
| 182 | + url: `/pages-sub/daily/maintain-manage/add-record?finishState=${item.finishState}&planNo=${item.planNo}&businessType=${item.busiLine}` | |
| 183 | 183 | }) |
| 184 | 184 | } else { |
| 185 | 185 | uni.navigateTo({ |
| 186 | - url: `/pages-sub/daily/maintain-manage/pending-plan-detail?finishState=${item.finishState}&planNo=${item.planNo}&planTypeId=${item.planTypeId}` | |
| 186 | + url: `/pages-sub/daily/maintain-manage/pending-plan-detail?finishState=${item.finishState}&planNo=${item.planNo}&planTypeId=${item.planTypeId}&businessType=${item.busiLine}` | |
| 187 | 187 | }) |
| 188 | 188 | } |
| 189 | 189 | } | ... | ... |
蓝信H5改造工作量评估.xlsx
0 → 100644
No preview for this file type