| | |
| | | clearable /> |
| | | </u-form-item> |
| | | <u-form-item label="保养状态" |
| | | prop="status" |
| | | prop="maintenancestatusText" |
| | | required |
| | | border-bottom> |
| | | <u-input v-model="maintenancestatusText" |
| | |
| | | style="margin-right: 5px;"></u-icon> |
| | | {{ uploading ? '上传中...' : '拍照' }} |
| | | </u-button> |
| | | <u-button type="success" |
| | | <!-- <u-button type="success" |
| | | @click="chooseMedia('video')" |
| | | :loading="uploading" |
| | | :disabled="uploadFiles.length >= uploadConfig.limit" |
| | |
| | | color="#fff" |
| | | style="margin-right: 5px;"></uni-icons> |
| | | {{ uploading ? '上传中...' : '拍视频' }} |
| | | </u-button> |
| | | </u-button> --> |
| | | </view> |
| | | <!-- 上传进度 --> |
| | | <view v-if="uploading" |
| | |
| | | :key="index" |
| | | class="file-item"> |
| | | <view class="file-preview-container"> |
| | | <!-- {{formatFileUrl(file.url)}} --> |
| | | <image v-if="file.type === 'image' || isImageFile(file)" |
| | | :src="file.url || file.tempFilePath || file.path || file.downloadUrl" |
| | | :src="formatFileUrl(file.url || file.tempFilePath || file.path || file.downloadUrl)" |
| | | class="file-preview" |
| | | mode="aspectFill" /> |
| | | <view v-else-if="file.type === 'video'" |
| | |
| | | </view> |
| | | <view v-if="uploadFiles.length === 0" |
| | | class="empty-state"> |
| | | <text>请选择要上传的保养图片或视频</text> |
| | | <text>请选择要上传的保养图片</text> |
| | | </view> |
| | | </view> |
| | | </u-form-item> |
| | |
| | | <view class="spare-part-popup"> |
| | | <view class="popup-header"> |
| | | <text class="popup-title">选择设备备件</text> |
| | | <up-button type="primary" |
| | | size="small" |
| | | @click="confirmSparePartSelection">确定</up-button> |
| | | </view> |
| | | <view class="spare-part-options"> |
| | | <view v-for="(item, index) in sparePartOptions" |
| | |
| | | color="#2c7be5" /> |
| | | </view> |
| | | </view> |
| | | <up-button type="primary" |
| | | size="small" |
| | | :customStyle="{ borderRadius: '6px', padding: '4px 12px' }" |
| | | @click="confirmSparePartSelection">确定</up-button> |
| | | </view> |
| | | </up-popup> |
| | | </view> |
| | |
| | | |
| | | // 提交表单 |
| | | const sendForm = async () => { |
| | | console.log(form.value.sparePartsIds, "form.value.sparePartsIds"); |
| | | try { |
| | | // 手动验证表单 |
| | | let isValid = true; |
| | |
| | | const submitData = { |
| | | ...form.value, |
| | | imagesFile: form.value.status == "1" ? uploadFiles.value : [], |
| | | sparePartsIds: form.sparePartsIds ? form.sparePartsIds.join(",") : "", |
| | | sparePartsIds: form.value.sparePartsIds |
| | | ? form.value.sparePartsIds.join(",") |
| | | : "", |
| | | }; |
| | | const { code } = await addMaintenance({ id: id, ...submitData }); |
| | | |
| | |
| | | return uni.getStorageSync("repairId"); |
| | | }; |
| | | |
| | | const dataform = ref({}); |
| | | // 获取设备信息 |
| | | const getUpkeepItemData = () => { |
| | | try { |
| | |
| | | if (!dataStr) { |
| | | return null; |
| | | } |
| | | dataform.value = JSON.parse(dataStr); |
| | | fetchSparePartOptions(dataform.value.deviceLedgerId); |
| | | return JSON.parse(dataStr); |
| | | } catch (e) { |
| | | console.error("解析设备数据失败:", e); |
| | |
| | | }; |
| | | |
| | | // 检查备件是否已选中 |
| | | const isSparePartSelected = value => { |
| | | return tempSelectedSpareParts.value.some(item => item.value === value); |
| | | const isSparePartSelected = id => { |
| | | return tempSelectedSpareParts.value.some( |
| | | item => item.id === id || item.value === id |
| | | ); |
| | | }; |
| | | |
| | | // 切换备件选中状态 |
| | | const toggleSparePartSelection = item => { |
| | | const itemId = item.id || item.value; |
| | | const index = tempSelectedSpareParts.value.findIndex( |
| | | selected => selected.value === item.value |
| | | selected => selected.id === itemId || selected.value === itemId |
| | | ); |
| | | if (index > -1) { |
| | | tempSelectedSpareParts.value.splice(index, 1); |
| | |
| | | // 确认备件选择 |
| | | const confirmSparePartSelection = () => { |
| | | selectedSpareParts.value = [...tempSelectedSpareParts.value]; |
| | | form.value.sparePartsIds = selectedSpareParts.value.map(item => item.value); |
| | | form.value.sparePartsIds = selectedSpareParts.value.map(item => item.id); |
| | | showSparePart.value = false; |
| | | }; |
| | | |
| | | // 移除已选备件 |
| | | const removeSparePart = index => { |
| | | selectedSpareParts.value.splice(index, 1); |
| | | form.value.sparePartsIds = selectedSpareParts.value.map(item => item.value); |
| | | form.value.sparePartsIds = selectedSpareParts.value.map(item => item.id); |
| | | }; |
| | | |
| | | const sparePartsIds = ref([]); |
| | | // 初始化表单数据 |
| | | const initForm = () => { |
| | | // 获取设备信息 |
| | |
| | | maintenancestatusText.value = statusMap[itemData.status] || ""; |
| | | } |
| | | // 填充备件数据 |
| | | if (itemData.spareParts && itemData.spareParts.length > 0) { |
| | | selectedSpareParts.value = itemData.spareParts.map(sparePart => ({ |
| | | id: sparePart.id || sparePart.sparePartId || sparePart.value, |
| | | name: sparePart.name || sparePart.sparePartName, |
| | | code: sparePart.code || sparePart.sparePartCode, |
| | | value: sparePart.id || sparePart.sparePartId || sparePart.value, |
| | | })); |
| | | // 设置备件IDs |
| | | form.value.sparePartsIds = selectedSpareParts.value |
| | | .map(item => item.value) |
| | | .join(","); |
| | | } |
| | | |
| | | // 处理字符串格式的备件IDs |
| | | sparePartsIds.value = itemData.sparePartsIds; |
| | | |
| | | // 填充附件数据 |
| | | if (itemData.files && itemData.files.length > 0) { |
| | | uploadFiles.value = itemData.files.map(file => ({ |
| | |
| | | } |
| | | }; |
| | | |
| | | onShow(() => { |
| | | onShow(async () => { |
| | | // 先获取备件选项,再初始化表单 |
| | | const pageId = getPageId(); |
| | | if (pageId) { |
| | | await fetchSparePartOptions(pageId); |
| | | } |
| | | // 页面显示时初始化表单 |
| | | initForm(); |
| | | fetchSparePartOptions(getPageId()); |
| | | }); |
| | | const sparePartOptions = ref([]); |
| | | const fetchSparePartOptions = deviceLedgerId => { |
| | | getSparePartsOptions({ deviceLedgerId: deviceLedgerId }).then(res => { |
| | | if (res.code == 200) { |
| | | sparePartOptions.value = res.data || []; |
| | | } |
| | | return new Promise((resolve, reject) => { |
| | | getSparePartsOptions({ deviceLedgerId: deviceLedgerId }) |
| | | .then(res => { |
| | | if (res.code == 200) { |
| | | sparePartOptions.value = res.data || []; |
| | | const idArray = |
| | | typeof sparePartsIds.value === "string" |
| | | ? sparePartsIds.value.split(",") |
| | | : sparePartsIds.value; |
| | | |
| | | if (idArray.length > 0) { |
| | | selectedSpareParts.value = sparePartOptions.value |
| | | .filter( |
| | | option => |
| | | idArray.includes(option.id.toString()) || |
| | | idArray.includes(option.value?.toString()) |
| | | ) |
| | | .map(option => ({ |
| | | id: option.id || option.value, |
| | | name: option.name, |
| | | code: option.code, |
| | | value: option.id || option.value, |
| | | })); |
| | | // 设置备件IDs |
| | | form.value.sparePartsIds = idArray.join(","); |
| | | } |
| | | resolve(res.data); |
| | | } else { |
| | | resolve([]); |
| | | } |
| | | }) |
| | | .catch(err => { |
| | | console.error("获取备件选项失败:", err); |
| | | resolve([]); |
| | | }); |
| | | }); |
| | | }; |
| | | |
| | | // 格式化文件URL |
| | | const formatFileUrl = url => { |
| | | if (!url) return ""; |
| | | // const formatFileUrl = url => { |
| | | // if (!url) return ""; |
| | | |
| | | // 如果已经是完整的URL(http或https开头),直接返回 |
| | | if (url.startsWith("http://") || url.startsWith("https://")) { |
| | | return url; |
| | | } |
| | | // // 如果已经是完整的URL(http或https开头),直接返回 |
| | | // if (url.startsWith("http://") || url.startsWith("https://")) { |
| | | // return url; |
| | | // } |
| | | |
| | | // 如果是本地路径(如 D:\\ruoyi\\prod\\uploads...),需要转换为网络URL |
| | | // 从路径中提取uploads后面的部分 |
| | | const uploadsIndex = url.indexOf("uploads"); |
| | | if (uploadsIndex !== -1) { |
| | | const relativePath = url.substring(uploadsIndex); |
| | | // 使用baseUrl + /profile/ + 相对路径 |
| | | return `http://192.168.1.35:8888/profile/${relativePath}`; |
| | | } |
| | | // // 如果是本地路径(如 D:\\ruoyi\\prod\\uploads...),需要转换为网络URL |
| | | // // 从路径中提取uploads后面的部分 |
| | | // const uploadsIndex = url.indexOf("uploads"); |
| | | // if (uploadsIndex !== -1) { |
| | | // const relativePath = url.substring(uploadsIndex); |
| | | // // 使用baseUrl + /profile/ + 相对路径 |
| | | // return `http://192.168.1.35:8888/profile/${relativePath}`; |
| | | // } |
| | | |
| | | // 其他情况,尝试直接拼接 |
| | | return `http://192.168.1.35:8888/profile/${url}`; |
| | | }; |
| | | // // 其他情况,尝试直接拼接 |
| | | // return `http://192.168.1.35:8888/profile/${url}`; |
| | | // }; |
| | | |
| | | // 格式化文件大小 |
| | | const formatFileSize = size => { |
| | |
| | | uploadProgress.value = res.progress; |
| | | }); |
| | | } |
| | | }; // 格式化文件URL |
| | | const formatFileUrl = url => { |
| | | if (!url) return ""; |
| | | if (url.startsWith("http://") || url.startsWith("https://")) { |
| | | return url; |
| | | } |
| | | // const uploadsIndex = url.indexOf("uploads"); |
| | | // if (uploadsIndex !== -1) { |
| | | // const relativePath = url.substring(uploadsIndex); |
| | | // return `${config.fileUrl}/${relativePath}`; |
| | | // } |
| | | return `${config.fileUrl}/${url}`; |
| | | }; |
| | | |
| | | // 上传成功处理 |
| | |
| | | font-weight: 500; |
| | | } |
| | | |
| | | /* 备件选择弹窗样式 */ |
| | | .spare-part-popup { |
| | | width: 100%; |
| | | max-height: 80vh; |
| | | background: #fff; |
| | | border-radius: 16px 16px 0 0; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .popup-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | padding: 16px 20px; |
| | | border-bottom: 1px solid #f0f0f0; |
| | | background: #f8f9fa; |
| | | } |
| | | |
| | | .popup-title { |
| | | font-size: 16px; |
| | | font-weight: 600; |
| | | color: #333; |
| | | } |
| | | |
| | | .spare-part-options { |
| | | padding: 10px 0; |
| | | max-height: 60vh; |
| | | overflow-y: auto; |
| | | } |
| | | |
| | | .spare-part-option { |
| | | position: relative; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | padding: 14px 20px; |
| | | border-bottom: 1px solid #f0f0f0; |
| | | transition: all 0.2s ease; |
| | | } |
| | | |
| | | .spare-part-option:last-child { |
| | | border-bottom: none; |
| | | } |
| | | |
| | | .spare-part-option:hover { |
| | | background: #f8f9fa; |
| | | } |
| | | |
| | | .spare-part-option.selected { |
| | | background: #e6f7ff; |
| | | color: #1890ff; |
| | | } |
| | | |
| | | .spare-part-option.selected::before { |
| | | content: ""; |
| | | position: absolute; |
| | | left: 0; |
| | | top: 0; |
| | | bottom: 0; |
| | | width: 4px; |
| | | background: #1890ff; |
| | | } |
| | | |
| | | /* 文件上传样式 */ |
| | | .simple-upload-area { |
| | | width: 100%; |