| | |
| | | <template> |
| | | <view class="upkeep-maintain"> |
| | | <!-- 使ç¨éç¨é¡µé¢å¤´é¨ç»ä»¶ --> |
| | | <PageHeader title="æ°å¢ä¿å
»" @back="goBack" /> |
| | | |
| | | <!-- 表åå
容 --> |
| | | <u-form ref="formRef" :model="form" :rules="formRules" label-width="110px" :error-type="['message']"> |
| | | <!-- åºæ¬ä¿¡æ¯ --> |
| | | <u-form-item label="å®é
ä¿å
»äºº" prop="maintenanceActuallyName" required border-bottom> |
| | | <u-input |
| | | v-model="form.maintenanceActuallyName" |
| | | placeholder="请è¾å
¥å®é
ä¿å
»äºº" |
| | | clearable |
| | | /> |
| | | </u-form-item> |
| | | |
| | | <u-form-item label="å®é
ä¿å
»æ¥æ" prop="maintenanceActuallyTime" required border-bottom> |
| | | <u-input |
| | | v-model="form.maintenanceActuallyTime" |
| | | placeholder="è¯·éæ©å®é
ä¿å
»æ¥æ" |
| | | readonly |
| | | @click="showDatePicker" |
| | | clearable |
| | | /> |
| | | <template #right> |
| | | <u-icon name="arrow-right" @click.stop="showDatePicker" /> |
| | | </template> |
| | | </u-form-item> |
| | | |
| | | <u-form-item label="ä¿å
ȍȾ" prop="maintenanceResult" required border-bottom> |
| | | <u-input |
| | | v-model="maintenanceResultText" |
| | | placeholder="è¯·éæ©ä¿å
ȍȾ" |
| | | readonly |
| | | @click="showResultPicker" |
| | | clearable |
| | | /> |
| | | <template #right> |
| | | <u-icon name="arrow-right" @click.stop="showResultPicker" /> |
| | | </template> |
| | | </u-form-item> |
| | | |
| | | <!-- æäº¤æé® --> |
| | | <view class="footer-btns"> |
| | | <u-button class="cancel-btn" @click="goBack">åæ¶</u-button> |
| | | <u-button class="save-btn" @click="sendForm" :loading="loading">ä¿å</u-button> |
| | | </view> |
| | | </u-form> |
| | | |
| | | <!-- æ¥æéæ©å¨ --> |
| | | <u-popup v-model="showDate" mode="bottom" :closeable="true"> |
| | | <u-datetime-picker |
| | | v-model="form.maintenanceActuallyTime" |
| | | mode="date" |
| | | title="éæ©æ¥æ" |
| | | @confirm="onDateConfirm" |
| | | @cancel="showDate = false" |
| | | /> |
| | | </u-popup> |
| | | |
| | | <!-- ä¿å
»ç»æéæ©å¨ --> |
| | | <up-action-sheet |
| | | :show="showResult" |
| | | :actions="resultColumns" |
| | | title="éæ©ä¿å
ȍȾ" |
| | | @select="onResultConfirm" |
| | | @close="showResult = false" |
| | | /> |
| | | </view> |
| | | <view class="upkeep-maintain"> |
| | | <!-- 使ç¨éç¨é¡µé¢å¤´é¨ç»ä»¶ --> |
| | | <PageHeader title="æ°å¢ä¿å
»" |
| | | @back="goBack" /> |
| | | <!-- 表åå
容 --> |
| | | <u-form ref="formRef" |
| | | :model="form" |
| | | :rules="formRules" |
| | | label-width="110px" |
| | | :error-type="['message']"> |
| | | <!-- åºæ¬ä¿¡æ¯ --> |
| | | <u-form-item label="å®é
ä¿å
»äºº" |
| | | prop="maintenanceActuallyName" |
| | | required |
| | | border-bottom> |
| | | <u-input v-model="form.maintenanceActuallyName" |
| | | placeholder="请è¾å
¥å®é
ä¿å
»äºº" |
| | | clearable /> |
| | | </u-form-item> |
| | | <u-form-item label="å®é
ä¿å
»æ¥æ" |
| | | prop="maintenanceActuallyTime" |
| | | required |
| | | border-bottom> |
| | | <u-input v-model="form.maintenanceActuallyTime" |
| | | placeholder="è¯·éæ©å®é
ä¿å
»æ¥æ" |
| | | readonly |
| | | @click="showDatePicker" |
| | | clearable /> |
| | | <template #right> |
| | | <u-icon name="arrow-right" |
| | | @click.stop="showDatePicker" /> |
| | | </template> |
| | | </u-form-item> |
| | | <u-form-item label="ä¿å
ȍȾ" |
| | | prop="maintenanceResult" |
| | | required |
| | | border-bottom> |
| | | <u-input v-model="form.maintenanceResult" |
| | | placeholder="请è¾å
¥ä¿å
ȍȾ" |
| | | clearable /> |
| | | </u-form-item> |
| | | <u-form-item label="ä¿å
»ç¶æ" |
| | | prop="status" |
| | | required |
| | | border-bottom> |
| | | <u-input v-model="maintenancestatusText" |
| | | placeholder="è¯·éæ©ä¿å
»ç¶æ" |
| | | readonly |
| | | @click="showResultPicker" |
| | | clearable /> |
| | | <template #right> |
| | | <u-icon name="arrow-right" |
| | | @click="showResultPicker" /> |
| | | </template> |
| | | </u-form-item> |
| | | <u-form-item label="设å¤å¤ä»¶" |
| | | prop="sparePartsIds" |
| | | border-bottom> |
| | | <view class="spare-parts-container" |
| | | @click="showSparePartPicker"> |
| | | <view v-if="selectedSpareParts.length > 0" |
| | | class="spare-parts-list"> |
| | | <view v-for="(item, index) in selectedSpareParts" |
| | | :key="index" |
| | | class="spare-part-tag"> |
| | | <text>{{ item.name }}</text> |
| | | <u-icon name="close" |
| | | size="12" |
| | | color="#fff" |
| | | @click="removeSparePart(index)" /> |
| | | </view> |
| | | </view> |
| | | <text v-else |
| | | class="placeholder">è¯·éæ©è®¾å¤å¤ä»¶</text> |
| | | </view> |
| | | <template #right> |
| | | <u-icon name="arrow-right" |
| | | @click="showSparePartPicker" /> |
| | | </template> |
| | | </u-form-item> |
| | | <!-- ä¸ä¼ éä»¶ --> |
| | | <u-form-item v-if="form.status == '1'" |
| | | label="ä¿å
»éä»¶" |
| | | border-bottom> |
| | | <view class="simple-upload-area"> |
| | | <view class="upload-buttons"> |
| | | <u-button type="primary" |
| | | @click="chooseMedia('image')" |
| | | :loading="uploading" |
| | | :disabled="uploadFiles.length >= uploadConfig.limit" |
| | | :customStyle="{ marginRight: '10px', flex: 1 }"> |
| | | <u-icon name="camera" |
| | | size="18" |
| | | color="#fff" |
| | | style="margin-right: 5px;"></u-icon> |
| | | {{ uploading ? 'ä¸ä¼ ä¸...' : 'æç
§' }} |
| | | </u-button> |
| | | <u-button type="success" |
| | | @click="chooseMedia('video')" |
| | | :loading="uploading" |
| | | :disabled="uploadFiles.length >= uploadConfig.limit" |
| | | :customStyle="{ flex: 1 }"> |
| | | <uni-icons type="videocam" |
| | | name="videocam" |
| | | size="18" |
| | | color="#fff" |
| | | style="margin-right: 5px;"></uni-icons> |
| | | {{ uploading ? 'ä¸ä¼ ä¸...' : 'æè§é¢' }} |
| | | </u-button> |
| | | </view> |
| | | <!-- ä¸ä¼ è¿åº¦ --> |
| | | <view v-if="uploading" |
| | | class="upload-progress"> |
| | | <u-line-progress :percentage="uploadProgress" |
| | | :showText="true" |
| | | activeColor="#409eff"></u-line-progress> |
| | | </view> |
| | | <!-- ä¸ä¼ çæä»¶å表 --> |
| | | <view v-if="uploadFiles.length > 0" |
| | | class="file-list"> |
| | | <view v-for="(file, index) in uploadFiles" |
| | | :key="index" |
| | | class="file-item"> |
| | | <view class="file-preview-container"> |
| | | <image v-if="file.type === 'image' || isImageFile(file)" |
| | | :src="file.url || file.tempFilePath || file.path || file.downloadUrl" |
| | | class="file-preview" |
| | | mode="aspectFill" /> |
| | | <view v-else-if="file.type === 'video'" |
| | | class="video-preview"> |
| | | <uni-icons type="videocam" |
| | | name="videocam" |
| | | size="18" |
| | | color="#fff" |
| | | style="margin-right: 5px;"></uni-icons> |
| | | <text class="video-text">è§é¢</text> |
| | | </view> |
| | | <!-- å é¤æé® --> |
| | | <view class="delete-btn" |
| | | @click="removeFile(index)"> |
| | | <u-icon name="close" |
| | | size="12" |
| | | color="#fff"></u-icon> |
| | | </view> |
| | | </view> |
| | | <view class="file-info"> |
| | | <text class="file-name">{{ file.bucketFilename || file.name || (file.type === 'image' ? 'å¾ç' : 'è§é¢') |
| | | }}</text> |
| | | <text class="file-size">{{ formatFileSize(file.size) }}</text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <view v-if="uploadFiles.length === 0" |
| | | class="empty-state"> |
| | | <text>è¯·éæ©è¦ä¸ä¼ çä¿å
»å¾çæè§é¢</text> |
| | | </view> |
| | | </view> |
| | | </u-form-item> |
| | | <!-- æäº¤æé® --> |
| | | <view class="footer-btns"> |
| | | <u-button class="cancel-btn" |
| | | @click="goBack">åæ¶</u-button> |
| | | <u-button class="save-btn" |
| | | @click="sendForm" |
| | | :loading="loading">ä¿å</u-button> |
| | | </view> |
| | | </u-form> |
| | | <!-- æ¥æéæ©å¨ --> |
| | | <u-popup v-model="showDate" |
| | | mode="bottom" |
| | | :closeable="true"> |
| | | <u-datetime-picker v-model="form.maintenanceActuallyTime" |
| | | mode="date" |
| | | title="éæ©æ¥æ" |
| | | @confirm="onDateConfirm" |
| | | @cancel="showDate = false" /> |
| | | </u-popup> |
| | | <!-- ä¿å
»ç»æéæ©å¨ --> |
| | | <up-action-sheet :show="showResult" |
| | | :actions="resultColumns" |
| | | title="éæ©ä¿å
ȍȾ" |
| | | @select="onResultConfirm" |
| | | @close="showResult = false" /> |
| | | <!-- 设å¤å¤ä»¶éæ©å¨ --> |
| | | <up-popup :show="showSparePart" |
| | | mode="bottom" |
| | | :closeable="true" |
| | | @close="showSparePart = false"> |
| | | <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" |
| | | :key="index" |
| | | class="spare-part-option" |
| | | :class="{ 'selected': isSparePartSelected(item.id) }" |
| | | @click="toggleSparePartSelection(item)"> |
| | | <text>{{ item.name }}</text> |
| | | <u-icon v-if="isSparePartSelected(item.id)" |
| | | name="checkmark" |
| | | color="#2c7be5" /> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </up-popup> |
| | | </view> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, onMounted } from 'vue'; |
| | | import { onShow } from '@dcloudio/uni-app'; |
| | | import PageHeader from '@/components/PageHeader.vue'; |
| | | import { addMaintenance } from '@/api/equipmentManagement/upkeep'; |
| | | import useUserStore from "@/store/modules/user"; |
| | | import dayjs from "dayjs"; |
| | | import { formatDateToYMD } from '@/utils/ruoyi'; |
| | | import { ref, onMounted } from "vue"; |
| | | import { onShow } from "@dcloudio/uni-app"; |
| | | import PageHeader from "@/components/PageHeader.vue"; |
| | | import { |
| | | addMaintenance, |
| | | getSparePartsOptions, |
| | | } from "@/api/equipmentManagement/upkeep"; |
| | | import useUserStore from "@/store/modules/user"; |
| | | import dayjs from "dayjs"; |
| | | import { formatDateToYMD } from "@/utils/ruoyi"; |
| | | import config from "@/config"; |
| | | |
| | | // æ¾ç¤ºæç¤ºä¿¡æ¯ |
| | | const showToast = (message) => { |
| | | uni.showToast({ |
| | | title: message, |
| | | icon: 'none' |
| | | }) |
| | | }; |
| | | // æ¾ç¤ºæç¤ºä¿¡æ¯ |
| | | const showToast = message => { |
| | | uni.showToast({ |
| | | title: message, |
| | | icon: "none", |
| | | }); |
| | | }; |
| | | |
| | | defineOptions({ |
| | | name: "设å¤ä¿å
»è¡¨å", |
| | | }); |
| | | defineOptions({ |
| | | name: "设å¤ä¿å
»è¡¨å", |
| | | }); |
| | | |
| | | const userStore = useUserStore(); |
| | | const userStore = useUserStore(); |
| | | |
| | | // 表åå¼ç¨ |
| | | const formRef = ref(null); |
| | | const loading = ref(false); |
| | | const showDate = ref(false); |
| | | const showResult = ref(false); |
| | | const currentDate = ref([new Date().getFullYear(), new Date().getMonth() + 1, new Date().getDate()]); |
| | | const resultPickerValue = ref([]); |
| | | const maintenanceResultText = ref(''); |
| | | // 表åå¼ç¨ |
| | | const formRef = ref(null); |
| | | const loading = ref(false); |
| | | const showDate = ref(false); |
| | | const showResult = ref(false); |
| | | const showSparePart = ref(false); |
| | | const currentDate = ref([ |
| | | new Date().getFullYear(), |
| | | new Date().getMonth() + 1, |
| | | new Date().getDate(), |
| | | ]); |
| | | const resultPickerValue = ref([]); |
| | | const maintenancestatusText = ref(""); |
| | | const selectedSpareParts = ref([]); |
| | | const tempSelectedSpareParts = ref([]); |
| | | |
| | | // ä¿å
»ç»æé项 |
| | | const resultColumns = [ |
| | | { name: 'å®å¥½', value: 1 }, |
| | | { name: 'ç»´ä¿®', value: 0 } |
| | | ]; |
| | | // æä»¶ä¸ä¼ ç¸å
³ |
| | | const uploadFiles = ref([]); |
| | | const uploading = ref(false); |
| | | const uploadProgress = ref(0); |
| | | const number = ref(0); |
| | | |
| | | // 表åéªè¯è§å |
| | | const formRules = { |
| | | maintenanceActuallyName: [{ required: true, trigger: "blur", message: "请è¾å
¥å®é
ä¿å
»äºº" }], |
| | | maintenanceActuallyTime: [{ required: true, trigger: "change", message: "è¯·éæ©å®é
ä¿å
»æ¥æ" }], |
| | | maintenanceResult: [{ required: true, trigger: "change", message: "è¯·éæ©ä¿å
ȍȾ" }], |
| | | }; |
| | | // ä¸ä¼ é
ç½® |
| | | const uploadConfig = { |
| | | limit: 9, |
| | | fileType: ["jpg", "jpeg", "png", "gif", "webp", "mp4", "mov", "avi", "wmv"], |
| | | maxVideoDuration: 60, |
| | | }; |
| | | |
| | | // ä½¿ç¨ ref 声æè¡¨åæ°æ® |
| | | const form = ref({ |
| | | maintenanceActuallyName: userStore.nickName || '', // é»è®¤ä½¿ç¨å½åç¨æ·æµç§° |
| | | maintenanceResult: undefined, // ä¿å
ȍȾ |
| | | maintenanceActuallyTime: dayjs().format("YYYY-MM-DD HH:mm:ss"), // å®é
ä¿å
»æ¥æï¼åªæ¾ç¤ºæ¥æï¼ |
| | | }); |
| | | // ä¸ä¼ æä»¶URL |
| | | const uploadFileUrl = ref(`${config.baseUrl}/file/upload`); |
| | | |
| | | // æ¸
é¤è¡¨åæ ¡éªç¶æ |
| | | const clearValidate = () => { |
| | | // uview-plusä¸éè¦æå¨æ¸
é¤éªè¯ç¶æï¼éç½®è¡¨åæ¶ä¼èªå¨æ¸
é¤ |
| | | }; |
| | | // ä¿å
»ç»æé项 |
| | | const resultColumns = [ |
| | | { name: "å®ç»", value: 1 }, |
| | | { name: "å¾
ä¿å
»", value: 0 }, |
| | | { name: "失败", value: 2 }, |
| | | ]; |
| | | |
| | | // éç½®è¡¨åæ°æ®åæ ¡éªç¶æ |
| | | const resetForm = () => { |
| | | form.value = { |
| | | maintenanceActuallyName: userStore.nickName || '', |
| | | maintenanceResult: undefined, |
| | | maintenanceActuallyTime: dayjs().format("YYYY-MM-DD HH:mm:ss"), |
| | | }; |
| | | maintenanceResultText.value = ''; |
| | | }; |
| | | // 表åéªè¯è§å |
| | | const formRules = { |
| | | maintenanceActuallyName: [ |
| | | { required: true, trigger: "blur", message: "请è¾å
¥å®é
ä¿å
»äºº" }, |
| | | ], |
| | | maintenanceActuallyTime: [ |
| | | { required: true, trigger: "change", message: "è¯·éæ©å®é
ä¿å
»æ¥æ" }, |
| | | ], |
| | | maintenanceResult: [ |
| | | { required: true, trigger: "change", message: "è¯·éæ©ä¿å
ȍȾ" }, |
| | | ], |
| | | }; |
| | | |
| | | const resetFormAndValidate = () => { |
| | | resetForm(); |
| | | // clearValidate(); // å é¤è¿è¡ï¼Vant4ä¼èªå¨å¤ç |
| | | }; |
| | | // ä½¿ç¨ ref 声æè¡¨åæ°æ® |
| | | const form = ref({ |
| | | maintenanceActuallyName: userStore.nickName || "", // é»è®¤ä½¿ç¨å½åç¨æ·æµç§° |
| | | maintenanceResult: undefined, // ä¿å
ȍȾ |
| | | maintenanceActuallyTime: dayjs().format("YYYY-MM-DD HH:mm:ss"), // å®é
ä¿å
»æ¥æï¼åªæ¾ç¤ºæ¥æï¼ |
| | | sparePartsIds: undefined, // 设å¤å¤ä»¶ID |
| | | }); |
| | | |
| | | // æäº¤è¡¨å |
| | | const sendForm = async () => { |
| | | try { |
| | | // æå¨éªè¯è¡¨å |
| | | let isValid = true; |
| | | let errorMessage = ''; |
| | | if (!form.value.maintenanceActuallyName) { |
| | | isValid = false; |
| | | errorMessage = '请è¾å
¥å®é
ä¿å
»äºº'; |
| | | } else if (!form.value.maintenanceActuallyTime) { |
| | | isValid = false; |
| | | errorMessage = 'è¯·éæ©å®é
ä¿å
»æ¥æ'; |
| | | } else if (form.value.maintenanceResult === undefined) { |
| | | isValid = false; |
| | | errorMessage = 'è¯·éæ©ä¿å
ȍȾ'; |
| | | } |
| | | // æ¸
é¤è¡¨åæ ¡éªç¶æ |
| | | const clearValidate = () => { |
| | | // uview-plusä¸éè¦æå¨æ¸
é¤éªè¯ç¶æï¼éç½®è¡¨åæ¶ä¼èªå¨æ¸
é¤ |
| | | }; |
| | | |
| | | if (!isValid) { |
| | | showToast(errorMessage); |
| | | return; |
| | | } |
| | | // éç½®è¡¨åæ°æ®åæ ¡éªç¶æ |
| | | const resetForm = () => { |
| | | form.value = { |
| | | maintenanceActuallyName: userStore.nickName || "", |
| | | maintenanceResult: undefined, |
| | | maintenanceActuallyTime: dayjs().format("YYYY-MM-DD HH:mm:ss"), |
| | | sparePartsIds: [], |
| | | }; |
| | | maintenancestatusText.value = ""; |
| | | selectedSpareParts.value = []; |
| | | tempSelectedSpareParts.value = []; |
| | | }; |
| | | |
| | | // éªè¯éè¿ |
| | | submitFormData(); |
| | | } catch (e) { |
| | | showToast('表åéªè¯å¤±è´¥'); |
| | | } |
| | | }; |
| | | const resetFormAndValidate = () => { |
| | | resetForm(); |
| | | // clearValidate(); // å é¤è¿è¡ï¼Vant4ä¼èªå¨å¤ç |
| | | }; |
| | | // 夿æ¯å¦ä¸ºå¾çæä»¶ |
| | | const isImageFile = file => { |
| | | // æ£æ¥contentTypeåæ®µ |
| | | if (file.contentType && file.contentType.startsWith("image/")) { |
| | | return true; |
| | | } |
| | | |
| | | // æäº¤è¡¨åæ°æ® |
| | | const submitFormData = async () => { |
| | | try { |
| | | loading.value = true; |
| | | const id = getPageId(); |
| | | |
| | | if (!id) { |
| | | showToast('åæ°é误'); |
| | | loading.value = false; |
| | | return; |
| | | } |
| | | |
| | | // åå¤æäº¤æ°æ®ï¼maintenanceActuallyTime å ä¸å½åæ¶åç§ |
| | | const submitData = { ...form.value }; |
| | | const { code } = await addMaintenance({ id: id, ...submitData }); |
| | | |
| | | if (code == 200) { |
| | | showToast('æ°å¢ä¿å
»æå'); |
| | | resetFormAndValidate(); |
| | | setTimeout(() => { |
| | | uni.navigateBack(); |
| | | }, 1500); |
| | | } else { |
| | | loading.value = false; |
| | | } |
| | | } catch (e) { |
| | | loading.value = false; |
| | | showToast('æä½å¤±è´¥'); |
| | | } |
| | | }; |
| | | // æ£æ¥åæçtypeåæ®µ |
| | | if (file.type === "image") return true; |
| | | |
| | | // è¿åä¸ä¸é¡µ |
| | | const goBack = () => { |
| | | // æ¸
é¤åå¨çid |
| | | uni.removeStorageSync('repairId'); |
| | | uni.navigateBack(); |
| | | }; |
| | | // æ£æ¥æä»¶æ©å±å |
| | | const name = file.bucketFilename || file.originalFilename || file.name || ""; |
| | | const ext = name.split(".").pop()?.toLowerCase(); |
| | | return ["jpg", "jpeg", "png", "gif", "webp"].includes(ext); |
| | | }; |
| | | |
| | | // è·å页é¢ID |
| | | const getPageId = () => { |
| | | // 仿¬å°åå¨è·åid |
| | | return uni.getStorageSync('repairId'); |
| | | }; |
| | | // æäº¤è¡¨å |
| | | const sendForm = async () => { |
| | | try { |
| | | // æå¨éªè¯è¡¨å |
| | | let isValid = true; |
| | | let errorMessage = ""; |
| | | if (!form.value.maintenanceActuallyName) { |
| | | isValid = false; |
| | | errorMessage = "请è¾å
¥å®é
ä¿å
»äºº"; |
| | | } else if (!form.value.maintenanceActuallyTime) { |
| | | isValid = false; |
| | | errorMessage = "è¯·éæ©å®é
ä¿å
»æ¥æ"; |
| | | } else if (form.value.maintenanceResult === undefined) { |
| | | isValid = false; |
| | | errorMessage = "è¯·éæ©ä¿å
ȍȾ"; |
| | | } else if (uploadFiles.value.length === 0 && form.value.status == "1") { |
| | | isValid = false; |
| | | errorMessage = "请ä¸ä¼ ä¿å
ȍ
§ç"; |
| | | } |
| | | |
| | | // æ¾ç¤ºæ¥æéæ©å¨ |
| | | const showDatePicker = () => { |
| | | showDate.value = true; |
| | | }; |
| | | if (!isValid) { |
| | | showToast(errorMessage); |
| | | return; |
| | | } |
| | | |
| | | // ç¡®è®¤æ¥æéæ© |
| | | const onDateConfirm = (e) => { |
| | | // åªä¿åå¹´ææ¥ï¼ä¸å
嫿¶åç§ |
| | | form.value.maintenanceActuallyTime = dayjs(e.value).format('YYYY-MM-DD HH:mm:ss'); |
| | | showDate.value = false; |
| | | }; |
| | | // éªè¯éè¿ |
| | | submitFormData(); |
| | | } catch (e) { |
| | | showToast("表åéªè¯å¤±è´¥"); |
| | | } |
| | | }; |
| | | |
| | | // æ¾ç¤ºä¿å
»ç»æéæ©å¨ |
| | | const showResultPicker = () => { |
| | | showResult.value = true; |
| | | }; |
| | | // æäº¤è¡¨åæ°æ® |
| | | const submitFormData = async () => { |
| | | try { |
| | | loading.value = true; |
| | | const id = getPageId(); |
| | | |
| | | // 确认ä¿å
»ç»æéæ© |
| | | const onResultConfirm = (selected) => { |
| | | form.value.maintenanceResult = selected.value; |
| | | maintenanceResultText.value = selected.name; |
| | | showResult.value = false; |
| | | }; |
| | | if (!id) { |
| | | showToast("åæ°é误"); |
| | | loading.value = false; |
| | | return; |
| | | } |
| | | // åå¤æäº¤æ°æ®ï¼maintenanceActuallyTime å ä¸å½åæ¶åç§ |
| | | const submitData = { |
| | | ...form.value, |
| | | imagesFile: form.value.status == "1" ? uploadFiles.value : [], |
| | | sparePartsIds: form.sparePartsIds ? form.sparePartsIds.join(",") : "", |
| | | }; |
| | | const { code } = await addMaintenance({ id: id, ...submitData }); |
| | | |
| | | // åå§åè¡¨åæ°æ® |
| | | const initForm = () => { |
| | | // 设置ä¿å
»äººä¸ºå½åç¨æ·æµç§° |
| | | form.value.maintenanceActuallyName = userStore.nickName || ''; |
| | | // 设置å½åæ¥æï¼åªå
å«å¹´ææ¥ï¼ |
| | | form.value.maintenanceActuallyTime = dayjs().format('YYYY-MM-DD HH:mm:ss'); |
| | | currentDate.value = [new Date().getFullYear(), new Date().getMonth() + 1, new Date().getDate()]; |
| | | }; |
| | | if (code == 200) { |
| | | showToast("æ°å¢ä¿å
»æå"); |
| | | resetFormAndValidate(); |
| | | setTimeout(() => { |
| | | uni.navigateBack(); |
| | | }, 1500); |
| | | } else { |
| | | loading.value = false; |
| | | } |
| | | } catch (e) { |
| | | loading.value = false; |
| | | showToast("æä½å¤±è´¥"); |
| | | } |
| | | }; |
| | | |
| | | onShow(() => { |
| | | // 页颿¾ç¤ºæ¶åå§å表å |
| | | initForm(); |
| | | }); |
| | | // è¿åä¸ä¸é¡µ |
| | | const goBack = () => { |
| | | // æ¸
é¤åå¨çidåæ°æ® |
| | | uni.removeStorageSync("repairId"); |
| | | uni.removeStorageSync("upkeepItemData"); |
| | | uni.navigateBack(); |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | // 页é¢å è½½æ¶åå§å表å |
| | | initForm(); |
| | | }); |
| | | // è·å页é¢ID |
| | | const getPageId = () => { |
| | | // 仿¬å°åå¨è·åid |
| | | return uni.getStorageSync("repairId"); |
| | | }; |
| | | |
| | | // è·å设å¤ä¿¡æ¯ |
| | | const getUpkeepItemData = () => { |
| | | try { |
| | | const dataStr = uni.getStorageSync("upkeepItemData"); |
| | | if (!dataStr) { |
| | | return null; |
| | | } |
| | | return JSON.parse(dataStr); |
| | | } catch (e) { |
| | | console.error("è§£æè®¾å¤æ°æ®å¤±è´¥:", e); |
| | | return null; |
| | | } |
| | | }; |
| | | |
| | | // æ¾ç¤ºæ¥æéæ©å¨ |
| | | const showDatePicker = () => { |
| | | showDate.value = true; |
| | | }; |
| | | |
| | | // ç¡®è®¤æ¥æéæ© |
| | | const onDateConfirm = e => { |
| | | // åªä¿åå¹´ææ¥ï¼ä¸å
嫿¶åç§ |
| | | form.value.maintenanceActuallyTime = dayjs(e.value).format( |
| | | "YYYY-MM-DD HH:mm:ss" |
| | | ); |
| | | showDate.value = false; |
| | | }; |
| | | |
| | | // æ¾ç¤ºä¿å
»ç»æéæ©å¨ |
| | | const showResultPicker = () => { |
| | | showResult.value = true; |
| | | }; |
| | | |
| | | // 确认ä¿å
»ç»æéæ© |
| | | const onResultConfirm = selected => { |
| | | form.value.status = selected.value; |
| | | maintenancestatusText.value = selected.name; |
| | | showResult.value = false; |
| | | }; |
| | | |
| | | // æ¾ç¤ºè®¾å¤å¤ä»¶éæ©å¨ |
| | | const showSparePartPicker = () => { |
| | | tempSelectedSpareParts.value = [...selectedSpareParts.value]; |
| | | showSparePart.value = true; |
| | | }; |
| | | |
| | | // æ£æ¥å¤ä»¶æ¯å¦å·²éä¸ |
| | | const isSparePartSelected = value => { |
| | | return tempSelectedSpareParts.value.some(item => item.value === value); |
| | | }; |
| | | |
| | | // 忢å¤ä»¶éä¸ç¶æ |
| | | const toggleSparePartSelection = item => { |
| | | const index = tempSelectedSpareParts.value.findIndex( |
| | | selected => selected.value === item.value |
| | | ); |
| | | if (index > -1) { |
| | | tempSelectedSpareParts.value.splice(index, 1); |
| | | } else { |
| | | tempSelectedSpareParts.value.push(item); |
| | | } |
| | | }; |
| | | |
| | | // 确认å¤ä»¶éæ© |
| | | const confirmSparePartSelection = () => { |
| | | selectedSpareParts.value = [...tempSelectedSpareParts.value]; |
| | | form.value.sparePartsIds = selectedSpareParts.value.map(item => item.value); |
| | | showSparePart.value = false; |
| | | }; |
| | | |
| | | // ç§»é¤å·²éå¤ä»¶ |
| | | const removeSparePart = index => { |
| | | selectedSpareParts.value.splice(index, 1); |
| | | form.value.sparePartsIds = selectedSpareParts.value.map(item => item.value); |
| | | }; |
| | | |
| | | // åå§åè¡¨åæ°æ® |
| | | const initForm = () => { |
| | | // è·å设å¤ä¿¡æ¯ |
| | | const itemData = getUpkeepItemData(); |
| | | |
| | | // éç½®éæ©çå¤ä»¶ |
| | | selectedSpareParts.value = []; |
| | | // éç½®ä¸ä¼ çæä»¶ |
| | | uploadFiles.value = []; |
| | | uploading.value = false; |
| | | uploadProgress.value = 0; |
| | | maintenancestatusText.value = ""; |
| | | |
| | | // 设置ä¿å
»äººä¸ºå½åç¨æ·æµç§° |
| | | form.value.maintenanceActuallyName = userStore.nickName || ""; |
| | | // 设置å½åæ¥æï¼åªå
å«å¹´ææ¥ï¼ |
| | | form.value.maintenanceActuallyTime = dayjs().format("YYYY-MM-DD HH:mm:ss"); |
| | | currentDate.value = [ |
| | | new Date().getFullYear(), |
| | | new Date().getMonth() + 1, |
| | | new Date().getDate(), |
| | | ]; |
| | | |
| | | // 妿æè®¾å¤ä¿¡æ¯ï¼å¡«å
å·²æçä¿å
»æ°æ® |
| | | if (itemData) { |
| | | // å¡«å
å®é
ä¿å
»äºº |
| | | if (itemData.maintenanceActuallyName) { |
| | | form.value.maintenanceActuallyName = itemData.maintenanceActuallyName; |
| | | } |
| | | // å¡«å
ä¿å
ȍȾ |
| | | if ( |
| | | itemData.maintenanceResult !== undefined && |
| | | itemData.maintenanceResult !== null |
| | | ) { |
| | | form.value.maintenanceResult = itemData.maintenanceResult; |
| | | } |
| | | // å¡«å
å®é
ä¿å
»æ¥æ |
| | | if (itemData.maintenanceActuallyTime) { |
| | | form.value.maintenanceActuallyTime = itemData.maintenanceActuallyTime; |
| | | // è§£ææ¥æè®¾ç½®å°æ¥æéæ©å¨ |
| | | const date = dayjs(itemData.maintenanceActuallyTime); |
| | | currentDate.value = [date.year(), date.month() + 1, date.date()]; |
| | | } |
| | | // å¡«å
ä¿å
»ç¶æ |
| | | if (itemData.status) { |
| | | const statusMap = { |
| | | 0: "å¾
ä¿å
»", |
| | | 1: "å®ç»", |
| | | 2: "失败", |
| | | }; |
| | | 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(","); |
| | | } |
| | | // å¡«å
éä»¶æ°æ® |
| | | if (itemData.files && itemData.files.length > 0) { |
| | | uploadFiles.value = itemData.files.map(file => ({ |
| | | id: file.id, |
| | | name: file.name || file.bucketFilename || file.originalFilename, |
| | | url: file.url || file.downloadUrl, |
| | | type: |
| | | file.type || |
| | | (file.contentType && file.contentType.startsWith("image/") |
| | | ? "image" |
| | | : "video"), |
| | | size: file.size || file.byteSize, |
| | | })); |
| | | } else if (itemData.uploadFiles && itemData.uploadFiles.length > 0) { |
| | | uploadFiles.value = itemData.uploadFiles.map(file => ({ |
| | | id: file.id, |
| | | name: file.name || file.bucketFilename || file.originalFilename, |
| | | url: file.url || file.downloadUrl || file.tempFilePath || file.path, |
| | | type: file.type, |
| | | size: file.size, |
| | | })); |
| | | } |
| | | } |
| | | }; |
| | | |
| | | onShow(() => { |
| | | // 页颿¾ç¤ºæ¶åå§å表å |
| | | initForm(); |
| | | fetchSparePartOptions(getPageId()); |
| | | }); |
| | | const sparePartOptions = ref([]); |
| | | const fetchSparePartOptions = deviceLedgerId => { |
| | | getSparePartsOptions({ deviceLedgerId: deviceLedgerId }).then(res => { |
| | | if (res.code == 200) { |
| | | sparePartOptions.value = res.data || []; |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | // æ ¼å¼åæä»¶URL |
| | | const formatFileUrl = url => { |
| | | if (!url) return ""; |
| | | |
| | | // å¦æå·²ç»æ¯å®æ´ç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}`; |
| | | } |
| | | |
| | | // å
¶ä»æ
åµï¼å°è¯ç´æ¥æ¼æ¥ |
| | | return `http://192.168.1.35:8888/profile/${url}`; |
| | | }; |
| | | |
| | | // æ ¼å¼åæä»¶å¤§å° |
| | | const formatFileSize = size => { |
| | | if (!size) return ""; |
| | | if (size < 1024) return size + "B"; |
| | | if (size < 1024 * 1024) return (size / 1024).toFixed(1) + "KB"; |
| | | return (size / (1024 * 1024)).toFixed(1) + "MB"; |
| | | }; |
| | | |
| | | // æç
§/æè§é¢ |
| | | const chooseMedia = type => { |
| | | if (uploadFiles.value.length >= uploadConfig.limit) { |
| | | uni.showToast({ |
| | | title: `æå¤åªè½éæ©${uploadConfig.limit}个æä»¶`, |
| | | icon: "none", |
| | | }); |
| | | return; |
| | | } |
| | | |
| | | const remaining = uploadConfig.limit - uploadFiles.value.length; |
| | | |
| | | // ä¼å
ï¼chooseMediaï¼æ¯æ image/videoï¼ |
| | | if (typeof uni.chooseMedia === "function") { |
| | | uni.chooseMedia({ |
| | | count: Math.min(remaining, 1), |
| | | mediaType: [type || "image"], |
| | | sizeType: ["compressed", "original"], |
| | | sourceType: ["camera"], // æ¯æç¸æºåç¸å |
| | | success: res => { |
| | | try { |
| | | const files = res?.tempFiles || []; |
| | | if (!files.length) throw new Error("æªè·åå°æä»¶"); |
| | | |
| | | files.forEach((tf, idx) => { |
| | | const filePath = tf.tempFilePath || tf.path || ""; |
| | | const fileType = tf.fileType || type || "image"; |
| | | const ext = fileType === "video" ? "mp4" : "jpg"; |
| | | const file = { |
| | | tempFilePath: filePath, |
| | | path: filePath, |
| | | type: fileType, |
| | | name: `${fileType}_${Date.now()}_${idx}.${ext}`, |
| | | size: tf.size || 0, |
| | | duration: tf.duration || 0, |
| | | createTime: Date.now(), |
| | | uid: Date.now() + Math.random() + idx, |
| | | }; |
| | | |
| | | console.log("chooseMedia æåè·åæä»¶:", file); |
| | | handleBeforeUpload(file); |
| | | }); |
| | | } catch (e) { |
| | | console.error("å¤çææç»æå¤±è´¥:", e); |
| | | uni.showToast({ title: "å¤çæä»¶å¤±è´¥", icon: "error" }); |
| | | } |
| | | }, |
| | | fail: err => { |
| | | console.error("ææå¤±è´¥:", err); |
| | | uni.showToast({ title: "ææå¤±è´¥", icon: "error" }); |
| | | }, |
| | | }); |
| | | return; |
| | | } |
| | | |
| | | // é级ï¼chooseImage / chooseVideo |
| | | if (type === "video") { |
| | | uni.chooseVideo({ |
| | | sourceType: ["camera", "album"], |
| | | maxDuration: uploadConfig.maxVideoDuration, |
| | | camera: "back", |
| | | success: res => { |
| | | try { |
| | | if (!res.tempFilePath) { |
| | | throw new Error("æªè·åå°è§é¢æä»¶"); |
| | | } |
| | | |
| | | const file = { |
| | | tempFilePath: res.tempFilePath, |
| | | path: res.tempFilePath, |
| | | type: "video", |
| | | name: `video_${Date.now()}.mp4`, |
| | | size: res.size || 0, |
| | | duration: res.duration || 0, |
| | | createTime: new Date().getTime(), |
| | | uid: Date.now() + Math.random(), |
| | | }; |
| | | |
| | | handleBeforeUpload(file); |
| | | } catch (error) { |
| | | console.error("å¤çæè§é¢ç»æå¤±è´¥:", error); |
| | | uni.showToast({ title: "å¤çè§é¢å¤±è´¥", icon: "error" }); |
| | | } |
| | | }, |
| | | fail: err => { |
| | | console.error("æè§é¢å¤±è´¥:", err); |
| | | uni.showToast({ title: "æè§é¢å¤±è´¥", icon: "error" }); |
| | | }, |
| | | }); |
| | | } else { |
| | | uni.chooseImage({ |
| | | count: 1, |
| | | sizeType: ["compressed", "original"], |
| | | sourceType: ["camera", "album"], |
| | | success: res => { |
| | | const tempFilePath = res?.tempFilePaths?.[0]; |
| | | const tempFile = res?.tempFiles?.[0] || {}; |
| | | if (!tempFilePath) return; |
| | | handleBeforeUpload({ |
| | | tempFilePath, |
| | | path: tempFilePath, |
| | | type: "image", |
| | | name: `photo_${Date.now()}.jpg`, |
| | | size: tempFile.size || 0, |
| | | createTime: Date.now(), |
| | | uid: Date.now() + Math.random(), |
| | | }); |
| | | }, |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | // å 餿件 |
| | | const removeFile = index => { |
| | | uni.showModal({ |
| | | title: "确认å é¤", |
| | | content: "ç¡®å®è¦å é¤è¿ä¸ªæä»¶åï¼", |
| | | success: res => { |
| | | if (res.confirm) { |
| | | uploadFiles.value.splice(index, 1); |
| | | uni.showToast({ |
| | | title: "å 餿å", |
| | | icon: "success", |
| | | }); |
| | | } |
| | | }, |
| | | }); |
| | | }; |
| | | |
| | | // ä¸ä¼ åæ ¡éª |
| | | const handleBeforeUpload = async file => { |
| | | // æ ¡éªæä»¶ç±»å |
| | | if ( |
| | | uploadConfig.fileType && |
| | | Array.isArray(uploadConfig.fileType) && |
| | | uploadConfig.fileType.length > 0 |
| | | ) { |
| | | const fileName = file.name || ""; |
| | | const fileExtension = fileName |
| | | ? fileName.split(".").pop().toLowerCase() |
| | | : ""; |
| | | |
| | | // æ ¹æ®æä»¶ç±»åç¡®å®ææçæ©å±å |
| | | let expectedTypes = []; |
| | | if (file.type === "image") { |
| | | expectedTypes = ["jpg", "jpeg", "png", "gif", "webp"]; |
| | | } else if (file.type === "video") { |
| | | expectedTypes = ["mp4", "mov", "avi", "wmv"]; |
| | | } |
| | | |
| | | // æ£æ¥æä»¶æ©å±åæ¯å¦å¨å
许çç±»åä¸ |
| | | if (fileExtension && expectedTypes.length > 0) { |
| | | const isAllowed = expectedTypes.some( |
| | | type => uploadConfig.fileType.includes(type) && type === fileExtension |
| | | ); |
| | | |
| | | if (!isAllowed) { |
| | | uni.showToast({ |
| | | title: `æä»¶æ ¼å¼ä¸æ¯æï¼è¯·ææ ${expectedTypes.join("/")} æ ¼å¼çæä»¶`, |
| | | icon: "none", |
| | | }); |
| | | return false; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // æ ¡éªéè¿ï¼å¼å§ä¸ä¼ |
| | | uploadFile(file); |
| | | return true; |
| | | }; |
| | | |
| | | // æä»¶ä¸ä¼ å¤ç |
| | | const uploadFile = async file => { |
| | | uploading.value = true; |
| | | uploadProgress.value = 0; |
| | | number.value++; |
| | | |
| | | // ç¡®ä¿tokenåå¨ |
| | | const token = userStore.token; |
| | | if (!token) { |
| | | handleUploadError("ç¨æ·æªç»å½"); |
| | | return; |
| | | } |
| | | |
| | | uploadWithUniUploadFile(file, file.tempFilePath || file.path || "", token); |
| | | }; |
| | | |
| | | // 使ç¨uni.uploadFileä¸ä¼ |
| | | const uploadWithUniUploadFile = (file, filePath, token) => { |
| | | if (!filePath) { |
| | | handleUploadError("æä»¶è·¯å¾ä¸åå¨"); |
| | | return; |
| | | } |
| | | |
| | | const uploadTask = uni.uploadFile({ |
| | | url: uploadFileUrl.value, |
| | | filePath: filePath, |
| | | name: "file", |
| | | formData: { |
| | | type: 10, // ä¿å
»éä»¶ç±»å |
| | | }, |
| | | header: { |
| | | Authorization: `Bearer ${token}`, |
| | | }, |
| | | success: res => { |
| | | try { |
| | | if (res.statusCode === 200) { |
| | | const response = JSON.parse(res.data); |
| | | if (response.code === 200) { |
| | | handleUploadSuccess(response, file); |
| | | uni.showToast({ |
| | | title: "ä¸ä¼ æå", |
| | | icon: "success", |
| | | }); |
| | | } else { |
| | | handleUploadError(response.msg || "æå¡å¨è¿åé误"); |
| | | } |
| | | } else { |
| | | handleUploadError(`æå¡å¨é误ï¼ç¶æç : ${res.statusCode}`); |
| | | } |
| | | } catch (e) { |
| | | console.error("è§£æååºå¤±è´¥:", e); |
| | | console.error("åå§ååºæ°æ®:", res.data); |
| | | handleUploadError("ååºæ°æ®è§£æå¤±è´¥: " + e.message); |
| | | } |
| | | }, |
| | | fail: err => { |
| | | console.error("ä¸ä¼ 失败:", err.errMsg || err); |
| | | number.value--; |
| | | |
| | | let errorMessage = "ä¸ä¼ 失败"; |
| | | if (err.errMsg) { |
| | | if (err.errMsg.includes("statusCode: null")) { |
| | | errorMessage = "ç½ç»è¿æ¥å¤±è´¥ï¼è¯·æ£æ¥ç½ç»è®¾ç½®"; |
| | | } else if (err.errMsg.includes("timeout")) { |
| | | errorMessage = "ä¸ä¼ è¶
æ¶ï¼è¯·éè¯"; |
| | | } else if (err.errMsg.includes("fail")) { |
| | | errorMessage = "ä¸ä¼ 失败ï¼è¯·æ£æ¥ç½ç»è¿æ¥"; |
| | | } else { |
| | | errorMessage = err.errMsg; |
| | | } |
| | | } |
| | | |
| | | handleUploadError(errorMessage); |
| | | }, |
| | | complete: () => { |
| | | uploading.value = false; |
| | | uploadProgress.value = 0; |
| | | }, |
| | | }); |
| | | |
| | | // çå¬ä¸ä¼ è¿åº¦ |
| | | if (uploadTask && uploadTask.onProgressUpdate) { |
| | | uploadTask.onProgressUpdate(res => { |
| | | uploadProgress.value = res.progress; |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | // ä¸ä¼ æåå¤ç |
| | | const handleUploadSuccess = (res, file) => { |
| | | console.log("ä¸ä¼ æåååº:", res); |
| | | |
| | | // å¤çä¸åçæ°æ®ç»æï¼å¯è½æ¯æ°ç»ï¼ä¹å¯è½æ¯å个对象 |
| | | let uploadedFile = null; |
| | | uploadedFile = res.data; |
| | | |
| | | if (!uploadedFile) { |
| | | console.error("æ æ³è§£æä¸ä¼ ååºæ°æ®:", res); |
| | | number.value--; |
| | | handleUploadError("ä¸ä¼ ååºæ°æ®æ ¼å¼é误", false); |
| | | return; |
| | | } |
| | | console.log("ä¸ä¼ æåæä»¶æ°æ®:", uploadedFile, file); |
| | | |
| | | // ç¡®ä¿ä¸ä¼ çæä»¶æ°æ®å®æ´ï¼å
å«idåtype |
| | | const fileData = { |
| | | name: uploadedFile.originalName, |
| | | type: file.type, |
| | | url: uploadedFile.tempPath, |
| | | }; |
| | | |
| | | uploadFiles.value.push(fileData); |
| | | number.value = 0; |
| | | }; |
| | | |
| | | // ä¸ä¼ 失败å¤ç |
| | | const handleUploadError = (message = "ä¸ä¼ æä»¶å¤±è´¥", showRetry = false) => { |
| | | uploading.value = false; |
| | | uploadProgress.value = 0; |
| | | |
| | | if (showRetry) { |
| | | uni.showModal({ |
| | | title: "ä¸ä¼ 失败", |
| | | content: message + "ï¼æ¯å¦éè¯ï¼", |
| | | success: res => { |
| | | if (res.confirm) { |
| | | // ç¨æ·éæ©éè¯ï¼è¿éå¯ä»¥éæ°è§¦åä¸ä¼ |
| | | } |
| | | }, |
| | | }); |
| | | } else { |
| | | uni.showToast({ |
| | | title: message, |
| | | icon: "error", |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | // 页é¢å è½½æ¶åå§å表å |
| | | initForm(); |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | @import '@/static/scss/form-common.scss'; |
| | | .upkeep-maintain { |
| | | min-height: 100vh; |
| | | background: #f8f9fa; |
| | | padding-bottom: 5rem; |
| | | } |
| | | @import "@/static/scss/form-common.scss"; |
| | | .upkeep-maintain { |
| | | min-height: 100vh; |
| | | background: #f8f9fa; |
| | | padding-bottom: 5rem; |
| | | } |
| | | |
| | | .footer-btns { |
| | | position: fixed; |
| | | left: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | background: #fff; |
| | | display: flex; |
| | | justify-content: space-around; |
| | | align-items: center; |
| | | padding: 0.75rem 0; |
| | | box-shadow: 0 -0.125rem 0.5rem rgba(0,0,0,0.05); |
| | | z-index: 1000; |
| | | } |
| | | .footer-btns { |
| | | position: fixed; |
| | | left: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | background: #fff; |
| | | display: flex; |
| | | justify-content: space-around; |
| | | align-items: center; |
| | | padding: 0.75rem 0; |
| | | box-shadow: 0 -0.125rem 0.5rem rgba(0, 0, 0, 0.05); |
| | | z-index: 1000; |
| | | } |
| | | |
| | | .cancel-btn { |
| | | font-weight: 400; |
| | | font-size: 1rem; |
| | | color: #FFFFFF; |
| | | width: 6.375rem; |
| | | background: #C7C9CC; |
| | | box-shadow: 0 0.25rem 0.625rem 0 rgba(3,88,185,0.2); |
| | | border-radius: 2.5rem 2.5rem 2.5rem 2.5rem; |
| | | } |
| | | .cancel-btn { |
| | | font-weight: 400; |
| | | font-size: 1rem; |
| | | color: #ffffff; |
| | | width: 6.375rem; |
| | | background: #c7c9cc; |
| | | box-shadow: 0 0.25rem 0.625rem 0 rgba(3, 88, 185, 0.2); |
| | | border-radius: 2.5rem 2.5rem 2.5rem 2.5rem; |
| | | } |
| | | |
| | | .save-btn { |
| | | font-weight: 400; |
| | | font-size: 1rem; |
| | | color: #FFFFFF; |
| | | width: 14rem; |
| | | background: linear-gradient( 140deg, #00BAFF 0%, #006CFB 100%); |
| | | box-shadow: 0 0.25rem 0.625rem 0 rgba(3,88,185,0.2); |
| | | border-radius: 2.5rem 2.5rem 2.5rem 2.5rem; |
| | | } |
| | | .save-btn { |
| | | font-weight: 400; |
| | | font-size: 1rem; |
| | | color: #ffffff; |
| | | width: 14rem; |
| | | background: linear-gradient(140deg, #00baff 0%, #006cfb 100%); |
| | | box-shadow: 0 0.25rem 0.625rem 0 rgba(3, 88, 185, 0.2); |
| | | border-radius: 2.5rem 2.5rem 2.5rem 2.5rem; |
| | | } |
| | | |
| | | // ååºå¼è°æ´ |
| | | @media (max-width: 768px) { |
| | | .submit-section { |
| | | padding: 12px; |
| | | } |
| | | } |
| | | // ååºå¼è°æ´ |
| | | @media (max-width: 768px) { |
| | | .submit-section { |
| | | padding: 12px; |
| | | } |
| | | } |
| | | |
| | | .tip-text { |
| | | padding: 4px 16px 0 16px; |
| | | font-size: 12px; |
| | | color: #888; |
| | | } |
| | | .tip-text { |
| | | padding: 4px 16px 0 16px; |
| | | font-size: 12px; |
| | | color: #888; |
| | | } |
| | | |
| | | /* 设å¤å¤ä»¶å¤éæ ·å¼ */ |
| | | .spare-parts-container { |
| | | flex: 1; |
| | | min-height: 40px; |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | .spare-parts-list { |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | gap: 8px; |
| | | } |
| | | |
| | | .spare-part-tag { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 4px; |
| | | background: #2c7be5; |
| | | color: #fff; |
| | | padding: 4px 8px; |
| | | border-radius: 4px; |
| | | font-size: 12px; |
| | | } |
| | | |
| | | .placeholder { |
| | | color: #c0c4cc; |
| | | font-size: 14px; |
| | | } |
| | | |
| | | /* å¤ä»¶éæ©å¼¹çªæ ·å¼ */ |
| | | .spare-part-popup { |
| | | padding: 16px; |
| | | max-height: 60vh; |
| | | display: flex; |
| | | flex-direction: column; |
| | | } |
| | | |
| | | .popup-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | margin-bottom: 16px; |
| | | padding-bottom: 12px; |
| | | border-bottom: 1px solid #e8e8e8; |
| | | } |
| | | |
| | | .popup-title { |
| | | font-size: 16px; |
| | | font-weight: 600; |
| | | color: #333; |
| | | } |
| | | |
| | | .spare-part-options { |
| | | flex: 1; |
| | | overflow-y: auto; |
| | | } |
| | | |
| | | .spare-part-option { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | padding: 12px 0; |
| | | border-bottom: 1px solid #f0f0f0; |
| | | font-size: 14px; |
| | | color: #333; |
| | | } |
| | | |
| | | .spare-part-option.selected { |
| | | color: #2c7be5; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | /* æä»¶ä¸ä¼ æ ·å¼ */ |
| | | .simple-upload-area { |
| | | width: 100%; |
| | | } |
| | | |
| | | .upload-buttons { |
| | | display: flex; |
| | | margin-bottom: 12px; |
| | | } |
| | | |
| | | .upload-progress { |
| | | margin: 12px 0; |
| | | } |
| | | |
| | | .file-list { |
| | | margin-top: 12px; |
| | | } |
| | | |
| | | .file-item { |
| | | display: flex; |
| | | align-items: center; |
| | | margin-bottom: 12px; |
| | | padding: 10px; |
| | | background: #f8f9fa; |
| | | border-radius: 8px; |
| | | } |
| | | |
| | | .file-preview-container { |
| | | position: relative; |
| | | margin-right: 12px; |
| | | } |
| | | |
| | | .file-preview { |
| | | width: 80px; |
| | | height: 80px; |
| | | border-radius: 4px; |
| | | } |
| | | |
| | | .video-preview { |
| | | width: 80px; |
| | | height: 80px; |
| | | background: #333; |
| | | border-radius: 4px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | color: #fff; |
| | | font-size: 12px; |
| | | } |
| | | |
| | | .delete-btn { |
| | | position: absolute; |
| | | top: -8px; |
| | | right: -8px; |
| | | width: 20px; |
| | | height: 20px; |
| | | background: #f56c6c; |
| | | border-radius: 50%; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | } |
| | | |
| | | .file-info { |
| | | flex: 1; |
| | | } |
| | | |
| | | .file-name { |
| | | display: block; |
| | | font-size: 14px; |
| | | color: #333; |
| | | margin-bottom: 4px; |
| | | line-height: 1.4; |
| | | } |
| | | |
| | | .file-size { |
| | | font-size: 12px; |
| | | color: #999; |
| | | } |
| | | |
| | | .empty-state { |
| | | padding: 20px 0; |
| | | text-align: center; |
| | | color: #999; |
| | | font-size: 14px; |
| | | } |
| | | </style> |