diff --git a/pages-sub/daily/quick-order/add-order.vue b/pages-sub/daily/quick-order/add-order.vue
index 2cf5b58..89cc1d6 100644
--- a/pages-sub/daily/quick-order/add-order.vue
+++ b/pages-sub/daily/quick-order/add-order.vue
@@ -1,15 +1,17 @@
-
-
-
-
+
+
+
+
workOrderFormRef.value?.validateField('problemDesc')"
>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- uploadImgs(event, 'problemImgsList')"
- @delete="(event) => deleteImg(event, 'problemImgsList')"
- multiple
- :max-count="3"
- upload-text="选择问题照片"
- >
-
-
-
-
- uploadImgs(event, 'completeImgsList')"
- @delete="(event) => deleteImg(event, 'completeImgsList')"
- multiple
- :max-count="3"
- :sizeType="['compressed']"
- upload-text="选择完成照片"
- >
-
-
+
+
+
+
+
+ uploadImgs(event, 'problemImgsList')"
+ @delete="(event) => deleteImg(event, 'problemImgsList')"
+ multiple
+ :max-count="3"
+ upload-text="选择问题照片"
+ >
+
+
+
+
+
+
+ uploadImgs(event, 'completeImgsList')"
+ @delete="(event) => deleteImg(event, 'completeImgsList')"
+ multiple
+ :max-count="3"
+ :sizeType="['compressed']"
+ upload-text="选择完成照片"
+ >
+
+
-
-
-
-
-
-
+
+
+
+ workOrderFormRef.value?.validateField('handleResultDesc')"
+ >
+
+
+
@@ -160,6 +145,24 @@
:disabled="isSubmitting"
>
+
+
+
+
+
+
@@ -172,19 +175,12 @@ import { getRoadListByLatLng } from '@/api/common'
import { uploadImages } from '@/common/utils/upload';
import { createQuick } from '@/api/quick-order/quick-order'
-// ========== 基础变量定义(语义化命名) ==========
-// 图片分类标签列表
-const imgTabList = ref([
- { name: '问题照片', id: '1' },
- { name: '完成照片', id: '2' }
-])
-// 激活的图片标签(默认选中问题照片)
-const activeImgTab = ref('1')
+// ========== 基础变量定义 ==========
// 问题照片列表
const problemImgsList = ref([])
// 完成照片列表
const completeImgsList = ref([])
-// 表单Ref(语义化:工单表单)
+// 表单Ref
const workOrderFormRef = ref(null)
// 提交加载状态
const isSubmitting = ref(false)
@@ -199,7 +195,7 @@ const orderNameList = ref([
{ name: '垃圾清理', code: 'ORDER003' }
])
-// ========== 工单表单数据(语义化字段名) ==========
+// ========== 工单表单数据 ==========
const workOrderForm = reactive({
roadId: 0, // 道路ID
roadName: '', // 道路名称
@@ -211,20 +207,20 @@ const workOrderForm = reactive({
lon: 0 // 经度
})
-// ========== 表单校验规则(修复trigger + 语义化) ==========
+// ========== 表单校验规则 ==========
const workOrderFormRules = reactive({
workLocation: [
- { type: 'string', required: true, message: '请选择工单位置', trigger: 'change' }
+ { type: 'string', required: true, message: '请选择工单位置', trigger: ['change', 'blur'] }
],
roadName: [
- { type: 'string', required: true, message: '请选择道路名称', trigger: 'change' }
+ { type: 'string', required: true, message: '请选择道路名称', trigger: ['change', 'blur'] }
],
orderName: [
- { type: 'string', required: true, message: '请选择工单名称', trigger: 'change' }
+ { type: 'string', required: true, message: '请选择工单名称', trigger: ['change', 'blur'] }
],
problemDesc: [
- { type: 'string', required: true, message: '请输入情况描述', trigger: 'change' },
- { type: 'string', min: 3, max: 150, message: '情况描述需3-150字', trigger: 'change' }
+ { type: 'string', required: true, message: '请输入情况描述', trigger: ['change', 'blur'] },
+ { type: 'string', min: 3, max: 150, message: '情况描述需3-150字', trigger: ['change', 'blur'] }
],
problemImgs: [
{ required: true, message: '请上传问题照片', trigger: 'change' }
@@ -233,16 +229,14 @@ const workOrderFormRules = reactive({
{ required: true, message: '请上传完成照片', trigger: 'change' }
],
handleResultDesc: [
- { type: 'string', required: true, message: '请输入处理结果描述', trigger: 'change' },
- { type: 'string', min: 3, max: 200, message: '处理结果需3-200字', trigger: 'change' }
+ { type: 'string', required: true, message: '请输入处理结果描述', trigger: ['change', 'blur'] },
+ { type: 'string', min: 3, max: 200, message: '处理结果需3-200字', trigger: ['change', 'blur'] }
]
})
-// ========== 方法定义(语义化命名 + 修复逻辑) ==========
+// ========== 方法定义 ==========
/**
* 删除图片
- * @param event 删除事件
- * @param type 图片类型(problemImgsList/completeImgsList)
*/
const deleteImg = (event: UploadDeleteEvent, type: string) => {
console.log('删除图片事件:', event, '类型:', type)
@@ -255,19 +249,14 @@ const deleteImg = (event: UploadDeleteEvent, type: string) => {
}
/**
- * 上传图片(单/多图统一逻辑)
- * @param event 上传事件
- * @param type 图片类型(problemImgsList/completeImgsList)
+ * 上传图片
*/
const uploadImgs = async (event: { file: UploadFile | UploadFile[] }, type: string) => {
console.log('上传图片事件:', event, '类型:', type)
- // 统一处理为数组格式
const fileList = Array.isArray(event.file) ? event.file : [event.file]
const targetImgList = type === 'problemImgsList' ? problemImgsList : completeImgsList
- // 1. 提取文件路径
const filePaths = fileList.map(item => item.url)
- // 2. 添加上传中临时项
const tempItems: UploadFile[] = fileList.map(item => ({
...item,
status: 'uploading' as const,
@@ -277,14 +266,12 @@ const uploadImgs = async (event: { file: UploadFile | UploadFile[] }, type: stri
targetImgList.value.push(...tempItems)
try {
- // 3. 调用统一上传方法
const uploadResultUrls = await uploadImages({
filePaths: filePaths,
ignoreError: true
})
console.log('上传成功的URL列表:', uploadResultUrls)
- // 4. 更新成功状态
uploadResultUrls.forEach((url, index) => {
if (targetImgList.value[startIndex + index]) {
targetImgList.value.splice(startIndex + index, 1, {
@@ -296,7 +283,6 @@ const uploadImgs = async (event: { file: UploadFile | UploadFile[] }, type: stri
}
})
- // 5. 处理失败项
if (uploadResultUrls.length < fileList.length) {
const failCount = fileList.length - uploadResultUrls.length
for (let i = uploadResultUrls.length; i < fileList.length; i++) {
@@ -314,7 +300,6 @@ const uploadImgs = async (event: { file: UploadFile | UploadFile[] }, type: stri
}
} catch (err) {
console.error('图片上传失败:', err)
- // 标记所有为失败
for (let i = 0; i < fileList.length; i++) {
if (targetImgList.value[startIndex + i]) {
targetImgList.value.splice(startIndex + i, 1, {
@@ -329,16 +314,7 @@ const uploadImgs = async (event: { file: UploadFile | UploadFile[] }, type: stri
}
/**
- * 切换图片标签
- * @param item 标签项
- */
-const switchImgTab = (item: { name: string; id: string }) => {
- console.log('切换图片标签:', item)
- activeImgTab.value = item.id
-}
-
-/**
- * 选择工单位置(地图)- 核心修改:清空道路名称
+ * 选择工单位置
*/
const chooseWorkLocation = () => {
if (isSubmitting.value) return
@@ -348,17 +324,14 @@ const chooseWorkLocation = () => {
success: () => {
uni.chooseLocation({
success: async (res) => {
- // ========== 核心新增:清空道路名称相关数据 ==========
- workOrderForm.roadName = '' // 清空道路名称
- workOrderForm.roadId = 0 // 清空道路ID
- roadNameList.value = [] // 清空道路名称列表
+ workOrderForm.roadName = ''
+ workOrderForm.roadId = 0
+ roadNameList.value = []
- // 更新工单位置
workOrderForm.workLocation = res.name
workOrderForm.lat = res.latitude
workOrderForm.lon = res.longitude
- // 触发工单位置和道路名称的表单校验更新
workOrderFormRef.value?.validateField('workLocation')
workOrderFormRef.value?.validateField('roadName')
@@ -419,7 +392,6 @@ const chooseWorkLocation = () => {
/**
* 选择道路名称
- * @param e 选择事件
*/
const handleRoadNameSelect = (e: UniActionSheetSelectEvent) => {
console.log('选择道路名称:', e)
@@ -431,7 +403,6 @@ const handleRoadNameSelect = (e: UniActionSheetSelectEvent) => {
/**
* 选择工单名称
- * @param e 选择事件
*/
const handleOrderNameSelect = (e: UniActionSheetSelectEvent) => {
workOrderForm.orderName = e.name
@@ -448,8 +419,6 @@ const hideKeyboard = () => {
/**
* 提取图片URL数组
- * @param imgList 图片列表
- * @returns URL数组
*/
const getImgUrlList = (imgList: UploadFile[]) => {
console.log('提取图片URL:', imgList)
@@ -457,29 +426,28 @@ const getImgUrlList = (imgList: UploadFile[]) => {
}
/**
- * 校验上传图片(兜底校验)
- * @returns 是否校验通过
+ * 校验上传图片
*/
const validateUploadImgs = () => {
- // 修复:补充返回值,避免函数无返回
- if (activeImgTab.value === '1') {
- const hasValidImgs = problemImgsList.value.some(item => item.status === 'success')
- if (!hasValidImgs) {
- uni.showToast({ title: '请上传至少1张问题照片', icon: 'none' })
- return false
- }
- } else {
- const hasValidcompleteImgs = completeImgsList.value.some(item => item.status === 'success')
- if (!hasValidcompleteImgs) {
- uni.showToast({ title: '请上传至少1张完成照片', icon: 'none' })
- return false
- }
+ const hasValidProblemImgs = problemImgsList.value.some(item => item.status === 'success')
+ if (!hasValidProblemImgs) {
+ uni.showToast({ title: '请上传至少1张问题照片', icon: 'none' })
+ workOrderFormRef.value?.validateField('problemImgs')
+ return false
}
+
+ const hasValidCompleteImgs = completeImgsList.value.some(item => item.status === 'success')
+ if (!hasValidCompleteImgs) {
+ uni.showToast({ title: '请上传至少1张完成照片', icon: 'none' })
+ workOrderFormRef.value?.validateField('completeImgs')
+ return false
+ }
+
return true
}
/**
- * 提交工单(修复核心:await位置 + 表单Ref名称错误)
+ * 提交工单
*/
const submitWorkOrder = async () => {
if (isSubmitting.value) {
@@ -490,33 +458,36 @@ const submitWorkOrder = async () => {
try {
isSubmitting.value = true
- // 修复1:兜底校验图片
if (!validateUploadImgs()) {
isSubmitting.value = false
return
}
- // 修复2:使用正确的表单Ref名称(workOrderFormRef 而非 uFormRef)
- // 修复3:将validate转为Promise形式,配合async/await
- const valid = await new Promise((resolve) => {
- workOrderFormRef.value?.validate((isValid) => {
+ const valid = await new Promise((resolve) => {
+ workOrderFormRef.value?.validate((isValid, invalidFields) => {
+ console.log('校验失败的字段:', invalidFields)
resolve(isValid)
})
})
if (!valid) {
- uni.showToast({ title: '表单校验失败,请检查必填项', icon: 'none' })
+ const firstInvalidField = Object.keys(workOrderFormRef.value?.invalidFields || {})[0]
+ if (firstInvalidField) {
+ const el = document.querySelector(`[prop="${firstInvalidField}"]`)
+ el?.scrollIntoView({ behavior: 'smooth', block: 'center' })
+ }
+ uni.showToast({ title: '表单填写不完整,请检查', icon: 'none' })
isSubmitting.value = false
return
}
- // 构造提交数据
const submitData = {
roadId: workOrderForm.roadId,
roadName: workOrderForm.roadName,
- imgs: getImgUrlList(problemImgsList.value), // 问题照片URL数组
- longRangeImgList: getImgUrlList(completeImgsList.value), // 完成照片URL数组
- remark: activeImgTab.value === '2' ? workOrderForm.handleResultDesc : workOrderForm.problemDesc,
+ imgs: getImgUrlList(problemImgsList.value),
+ longRangeImgList: getImgUrlList(completeImgsList.value),
+ remark: workOrderForm.problemDesc,
+ handleResultDesc: workOrderForm.handleResultDesc,
latLonType: 2,
lat: workOrderForm.lat,
lon: workOrderForm.lon,
@@ -529,19 +500,9 @@ const submitWorkOrder = async () => {
}
console.log('提交工单数据:', submitData)
- // 修复4:await 现在在async函数中,可正常使用
await createQuick(submitData)
uni.showToast({ title: '工单提交成功', icon: 'success' })
- // 可选:提交成功后重置表单
- // problemImgsList.value = []
- // completeImgsList.value = []
- // Object.assign(workOrderForm, {
- // roadId: 0, roadName: '', workLocation: '', orderName: '',
- // problemDesc: '', handleResultDesc: '', lat: 0, lon: 0
- // })
- // workOrderFormRef.value?.clearValidate()
-
} catch (error) {
console.error('提交工单失败:', error)
uni.showToast({ title: '提交失败,请重试', icon: 'none' })
@@ -552,12 +513,10 @@ const submitWorkOrder = async () => {
// ========== 页面挂载初始化 ==========
onMounted(() => {
- setTimeout(() => {
- if (workOrderFormRef.value && !workOrderFormRef.value.rules) {
- workOrderFormRef.value.setRules(workOrderFormRules)
- console.log('工单表单规则初始化完成')
- }
- }, 200)
+ if (workOrderFormRef.value && !workOrderFormRef.value.rules) {
+ workOrderFormRef.value.setRules(workOrderFormRules)
+ console.log('工单表单规则初始化完成')
+ }
})
@@ -566,10 +525,15 @@ onMounted(() => {
.u-page {
background-color: #f5f5f5;
min-height: 100vh;
- padding-bottom: 100rpx; // 给底部按钮留空间
+ padding-bottom: 100rpx;
+}
+
+// 表单容器(新增:包裹整个表单)
+.work-order-form-container {
+ width: 100%;
}
-// 工单表单容器
+// 工单表单内容容器
.work-order-form-content {
background: #fff;
padding: 20rpx;
@@ -612,7 +576,7 @@ onMounted(() => {
}
// 提交按钮区域
-.fixed-bottom-btn-wrap { // 修复:原样式类名是submit-btn-wrap,与模板不一致
+.fixed-bottom-btn-wrap {
position: fixed;
bottom: 0;
left: 0;
@@ -630,15 +594,15 @@ onMounted(() => {
}
}
-// ========== 修复Label折行样式 ==========
+// Label样式
:deep(.u-form-item__label) {
- white-space: nowrap; // 强制不换行
- text-overflow: ellipsis; // 超出省略
- overflow: hidden; // 隐藏超出部分
- line-height: 1.4; // 行高适配
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ line-height: 1.4;
}
-// 表单基础样式适配
+// 表单基础样式
:deep(.u-form-item) {
--u-form-item-label-font-size: 28rpx;
--u-form-item-content-font-size: 28rpx;
@@ -658,7 +622,14 @@ onMounted(() => {
z-index: 9999 !important;
}
-:deep(.u-tabs) {
- background: #fff;
+// 错误提示样式
+:deep(.u-form-item__error-message) {
+ font-size: 24rpx !important;
+ color: #f56c6c !important;
+ margin-top: 5rpx !important;
+}
+
+:deep(.u-form-item--error .u-input__wrap) {
+ border-color: #f56c6c !important;
}
\ No newline at end of file