| | |
| | | <script setup lang="ts"> |
| | | import { onLaunch, onShow, onHide } from "@dcloudio/uni-app"; |
| | | import { useThemeStore } from "@/store"; |
| | | import { ref } from "vue"; |
| | | |
| | | // 主é¢åå§å |
| | | const themeStore = useThemeStore(); |
| | | |
| | | // å
¨å±æ«ç å¹¿ææ¥æ¶å¨ |
| | | let main: any = null; |
| | | let receiver: any = null; |
| | | let filter: any = null; |
| | | |
| | | // åå§åæ«ç å¹¿ææ¥æ¶ |
| | | const initGlobalScan = () => { |
| | | // #ifdef APP-PLUS |
| | | try { |
| | | main = plus.android.runtimeMainActivity(); |
| | | const IntentFilter = plus.android.importClass("android.content.IntentFilter"); |
| | | filter = new IntentFilter(); |
| | | filter.addAction("com.dwexample.ACTION"); |
| | | |
| | | receiver = plus.android.implements("io.dcloud.feature.internal.reflect.BroadcastReceiver", { |
| | | onReceive: (context: any, intent: any) => { |
| | | console.log("ð [å
¨å±Scan] onReceive 触å:", context, intent); |
| | | plus.android.importClass(intent); |
| | | const scanResult = intent.getStringExtra("com.motorolasolutions.emdk.datawedge.data_string"); |
| | | console.log("ð [å
¨å±Scan] æ«æç»æ:", scanResult); |
| | | |
| | | // åéå°ææå¯è½çäºä»¶ |
| | | const eventNames = ["scan", "scanIndex", "scanJX", "scanLS"]; |
| | | eventNames.forEach((eventName) => { |
| | | uni.$emit(eventName, { code: scanResult }); |
| | | console.log(`ð [å
¨å±Scan] å·²åé ${eventName} äºä»¶`); |
| | | }); |
| | | }, |
| | | }); |
| | | |
| | | // 注åå¹¿ææ¥æ¶å¨ |
| | | main.registerReceiver(receiver, filter); |
| | | console.log("ð [å
¨å±Scan] å
¨å±æ«ç å¹¿ææ¥æ¶å¨å·²å¯å¨"); |
| | | } catch (error) { |
| | | console.error("ð [å
¨å±Scan] åå§å失败:", error); |
| | | } |
| | | // #endif |
| | | }; |
| | | |
| | | // 忢æ«ç å¹¿ææ¥æ¶ |
| | | const stopGlobalScan = () => { |
| | | // #ifdef APP-PLUS |
| | | try { |
| | | if (main && receiver) { |
| | | main.unregisterReceiver(receiver); |
| | | console.log("ð [å
¨å±Scan] å
¨å±æ«ç å¹¿ææ¥æ¶å¨å·²åæ¢"); |
| | | } |
| | | } catch (error) { |
| | | console.error("ð [å
¨å±Scan] åæ¢å¤±è´¥:", error); |
| | | } |
| | | // #endif |
| | | }; |
| | | |
| | | onLaunch(() => { |
| | | console.log("App Launch"); |
| | | // åå§åä¸»é¢ |
| | | themeStore.initTheme(); |
| | | // åå§åå
¨å±æ«ç å¹¿ææ¥æ¶å¨ |
| | | initGlobalScan(); |
| | | }); |
| | | |
| | | onShow(() => { |
| | | console.log("App Show"); |
| | | // åºç¨æ¾ç¤ºæ¶éæ°å¯å¨å¹¿ææ¥æ¶å¨ |
| | | initGlobalScan(); |
| | | }); |
| | | |
| | | onHide(() => { |
| | | console.log("App Hide"); |
| | | // åºç¨éèæ¶ä¸åæ¢å¹¿æï¼ä¿æåå°æ¥æ¶ï¼ |
| | | }); |
| | | </script> |
| | | |
| | |
| | | data: data, |
| | | }); |
| | | }, |
| | | |
| | | // éªè¯äºç»´ç |
| | | assertScanQR(params: { deviceUid: string }) { |
| | | return request<BaseResult<any>>({ |
| | | url: "/wireInspection/assertScanQR?deviceUid=" + params.deviceUid, |
| | | method: "GET", |
| | | }); |
| | | }, |
| | | }; |
| | | |
| | | export default RoutingInspectionApi; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import { ref, computed, onUnmounted } from "vue"; |
| | | import { onShow, onHide } from "@dcloudio/uni-app"; |
| | | import RoutingInspectionApi from "@/api/routingInspection/routingInspection"; |
| | | |
| | | /** |
| | | * æ«ç æ°æ®æ¥å£ |
| | | */ |
| | | interface ScanCodeData { |
| | | uid?: string; |
| | | deviceModel?: string; |
| | | [key: string]: any; |
| | | } |
| | | |
| | | // å
¨å±çå¬å¨ç¶ææ å°ï¼ç¡®ä¿æ¯ä¸ªäºä»¶ååªæä¸ä¸ªçå¬å¨ï¼ |
| | | const globalListeners = new Map<string, boolean>(); |
| | | |
| | | // æ·»å ä¸ä¸ªå
¨å±çæè·æææ«ç äºä»¶ççå¬å¨ï¼ç¨äºè°è¯ï¼ |
| | | let debugListenerInitialized = false; |
| | | |
| | | const initDebugListener = () => { |
| | | if (debugListenerInitialized) return; |
| | | |
| | | // ç嬿æå¯è½çæ«ç äºä»¶ |
| | | const eventNames = ["scan", "scanIndex", "scanJX", "scanLS"]; |
| | | eventNames.forEach((eventName) => { |
| | | uni.$on(eventName, (data: any) => { |
| | | console.log(`ð [å
¨å±è°è¯] æè·å° ${eventName} äºä»¶:`, data); |
| | | }); |
| | | }); |
| | | |
| | | debugListenerInitialized = true; |
| | | console.log("ð [å
¨å±è°è¯] è°è¯çå¬å¨å·²åå§å"); |
| | | }; |
| | | |
| | | /** |
| | | * æ«ç 管ç Composable |
| | | * ç»ä¸ç®¡çæ«ç äºä»¶çå¬ãç¼ååå¨åæ°æ®è¯»å |
| | | * å
¨å±çå¬å¨ï¼ä¸é页é¢åæ¢èå
³é |
| | | * @param eventName çå¬çäºä»¶åç§°ï¼é»è®¤ä¸º "scan" |
| | | */ |
| | | export function useScanCode(eventName: string = "scan") { |
| | | // å½åæ«ç çè®¾å¤ UID |
| | | const deviceUid = ref<string>(""); |
| | | // å½åæ«ç çæºå°åå· |
| | | const deviceModel = ref<string>(""); |
| | | // 宿´çæ«ç æ°æ® |
| | | const scanData = ref<ScanCodeData>({}); |
| | | // ä¿åäºä»¶åç§° |
| | | const currentEventName = eventName; |
| | | |
| | | /** |
| | | * 仿¬å°ç¼åå è½½æ«ç æ°æ® |
| | | */ |
| | | const loadFromCache = () => { |
| | | try { |
| | | const cachedData = uni.getStorageSync("scanCodeData"); |
| | | if (cachedData) { |
| | | scanData.value = cachedData; |
| | | deviceUid.value = cachedData.uid || ""; |
| | | deviceModel.value = cachedData.deviceModel || ""; |
| | | console.log("[useScanCode] ä»ç¼åå è½½æ«ç æ°æ®:", cachedData); |
| | | return cachedData; |
| | | } |
| | | } catch (error) { |
| | | console.error("[useScanCode] 读åç¼å失败:", error); |
| | | } |
| | | return null; |
| | | }; |
| | | |
| | | /** |
| | | * ä¿åæ«ç æ°æ®å°ç¼å |
| | | */ |
| | | const saveToCache = (data: ScanCodeData) => { |
| | | try { |
| | | uni.setStorageSync("scanCodeData", data); |
| | | console.log("[useScanCode] å·²ä¿åå°ç¼å:", data); |
| | | return true; |
| | | } catch (error) { |
| | | console.error("[useScanCode] ä¿åç¼å失败:", error); |
| | | return false; |
| | | } |
| | | }; |
| | | |
| | | /** |
| | | * æ¸
空æ«ç æ°æ®åç¼å |
| | | */ |
| | | const clearScanData = () => { |
| | | try { |
| | | uni.removeStorageSync("scanCodeData"); |
| | | deviceUid.value = ""; |
| | | deviceModel.value = ""; |
| | | scanData.value = {}; |
| | | console.log("[useScanCode] å·²æ¸
空æ«ç æ°æ®"); |
| | | } catch (error) { |
| | | console.error("[useScanCode] æ¸
空ç¼å失败:", error); |
| | | } |
| | | }; |
| | | |
| | | /** |
| | | * éªè¯äºç»´ç ï¼ä»
è°ç¨æ¥å£ï¼ä¸å¤çè¿åç»æï¼ |
| | | */ |
| | | const validateQRCode = async (uid: string): Promise<void> => { |
| | | try { |
| | | console.log("[useScanCode] è°ç¨éªè¯äºç»´ç æ¥å£, deviceUid:", uid); |
| | | await RoutingInspectionApi.assertScanQR({ deviceUid: uid }); |
| | | console.log("[useScanCode] éªè¯æ¥å£è°ç¨å®æ"); |
| | | } catch (error: any) { |
| | | console.error("[useScanCode] éªè¯æ¥å£è°ç¨å¼å¸¸:", error); |
| | | // å³ä½¿å¼å¸¸ä¹ä¸å½±ååç»æµç¨ |
| | | } |
| | | }; |
| | | |
| | | /** |
| | | * å¤çæ«ç äºä»¶ |
| | | */ |
| | | const handleScanEvent = async (params: any) => { |
| | | console.log(`========== [useScanCode][${currentEventName}] æ¶å°æ«ç äºä»¶ ==========`); |
| | | console.log(`[useScanCode][${currentEventName}] æ¥æ¶åæ°:`, params); |
| | | console.log(`[useScanCode][${currentEventName}] è§¦åæ¶é´:`, new Date().toLocaleTimeString()); |
| | | |
| | | try { |
| | | if (!params?.code) { |
| | | console.warn("[useScanCode] æ«ç å
容为空"); |
| | | return; |
| | | } |
| | | |
| | | let codeObj: ScanCodeData = {}; |
| | | try { |
| | | codeObj = JSON.parse(params.code); |
| | | console.log("[useScanCode] è§£æåç对象:", codeObj); |
| | | } catch (err) { |
| | | console.error("[useScanCode] JSON è§£æå¤±è´¥:", err); |
| | | console.log("[useScanCode] åå§å符串:", params.code); |
| | | // 妿䏿¯ JSONï¼å°è¯ä½ä¸ºæ®éå符串å¤ç |
| | | codeObj = { code: params.code }; |
| | | } |
| | | |
| | | // æ£æ¥æ¯å¦æå¿
è¦çåæ®µï¼uid æ deviceModelï¼ |
| | | if (!codeObj.uid && !codeObj.deviceModel) { |
| | | console.warn("[useScanCode] æ«ç æ°æ®ç¼ºå° uid å deviceModelï¼ä¸ä¿åç¼å"); |
| | | uni.showToast({ |
| | | title: "æ«ç æ°æ®æ æ", |
| | | icon: "none", |
| | | }); |
| | | return; |
| | | } |
| | | |
| | | // æ´æ°æ¬å°ç¶æ |
| | | scanData.value = codeObj; |
| | | deviceUid.value = codeObj.uid || ""; |
| | | deviceModel.value = codeObj.deviceModel || ""; |
| | | |
| | | // ä¿åå°ç¼å |
| | | saveToCache(codeObj); |
| | | |
| | | // 妿æ uidï¼è°ç¨éªè¯æ¥å£ï¼ä¸çå¾
ç»æï¼ |
| | | if (codeObj.uid) { |
| | | validateQRCode(codeObj.uid); |
| | | } |
| | | |
| | | // æ¾ç¤ºæåæç¤º |
| | | uni.showToast({ |
| | | title: "æ«ç æå", |
| | | icon: "success", |
| | | }); |
| | | |
| | | console.log("[useScanCode] æ«ç æ°æ®å·²æ´æ°:", { |
| | | uid: deviceUid.value, |
| | | deviceModel: deviceModel.value, |
| | | }); |
| | | } catch (error) { |
| | | console.error("[useScanCode] å¤çæ«ç æ°æ®å¼å¸¸:", error); |
| | | } |
| | | }; |
| | | |
| | | /** |
| | | * å¯ç¨æ«ç çå¬ï¼å
¨å±ï¼æ¯æ¬¡é½éæ°æ³¨åä»¥ç¡®ä¿ææï¼ |
| | | */ |
| | | const enableListener = () => { |
| | | // å
ç§»é¤å¯è½åå¨çæ§çå¬å¨ |
| | | uni.$off(currentEventName, handleScanEvent); |
| | | // æ·»å æ°ççå¬å¨ |
| | | uni.$on(currentEventName, handleScanEvent); |
| | | // æ 记为å
¨å±å·²å¯ç¨ |
| | | globalListeners.set(currentEventName, true); |
| | | console.log( |
| | | `[useScanCode][${currentEventName}] â
å
¨å±çå¬å¨å·²å¯ç¨/å·æ°ï¼ä¸ä¼é页é¢åæ¢å
³éï¼` |
| | | ); |
| | | }; |
| | | |
| | | /** |
| | | * ç¦ç¨æ«ç çå¬ï¼ä»
ç¨äºåºç¨éåºæ¶æ¸
çï¼æ£å¸¸é¡µé¢åæ¢ä¸è°ç¨ï¼ |
| | | */ |
| | | const disableListener = () => { |
| | | if (!globalListeners.get(currentEventName)) { |
| | | console.log(`[useScanCode][${currentEventName}] çå¬å¨æªå¯ç¨ï¼è·³è¿`); |
| | | return; |
| | | } |
| | | |
| | | uni.$off(currentEventName, handleScanEvent); |
| | | globalListeners.delete(currentEventName); |
| | | console.log(`[useScanCode][${currentEventName}] â å
¨å±çå¬å¨å·²ç¦ç¨`); |
| | | }; |
| | | |
| | | /** |
| | | * 设置页é¢çå½å¨æé©åï¼å
¨å±çå¬å¨æ¨¡å¼ï¼ |
| | | * çå¬å¨å
¨å±å¯ç¨ä¸æ¬¡ï¼ä¸é页é¢åæ¢å
³é |
| | | * @param options é
ç½®é项 |
| | | */ |
| | | const setupLifecycle = ( |
| | | options: { |
| | | loadCacheOnShow?: boolean; // æ¯å¦å¨ onShow æ¶å è½½ç¼å |
| | | } = {} |
| | | ) => { |
| | | const { loadCacheOnShow = true } = options; |
| | | |
| | | // åªå¨ onShow æ¶å è½½ç¼åï¼ä¸ç¦ç¨çå¬å¨ |
| | | if (loadCacheOnShow) { |
| | | onShow(() => { |
| | | console.log(`[useScanCode][${currentEventName}] onShow 触å`); |
| | | loadFromCache(); |
| | | }); |
| | | } |
| | | |
| | | // 注æï¼ä¸åå¨ onHide å onUnmounted ä¸ç¦ç¨çå¬å¨ |
| | | // çå¬å¨ä¿æå
¨å±æ¿æ´»ç¶æ |
| | | }; |
| | | |
| | | // 页é¢å è½½æ¶èªå¨ä»ç¼å读å |
| | | loadFromCache(); |
| | | |
| | | return { |
| | | // ç¶æ |
| | | deviceUid, |
| | | deviceModel, |
| | | scanData, |
| | | // 计ç®å±æ§ |
| | | hasScanned: computed(() => !!deviceUid.value), |
| | | displayText: computed(() => deviceModel.value || "æªæ«ç "), |
| | | // æ¹æ³ |
| | | loadFromCache, |
| | | saveToCache, |
| | | clearScanData, |
| | | validateQRCode, |
| | | enableListener, |
| | | disableListener, |
| | | setupLifecycle, |
| | | }; |
| | | } |
| | |
| | | ä¿å |
| | | </wd-button> |
| | | <view class="placeholder"></view> |
| | | <view class="scan-info"> |
| | | <text class="scan-device-text">å½åæ«ç æºå°: {{ scannedDeviceModel || "æªæ«ç " }}</text> |
| | | </view> |
| | | <view class="scan-wrapper" @click="openScan"> |
| | | <wd-icon name="scan" size="24px" color="#0D867F"></wd-icon> |
| | | </view> |
| | |
| | | <wd-form-item label="ç产é¿åº¦" prop="actuallyLength"> |
| | | {{ formatValue(recordData.fixedInfo?.actuallyLength, "m") }} |
| | | </wd-form-item> |
| | | <wd-form-item label="å¼ å设置" prop="twistTension"> |
| | | {{ formatValue(recordData.fixedInfo?.twistTension, "N/m") }} |
| | | <wd-form-item label="å¼ å设置" prop="tensionSetting"> |
| | | {{ formatValue(recordData.fixedInfo?.tensionSetting, "N/m") }} |
| | | </wd-form-item> |
| | | <!-- ç»å¶å¤å¾ï¼å¯ç¼è¾ï¼ --> |
| | | <wd-form-item label="ç»å¶å¤å¾" prop="twistDiameter" required> |
| | | <wd-form-item label="ç»åå¤å¾" prop="twistedOuterDiameter" required> |
| | | <template v-if="isEdit"> |
| | | <wd-input |
| | | v-model="formData.twistDiameter" |
| | | placeholder="请è¾å
¥ç»å¶å¤å¾ï¼mmï¼" |
| | | v-model="formData.twistedOuterDiameter" |
| | | placeholder="请è¾å
¥ç»åå¤å¾ï¼mmï¼" |
| | | type="number" |
| | | /> |
| | | </template> |
| | | <template v-else> |
| | | {{ formatValue(formData.twistDiameter, "mm") }} |
| | | {{ formatValue(formData.twistedOuterDiameter, "mm") }} |
| | | </template> |
| | | </wd-form-item> |
| | | </wd-col> |
| | |
| | | </wd-form-item> |
| | | <wd-form-item label="èè·" prop="pitch" required> |
| | | <template v-if="isEdit"> |
| | | <wd-input v-model="item.pitch" placeholder="请è¾å
¥èè·ï¼mmï¼" type="number" /> |
| | | <wd-input |
| | | v-model="item.pitch" |
| | | placeholder="请è¾å
¥èè·ï¼mmï¼" |
| | | type="number" |
| | | @input="updatePitchRatio(item)" |
| | | /> |
| | | </template> |
| | | <template v-else> |
| | | {{ formatValue(item.pitch, "mm") }} |
| | |
| | | <wd-col :span="24"> |
| | | <wd-form-item label="产åå¤è§" prop="productAppearance" required> |
| | | <template v-if="isEdit"> |
| | | <wd-checkbox-group |
| | | v-model="formData.productAppearance" |
| | | inline |
| | | v-for="(opt, idx) in appearanceOptions" |
| | | :key="idx" |
| | | style="text-align: justify" |
| | | > |
| | | <wd-checkbox :modelValue="opt.value" style="width: 100px"> |
| | | <view style="display: flex; flex-wrap: wrap; gap: 10px"> |
| | | <wd-checkbox |
| | | v-for="(opt, idx) in appearanceOptions" |
| | | :key="idx" |
| | | :value="opt.value" |
| | | :modelValue="formData.productAppearance.includes(opt.value)" |
| | | @click="handleAppearanceClick(opt.value)" |
| | | style="width: 100px" |
| | | > |
| | | {{ opt.label }} |
| | | </wd-checkbox> |
| | | </wd-checkbox-group> |
| | | </view> |
| | | </template> |
| | | <template v-else> |
| | | {{ formatProductAppearance(formData.productAppearance) }} |
| | |
| | | <img :src="previewImageUrl" alt="é¢è§å¾ç" style="width: 100%; height: auto" /> |
| | | </div> |
| | | </wd-popup> |
| | | <Scan ref="scanRef" emitName="scan" /> |
| | | <wd-toast /> |
| | | </view> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { ref, reactive, computed } from "vue"; |
| | | import { onLoad } from "@dcloudio/uni-app"; |
| | | import { ref, reactive, computed, onUnmounted } from "vue"; |
| | | import { onLoad, onShow, onHide } from "@dcloudio/uni-app"; |
| | | import RoutingInspectionApi from "@/api/routingInspection/routingInspection"; |
| | | import Scan from "@/components/scan/index.vue"; |
| | | import { useToast } from "wot-design-uni"; |
| | | import AttachmentUpload from "../upload.vue"; |
| | | import { useUserStore } from "@/store/modules/user"; |
| | | import { useScanCode } from "@/composables/useScanCode"; |
| | | |
| | | const paramsType = ref(""); |
| | | const paramsId = ref(""); |
| | |
| | | const previewImageUrl = ref(""); |
| | | const isEdit = ref(false); |
| | | const tempFiles = ref<any[]>([]); // 临æ¶å卿°ä¸ä¼ çéä»¶ |
| | | const deviceUid = ref(""); |
| | | const scanRef = ref(); |
| | | const toast = useToast(); |
| | | const attachmentRef = ref<any>(null); |
| | | const detailData = reactive<any>({}); |
| | | const detailDataLoaded = ref(false); |
| | | |
| | | // è·åå½åç»å½ç¨æ·ä¿¡æ¯ |
| | | const userStore = useUserStore(); |
| | | const userInfo: any = computed(() => userStore.userInfo); |
| | | |
| | | // ä½¿ç¨æ«ç 管ç composableï¼å
¨å±çå¬å¨ï¼ä¸é页é¢åæ¢å
³éï¼ |
| | | const { |
| | | deviceUid, |
| | | deviceModel: scannedDeviceModel, |
| | | loadFromCache, |
| | | enableListener, |
| | | } = useScanCode("scanJX"); |
| | | |
| | | const formData = reactive({ |
| | | twistDiameter: "", // ç»å¶å¤å¾ |
| | | twistedOuterDiameter: "", // ç»å¶å¤å¾ |
| | | structureFormula: "", // æåç»æ |
| | | structureItems: [], // ç»ææ åå¼å宿µ |
| | | inspectTwist: [], // ç»çº¿å·¥èºè´¨éæ§å¶ |
| | |
| | | const structureResult = recordData.value.structureInfo?.structureRecordResult || {}; |
| | | const inspectionResult = recordData.value.inspectionResult || {}; |
| | | |
| | | formData.twistDiameter = inspectionResult.twistDiameter || ""; |
| | | formData.twistedOuterDiameter = |
| | | recordData.value.structureInfo.structureRecordResult.twistedOuterDiameter || ""; |
| | | formData.structureFormula = structureResult.inspectStructure?.structureFormula || ""; |
| | | formData.sampleComplete = inspectionResult.sampleComplete || ""; |
| | | formData.conclusion = structureResult.conclusion || ""; |
| | | formData.productAppearance = Array.isArray(structureResult.productAppearance) |
| | | |
| | | // åå§å产åå¤è§ |
| | | const appearance = Array.isArray(structureResult.productAppearance) |
| | | ? structureResult.productAppearance |
| | | : structureResult.productAppearance |
| | | ? [structureResult.productAppearance] |
| | | : []; |
| | | ? [structureResult.productAppearance] |
| | | : []; |
| | | formData.productAppearance = appearance; |
| | | |
| | | formData.structureItems = JSON.parse( |
| | | JSON.stringify(structureResult.inspectStructure?.structureItems || []) |
| | |
| | | const response = await RoutingInspectionApi.getStrandedInspectionStructureInfoById({ id }); |
| | | recordData.value = response.data; |
| | | detailData.value = response.data.structureInfo; |
| | | |
| | | // å¦æè®°å½äººä¸ºç©ºï¼é»è®¤è®¾ç½®ä¸ºå½åç»å½ç¨æ· |
| | | if (recordData.value.structureInfo && !recordData.value.structureInfo.createUserName) { |
| | | recordData.value.structureInfo.createUserName = |
| | | userInfo.value?.nickName || userInfo.value?.userName || ""; |
| | | } |
| | | |
| | | console.log("detailData.value", detailData.value); |
| | | tempFiles.value = []; // æ¸
ç©ºä¸´æ¶æä»¶ |
| | | initFormData(); // æ°æ®è¿åååå§å表å |
| | |
| | | const saveList = async () => { |
| | | // 1. åºç¡åæ®µæ ¡éª |
| | | if (!formData.structureFormula) return uni.showToast({ title: "æåç»æä¸ºå¿
填项", icon: "none" }); |
| | | if (!formData.twistDiameter) return uni.showToast({ title: "ç»å¶å¤å¾ä¸ºå¿
填项", icon: "none" }); |
| | | if (!formData.twistedOuterDiameter) |
| | | return uni.showToast({ title: "ç»å¶å¤å¾ä¸ºå¿
填项", icon: "none" }); |
| | | if (!formData.productAppearance.length) |
| | | return uni.showToast({ title: "产åå¤è§ä¸ºå¿
填项", icon: "none" }); |
| | | if (!formData.conclusion) return uni.showToast({ title: "ç»è®ºä¸ºå¿
填项", icon: "none" }); |
| | |
| | | if (!item.pitchRatio) |
| | | return uni.showToast({ title: `${item.twistName}è徿¯ä¸ºå¿
填项`, icon: "none" }); |
| | | } |
| | | console.log("1111", deviceUid.value); |
| | | if (!deviceUid.value) return uni.showToast({ title: "è¯·æ«æäºç»´ç ", icon: "none" }); |
| | | // éªè¯æ«ç æ°æ®ï¼ä»ç¼åææ°æ«ç è·åï¼ |
| | | console.log("ä¿ååæ£æ¥ deviceUid:", deviceUid.value); |
| | | if (!deviceUid.value) { |
| | | return uni.showToast({ |
| | | title: "请å
æ«æè®¾å¤äºç»´ç ", |
| | | icon: "none", |
| | | duration: 2000, |
| | | }); |
| | | } |
| | | const { newFiles } = attachmentRef.value.getSubmitFiles(); |
| | | console.log("newFiles", newFiles); |
| | | const allFileIds = [...newFiles]; |
| | |
| | | deviceUid: deviceUid.value, |
| | | id: paramsId.value, |
| | | result: { |
| | | twistDiameter: formData.twistDiameter, |
| | | twistedOuterDiameter: formData.twistedOuterDiameter, |
| | | structureFormula: formData.structureFormula, |
| | | structureItems: formData.structureItems, |
| | | inspectTwist: formData.inspectTwist, |
| | |
| | | }); |
| | | |
| | | if (res.code === 200) { |
| | | uni.showToast({ title: "ä¿åæå", icon: "success" }); |
| | | isEdit.value = false; |
| | | getDetailData(paramsId.value, paramsType.value); |
| | | // è®¾ç½®å·æ°æ è®°ï¼åè¯å表页éè¦å·æ° |
| | | uni.setStorageSync("needRefreshInspectionList", true); |
| | | |
| | | uni.showToast({ |
| | | title: "ä¿åæå", |
| | | icon: "success", |
| | | duration: 1500, |
| | | }); |
| | | // å»¶è¿è¿åå表页ï¼è®©ç¨æ·çå°æåæç¤º |
| | | setTimeout(() => { |
| | | uni.navigateBack({ |
| | | delta: 1, |
| | | }); |
| | | }, 1500); |
| | | } else { |
| | | uni.showModal({ title: res.msg || "ä¿å失败", icon: "error" }); |
| | | } |
| | |
| | | case 1: |
| | | return "danger"; // 已驳å |
| | | case 2: |
| | | return "info"; // å¾
å®¡æ ¸ |
| | | return "primary"; // å¾
å®¡æ ¸ |
| | | case 3: |
| | | return "success"; // éè¿ |
| | | default: |
| | | return "info"; |
| | | return "default"; |
| | | } |
| | | }; |
| | | |
| | |
| | | }); |
| | | }; |
| | | |
| | | const openScan = () => { |
| | | scanRef.value.triggerScan(); |
| | | // 计ç®è徿¯ |
| | | const calculatePitchRatio = (pitch: string, dia: string) => { |
| | | // 妿pitchædia为空ï¼åè¿å"-" |
| | | if (!pitch || !dia) return "-"; |
| | | |
| | | // å°pitchådia转æ¢ä¸ºæµ®ç¹æ° |
| | | const pitchNum = parseFloat(pitch); |
| | | const diaNum = parseFloat(dia); |
| | | |
| | | // 妿pitchNumædiaNumæ¯NaNï¼æè
diaNum为0ï¼åè¿å"-" |
| | | if (isNaN(pitchNum) || isNaN(diaNum) || diaNum === 0) return "-"; |
| | | |
| | | // 计ç®pitchNumådiaNumçæ¯å¼ï¼å¹¶ä¿ç两ä½å°æ° |
| | | return (pitchNum / diaNum).toFixed(2); |
| | | }; |
| | | const getScanCode = (params: any) => { |
| | | console.log("宿´åæ°ï¼", params); |
| | | let codeObj = {}; |
| | | try { |
| | | codeObj = JSON.parse(params.code); |
| | | } catch (err) { |
| | | console.error("JSONè§£æå¤±è´¥ï¼", err); |
| | | toast.error("æ«ç æ°æ®å¼å¸¸"); |
| | | return; |
| | | |
| | | // æ´æ°è徿¯ï¼å½èè·ååæ¶èªå¨è®¡ç®ï¼ |
| | | const updatePitchRatio = (item: any) => { |
| | | // 使ç¨ç»åå¤å¾ä½ä¸ºç´å¾æ¥è®¡ç®è徿¯ |
| | | const dia = item.dia; |
| | | item.pitchRatio = calculatePitchRatio(item.pitch, dia); |
| | | }; |
| | | |
| | | // å¤ç产åå¤è§éæ©çäºæ¥é»è¾ |
| | | const handleAppearanceClick = (value: string) => { |
| | | const currentValues = [...formData.productAppearance]; |
| | | const isCurrentlyChecked = currentValues.includes(value); |
| | | |
| | | let newSelection: string[] = []; |
| | | |
| | | if (value === "æ å¤è§é®é¢") { |
| | | if (isCurrentlyChecked) { |
| | | // åæ¶éä¸"æ å¤è§é®é¢" |
| | | newSelection = []; |
| | | } else { |
| | | // éä¸"æ å¤è§é®é¢"ï¼æ¸
空å
¶ä»é项 |
| | | newSelection = ["æ å¤è§é®é¢"]; |
| | | } |
| | | } else { |
| | | // ç¹å»å
¶ä»é项 |
| | | if (isCurrentlyChecked) { |
| | | // åæ¶éä¸è¯¥é项 |
| | | newSelection = currentValues.filter((v) => v !== value); |
| | | } else { |
| | | // éä¸è¯¥é项ï¼ç§»é¤"æ å¤è§é®é¢" |
| | | const filteredValues = currentValues.filter((v) => v !== "æ å¤è§é®é¢"); |
| | | newSelection = [...filteredValues, value]; |
| | | } |
| | | } |
| | | deviceUid.value = codeObj?.uid; |
| | | toast.success("æ«ç æå"); |
| | | |
| | | formData.productAppearance = newSelection; |
| | | }; |
| | | // ç¡®ä¿å
ç§»é¤åæ·»å çå¬ |
| | | const setupScanListener = () => { |
| | | uni.$off("scan", getScanCode); // å
ç§»é¤æ§ç |
| | | uni.$on("scan", getScanCode); // åæ·»å æ°ç |
| | | |
| | | const openScan = () => { |
| | | console.log("indexJX - ç¹å»æ«ç æé®ï¼å
¨å±æ«ç 模å¼ï¼æ éæå¨è§¦åï¼"); |
| | | // å
¨å±æ«ç 模å¼ä¸ï¼ç¡¬ä»¶æ«ç ä¼èªå¨è§¦åï¼æ éæå¨è°ç¨ |
| | | uni.showToast({ |
| | | title: "è¯·ä½¿ç¨æ«ç æªæ«æ", |
| | | icon: "none", |
| | | }); |
| | | }; |
| | | onUnmounted(() => { |
| | | // å¼å¯å¹¿æçå¬äºä»¶ |
| | | uni.$off("scan", getScanCode); |
| | | console.log("离å¼1"); |
| | | }); |
| | | onMounted(() => { |
| | | // å¼å¯å¹¿æçå¬äºä»¶ |
| | | setupScanListener(); |
| | | console.log("æ¾ç¤º1"); |
| | | |
| | | // 页颿¾ç¤ºæ¶çå¤ç |
| | | onShow(() => { |
| | | console.log("========== indexJX - onShow 触å =========="); |
| | | // éæ°å¯ç¨çå¬å¨ï¼ç¡®ä¿çå¬å¨ææï¼ |
| | | enableListener(); |
| | | // å è½½ç¼åï¼æ´æ°UIæ¾ç¤ºï¼ |
| | | const cachedData = loadFromCache(); |
| | | |
| | | // å¦ææ²¡æç¼åæ°æ®ï¼æç¤ºç¨æ·éè¦æ«ç |
| | | if (!cachedData || !cachedData.uid) { |
| | | console.log("â ï¸ æªæ£æµå°æ«ç ç¼åï¼ç¨æ·éè¦æ«æè®¾å¤äºç»´ç "); |
| | | // å¨ç¼è¾æ¨¡å¼ä¸ææç¤º |
| | | if (isEdit.value) { |
| | | setTimeout(() => { |
| | | uni.showToast({ |
| | | title: "è¯·æ«æè®¾å¤äºç»´ç ååä¿å", |
| | | icon: "none", |
| | | duration: 2000, |
| | | }); |
| | | }, 500); |
| | | } |
| | | } |
| | | }); |
| | | </script> |
| | | |
| | |
| | | flex: 1; |
| | | } |
| | | |
| | | .scan-info { |
| | | display: flex; |
| | | align-items: center; |
| | | margin-right: 10px; |
| | | |
| | | .scan-device-text { |
| | | font-size: 14px; |
| | | color: #0d867f; |
| | | font-weight: 500; |
| | | } |
| | | } |
| | | |
| | | .scan-wrapper { |
| | | width: 38px; |
| | | height: 38px; |
| | |
| | | ä¿å |
| | | </wd-button> |
| | | <view class="placeholder"></view> |
| | | <view class="scan-info"> |
| | | <text class="scan-device-text">å½åæ«ç æºå°: {{ scannedDeviceModel || "æªæ«ç " }}</text> |
| | | </view> |
| | | <view class="scan-wrapper" @click="openScan"> |
| | | <wd-icon name="scan" size="24px" color="#0D867F"></wd-icon> |
| | | </view> |
| | |
| | | |
| | | <wd-form-item label="å¤è§" prop="appearance" required> |
| | | <template v-if="isEdit"> |
| | | <wd-checkbox-group |
| | | v-model="formData.appearance" |
| | | inline |
| | | v-for="(opt, idx) in appearanceOptions" |
| | | :key="idx" |
| | | style="text-align: justify" |
| | | > |
| | | <wd-checkbox :modelValue="opt.value" style="width: 100px"> |
| | | <view style="display: flex; flex-wrap: wrap; gap: 10px"> |
| | | <wd-checkbox |
| | | v-for="(opt, idx) in appearanceOptions" |
| | | :key="idx" |
| | | :value="opt.value" |
| | | :modelValue="formData.appearance?.includes(opt.value) || false" |
| | | @click="handleAppearanceClick(opt.value)" |
| | | style="width: 100px" |
| | | > |
| | | {{ opt.label }} |
| | | </wd-checkbox> |
| | | </wd-checkbox-group> |
| | | </view> |
| | | </template> |
| | | <template v-else> |
| | | {{ formatProductAppearance(formData.appearance) }} |
| | |
| | | <img :src="previewImageUrl" alt="é¢è§å¾ç" style="width: 100%; height: auto" /> |
| | | </div> |
| | | </wd-popup> |
| | | <Scan ref="scanRef" emitName="scan" /> |
| | | <wd-toast /> |
| | | </view> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { ref, reactive } from "vue"; |
| | | import { onLoad } from "@dcloudio/uni-app"; |
| | | import { ref, reactive, computed, onUnmounted } from "vue"; |
| | | import { onLoad, onShow, onHide } from "@dcloudio/uni-app"; |
| | | import RoutingInspectionApi from "@/api/routingInspection/routingInspection"; |
| | | import Scan from "@/components/scan/index.vue"; |
| | | import { useToast } from "wot-design-uni"; |
| | | import AttachmentUpload from "../upload.vue"; |
| | | import { useUserStore } from "@/store/modules/user"; |
| | | import { useScanCode } from "@/composables/useScanCode"; |
| | | |
| | | // æ ¸å¿ç¶æ |
| | | const paramsId = ref(""); |
| | |
| | | const previewImageUrl = ref(""); |
| | | const isEdit = ref(false); |
| | | const tempFiles = ref<any[]>([]); |
| | | const deviceUid = ref(""); |
| | | const scanRef = ref(); |
| | | const toast = useToast(); |
| | | const attachmentRef = ref<any>(null); |
| | | |
| | | // è·åå½åç»å½ç¨æ·ä¿¡æ¯ |
| | | const userStore = useUserStore(); |
| | | const userInfo: any = computed(() => userStore.userInfo); |
| | | |
| | | // ä½¿ç¨æ«ç 管ç composableï¼å
¨å±çå¬å¨ï¼ä¸é页é¢åæ¢å
³éï¼ |
| | | const { |
| | | deviceUid, |
| | | deviceModel: scannedDeviceModel, |
| | | loadFromCache, |
| | | enableListener, |
| | | } = useScanCode("scanLS"); |
| | | |
| | | // è¡¨åæ°æ® |
| | | const formData = reactive({ |
| | | dia: "", |
| | | maxDia: "", |
| | | minDia: "", |
| | | appearance: [], |
| | | appearance: [] as string[], |
| | | windingTightness: "", |
| | | arrangementNeatness: "", |
| | | aluminumWireDistance: "", |
| | |
| | | case 1: |
| | | return "danger"; |
| | | case 2: |
| | | return "info"; |
| | | return "primary"; |
| | | case 3: |
| | | return "success"; |
| | | default: |
| | | return "info"; |
| | | return "default"; |
| | | } |
| | | }; |
| | | |
| | |
| | | |
| | | // æ ¼å¼åå·¥å
· |
| | | const formatProductAppearance = (productAppearance: string[]) => { |
| | | return !productAppearance.length ? "-" : productAppearance.join("ã"); |
| | | if (!productAppearance || !Array.isArray(productAppearance) || !productAppearance.length) { |
| | | return "-"; |
| | | } |
| | | return productAppearance.join("ã"); |
| | | }; |
| | | |
| | | // å¤çå¤è§éæ©çäºæ¥é»è¾ |
| | | const handleAppearanceClick = (value: string) => { |
| | | // ç¡®ä¿ appearance æ¯æ°ç» |
| | | if (!Array.isArray(formData.appearance)) { |
| | | formData.appearance = []; |
| | | } |
| | | |
| | | const currentValues = [...formData.appearance]; |
| | | const isCurrentlyChecked = currentValues.includes(value); |
| | | |
| | | let newSelection: string[] = []; |
| | | |
| | | if (value === "æ å¤è§é®é¢") { |
| | | if (isCurrentlyChecked) { |
| | | // åæ¶éä¸"æ å¤è§é®é¢" |
| | | newSelection = []; |
| | | } else { |
| | | // éä¸"æ å¤è§é®é¢"ï¼æ¸
空å
¶ä»é项 |
| | | newSelection = ["æ å¤è§é®é¢"]; |
| | | } |
| | | } else { |
| | | // ç¹å»å
¶ä»é项 |
| | | if (isCurrentlyChecked) { |
| | | // åæ¶éä¸è¯¥é项 |
| | | newSelection = currentValues.filter((v) => v !== value); |
| | | } else { |
| | | // éä¸è¯¥é项ï¼ç§»é¤"æ å¤è§é®é¢" |
| | | const filteredValues = currentValues.filter((v) => v !== "æ å¤è§é®é¢"); |
| | | newSelection = [...filteredValues, value]; |
| | | } |
| | | } |
| | | |
| | | formData.appearance = newSelection; |
| | | }; |
| | | |
| | | const formatValue = (value: any, unit?: string) => { |
| | |
| | | formData.dia = inspectionResult.dia || ""; |
| | | formData.maxDia = inspectionResult.maxDia || ""; |
| | | formData.minDia = inspectionResult.minDia || ""; |
| | | formData.appearance = inspectionResult.appearance || []; |
| | | // ç¡®ä¿ appearance æ¯æ°ç» |
| | | formData.appearance = Array.isArray(inspectionResult.appearance) |
| | | ? inspectionResult.appearance |
| | | : inspectionResult.appearance |
| | | ? [inspectionResult.appearance] |
| | | : []; |
| | | formData.windingTightness = inspectionResult.windingTightness || ""; |
| | | formData.arrangementNeatness = inspectionResult.arrangementNeatness || ""; |
| | | formData.aluminumWireDistance = inspectionResult.aluminumWireDistance || ""; |
| | |
| | | try { |
| | | const response = await RoutingInspectionApi.getDrawInspectInfoById({ id }); |
| | | detailData.value = response.data; |
| | | |
| | | // 妿巡æ£å为空ï¼é»è®¤è®¾ç½®ä¸ºå½åç»å½ç¨æ· |
| | | if (!detailData.value.processInspectionUserName) { |
| | | detailData.value.processInspectionUserName = |
| | | userInfo.value?.nickName || userInfo.value?.userName || ""; |
| | | } |
| | | |
| | | tempFiles.value = []; |
| | | initFormData(); |
| | | } catch (error) { |
| | |
| | | return uni.showToast({ title: "æåæ¨¡åæ¥å¤´æ
åµä¸ºå¿
填项", icon: "none" }); |
| | | if (!formData.conclusion) return uni.showToast({ title: "ç»è®ºä¸ºå¿
填项", icon: "none" }); |
| | | if (!formData.isFully) return uni.showToast({ title: "éææ ·åæ¯å¦é½å
¨ä¸ºå¿
填项", icon: "none" }); |
| | | if (!deviceUid.value) return uni.showToast({ title: "è¯·æ«æäºç»´ç ", icon: "none" }); |
| | | |
| | | // éªè¯æ«ç æ°æ®ï¼ä»ç¼åææ°æ«ç è·åï¼ |
| | | console.log("ä¿ååæ£æ¥ deviceUid:", deviceUid.value); |
| | | if (!deviceUid.value) { |
| | | return uni.showToast({ |
| | | title: "请å
æ«æè®¾å¤äºç»´ç ", |
| | | icon: "none", |
| | | duration: 2000, |
| | | }); |
| | | } |
| | | const { newFiles } = attachmentRef.value.getSubmitFiles(); |
| | | console.log("newFiles", newFiles); |
| | | const allFileIds = [...newFiles]; |
| | |
| | | processInspectionAttachmentList: allFileIds, |
| | | }); |
| | | if (res.code === 200) { |
| | | uni.showToast({ title: "ä¿åæå", icon: "success" }); |
| | | isEdit.value = false; |
| | | getDetailData(paramsId.value, paramsType.value); |
| | | // è®¾ç½®å·æ°æ è®°ï¼åè¯å表页éè¦å·æ° |
| | | uni.setStorageSync("needRefreshInspectionList", true); |
| | | |
| | | uni.showToast({ |
| | | title: "ä¿åæå", |
| | | icon: "success", |
| | | duration: 1500, |
| | | }); |
| | | // å»¶è¿è¿åå表页ï¼è®©ç¨æ·çå°æåæç¤º |
| | | setTimeout(() => { |
| | | uni.navigateBack({ |
| | | delta: 1, |
| | | }); |
| | | }, 1500); |
| | | } else { |
| | | uni.showModal({ title: res.msg || "ä¿å失败", icon: "error" }); |
| | | } |
| | |
| | | }; |
| | | |
| | | const openScan = () => { |
| | | scanRef.value.triggerScan(); |
| | | console.log("indexLS - ç¹å»æ«ç æé®ï¼å
¨å±æ«ç 模å¼ï¼æ éæå¨è§¦åï¼"); |
| | | // å
¨å±æ«ç 模å¼ä¸ï¼ç¡¬ä»¶æ«ç ä¼èªå¨è§¦åï¼æ éæå¨è°ç¨ |
| | | uni.showToast({ |
| | | title: "è¯·ä½¿ç¨æ«ç æªæ«æ", |
| | | icon: "none", |
| | | }); |
| | | }; |
| | | const getScanCode = (params: any) => { |
| | | let codeObj = {}; |
| | | try { |
| | | codeObj = JSON.parse(params.code); |
| | | } catch (err) { |
| | | toast.error("æ«ç æ°æ®å¼å¸¸"); |
| | | return; // è§£æå¤±è´¥ç´æ¥è¿åï¼é¿å
åç»é误 |
| | | |
| | | // 页颿¾ç¤ºæ¶çå¤ç |
| | | onShow(() => { |
| | | console.log("========== indexLS - onShow 触å =========="); |
| | | // éæ°å¯ç¨çå¬å¨ï¼ç¡®ä¿çå¬å¨ææï¼ |
| | | enableListener(); |
| | | // å è½½ç¼åï¼æ´æ°UIæ¾ç¤ºï¼ |
| | | const cachedData = loadFromCache(); |
| | | |
| | | // å¦ææ²¡æç¼åæ°æ®ï¼æç¤ºç¨æ·éè¦æ«ç |
| | | if (!cachedData || !cachedData.uid) { |
| | | console.log("â ï¸ æªæ£æµå°æ«ç ç¼åï¼ç¨æ·éè¦æ«æè®¾å¤äºç»´ç "); |
| | | // å¨ç¼è¾æ¨¡å¼ä¸ææç¤º |
| | | if (isEdit.value) { |
| | | setTimeout(() => { |
| | | uni.showToast({ |
| | | title: "è¯·æ«æè®¾å¤äºç»´ç ååä¿å", |
| | | icon: "none", |
| | | duration: 2000, |
| | | }); |
| | | }, 500); |
| | | } |
| | | } |
| | | deviceUid.value = codeObj?.uid; |
| | | toast.success("æ«ç æå"); |
| | | }; |
| | | // ç¡®ä¿å
ç§»é¤åæ·»å çå¬ |
| | | const setupScanListener = () => { |
| | | uni.$off("scan", getScanCode); // å
ç§»é¤æ§ç |
| | | uni.$on("scan", getScanCode); // åæ·»å æ°ç |
| | | }; |
| | | onUnmounted(() => { |
| | | // å¼å¯å¹¿æçå¬äºä»¶ |
| | | uni.$off("scan", getScanCode); |
| | | console.log("离å¼1"); |
| | | }); |
| | | onMounted(() => { |
| | | // å¼å¯å¹¿æçå¬äºä»¶ |
| | | setupScanListener(); |
| | | console.log("æ¾ç¤º1"); |
| | | }); |
| | | </script> |
| | | |
| | |
| | | |
| | | .placeholder { |
| | | flex: 1; |
| | | } |
| | | |
| | | .scan-info { |
| | | display: flex; |
| | | align-items: center; |
| | | margin-right: 10px; |
| | | |
| | | .scan-device-text { |
| | | font-size: 14px; |
| | | color: #0d867f; |
| | | font-weight: 500; |
| | | } |
| | | } |
| | | |
| | | .scan-wrapper { |
| | |
| | | align-items: flex-start; // åç´æ¹åé¡¶é¨å¯¹é½ï¼ä¸ç§»å
³é®ï¼ |
| | | gap: 20rpx; // é项ä¹é´çé´è· |
| | | } |
| | | </style> |
| | | </style> |
| | |
| | | <view> |
| | | <wd-row> |
| | | <wd-col :span="21"> |
| | | <wd-search placeholder-left hide-cancel></wd-search> |
| | | <wd-search |
| | | v-model="searchKeyword" |
| | | placeholder="请è¾å
¥çç»åç§°" |
| | | placeholder-left |
| | | hide-cancel |
| | | @search="handleSearch" |
| | | @clear="handleClear" |
| | | ></wd-search> |
| | | </wd-col> |
| | | <wd-col :span="3"> |
| | | <view class="scan_box" @click="openScan"> |
| | |
| | | :title="`${item.deviceModel}ï¼å¾
æ£æ¥${item.pendingNum}æ¡ï¼`" |
| | | class="tab_bg" |
| | | > |
| | | <ProductList :api="RoutingInspectionApi.getInspectListByPatrol" :ProList="item" /> |
| | | <ProductList |
| | | :key="searchKey" |
| | | :api="RoutingInspectionApi.getInspectListByPatrol" |
| | | :ProList="{ ...item, teamName: searchKeyword }" |
| | | /> |
| | | </wd-tab> |
| | | </wd-tabs> |
| | | <Scan ref="scanRef" emitName="scan" /> |
| | | <wd-toast /> |
| | | </view> |
| | | </template> |
| | | |
| | | <script lang="ts" setup> |
| | | import { ref, reactive, computed, onMounted, onUnmounted } from "vue"; |
| | | import { onShow, onHide } from "@dcloudio/uni-app"; |
| | | import ProductList from "./list/index.vue"; |
| | | import Scan from "@/components/scan/index.vue"; |
| | | import { useUserStore } from "@/store/modules/user"; |
| | | import reportApi from "@/api/work/report"; |
| | | import { useToast } from "wot-design-uni"; |
| | | import RoutingInspectionApi from "@/api/routingInspection/routingInspection"; |
| | | import { useScanCode } from "@/composables/useScanCode"; |
| | | |
| | | const scanRef = ref(); |
| | | const userStore = useUserStore(); |
| | | const userInfo: any = computed(() => userStore.userInfo); |
| | | const toast = useToast(); |
| | | const tab = ref<number>(0); |
| | | const patrolList = ref<any[]>([]); // å·¡æ£è®¾å¤åè¡¨æ°æ® |
| | | const searchKeyword = ref<string>(""); // æç´¢å
³é®è¯ï¼çç»åç§°ï¼ |
| | | const searchKey = ref<number>(0); // ç¨äºå¼ºå¶å·æ°å表 |
| | | |
| | | // ä½¿ç¨æ«ç 管ç composableï¼å
¨å±çå¬å¨ï¼ä¸é页é¢åæ¢å
³éï¼ |
| | | const { deviceUid, deviceModel, hasScanned, displayText, loadFromCache, enableListener } = |
| | | useScanCode("scanIndex"); |
| | | |
| | | const handlePatrolData = (index: number, count: number) => { |
| | | // å¯ä»¥å¨è¿éæ´æ°ç¹å®å·¡æ£è®¾å¤çå¾
æ£æ¥æ°é |
| | | // ä¾å¦ï¼patrolList.value[index].pendingNum = count; |
| | | }; |
| | | |
| | | // å¤çæç´¢ |
| | | const handleSearch = (value: string) => { |
| | | console.log("æç´¢çç»:", value); |
| | | searchKey.value++; // æ´æ° key 强å¶å·æ°å表 |
| | | }; |
| | | |
| | | // å¤çæ¸
空æç´¢ |
| | | const handleClear = () => { |
| | | console.log("æ¸
空æç´¢"); |
| | | searchKeyword.value = ""; |
| | | searchKey.value++; // æ´æ° key 强å¶å·æ°å表 |
| | | }; |
| | | |
| | | const openScan = () => { |
| | | scanRef.value.triggerScan(); |
| | | }; |
| | | |
| | | const getScanCode = async () => { |
| | | const { code } = await reportApi.sendWorkTime({ |
| | | userName: userInfo.value.userName, |
| | | console.log("index.vue - ç¹å»æ«ç æé®ï¼å
¨å±æ«ç 模å¼ï¼æ éæå¨è§¦åï¼"); |
| | | // å
¨å±æ«ç 模å¼ä¸ï¼ç¡¬ä»¶æ«ç ä¼èªå¨è§¦åï¼æ éæå¨è°ç¨ |
| | | uni.showToast({ |
| | | title: "è¯·ä½¿ç¨æ«ç æªæ«æ", |
| | | icon: "none", |
| | | }); |
| | | if (code == 200) { |
| | | toast.success("æ«ç æå"); |
| | | } |
| | | }; |
| | | |
| | | // è·åç¹å®å·¡æ£è®¾å¤çæ°æ® |
| | | const getPatrolData = (item: any) => { |
| | | return async (params: any) => { |
| | | // è¿éå¯ä»¥æ ¹æ®itemä¸çä¿¡æ¯è°ç¨ç¸åºçæ¥å£è·å详æ
|
| | | // è¿åçæ°æ®æ ¼å¼éè¦ä¸ProductListç»ä»¶ææçæ ¼å¼ä¸è´ |
| | | return { |
| | | code: 200, |
| | | data: { |
| | | type: "å·¡æ£", |
| | | data: { |
| | | total: 0, |
| | | records: [], |
| | | }, |
| | | }, |
| | | }; |
| | | }; |
| | | }; |
| | | |
| | | // è·åå·¡æ£è®¾å¤å表 |
| | |
| | | } |
| | | }; |
| | | |
| | | // ç¡®ä¿å
ç§»é¤åæ·»å çå¬ |
| | | const setupScanListener = () => { |
| | | uni.$off("scan", getScanCode); // å
ç§»é¤æ§ç |
| | | uni.$on("scan", getScanCode); // åæ·»å æ°ç |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | // å¼å¯å¹¿æçå¬äºä»¶ |
| | | setupScanListener(); |
| | | console.log("æ¾ç¤º1"); |
| | | // 页é¢å è½½æ¶è·åå·¡æ£è®¾å¤å表 |
| | | loadPatrolList(); |
| | | // å¯ç¨å
¨å±çå¬å¨ |
| | | enableListener(); |
| | | console.log("index.vue - onMounted"); |
| | | }); |
| | | |
| | | onUnmounted(() => { |
| | | // å¼å¯å¹¿æçå¬äºä»¶ |
| | | uni.$off("scan", getScanCode); |
| | | console.log("离å¼1"); |
| | | onShow(() => { |
| | | console.log("========== index.vue - onShow 触å =========="); |
| | | // 页颿¾ç¤ºæ¶éæ°å¯ç¨çå¬å¨ï¼ç¡®ä¿çå¬å¨ææï¼ |
| | | enableListener(); |
| | | // å è½½ç¼åï¼æ´æ°UIæ¾ç¤ºï¼ |
| | | loadFromCache(); |
| | | |
| | | // æ£æ¥æ¯å¦éè¦å·æ°å表ï¼åªææäº¤æååæå·æ°ï¼ |
| | | const needRefresh = uni.getStorageSync("needRefreshInspectionList"); |
| | | if (needRefresh) { |
| | | console.log("æ£æµå°éè¦å·æ°å表ï¼å¼å§å·æ°..."); |
| | | // éæ°å 载巡æ£è®¾å¤å表ï¼å·æ°å¾
æ£æ¥æ°éï¼ |
| | | loadPatrolList(); |
| | | // 强å¶å·æ° ProductList ç»ä»¶ |
| | | searchKey.value++; |
| | | // æ¸
é¤å·æ°æ è®° |
| | | uni.removeStorageSync("needRefreshInspectionList"); |
| | | } |
| | | }); |
| | | </script> |
| | | |
| | |
| | | .statistics_box { |
| | | margin: 15px; |
| | | } |
| | | </style> |
| | | </style> |
| | |
| | | <template> |
| | | <view class="card_box"> |
| | | <z-paging ref="pagingRef" v-model="list" :fixed="false" :auto-show-back-to-top="true" @query="getList"> |
| | | <ProductCard v-for="(item, index) in list" :key="index" :data="item" :map="map" |
| | | @click="toDetail(item.id, item.deviceType)" /> |
| | | </z-paging> |
| | | <wd-toast /> |
| | | </view> |
| | | <view class="card_box"> |
| | | <z-paging |
| | | ref="pagingRef" |
| | | v-model="list" |
| | | :fixed="false" |
| | | :auto-show-back-to-top="true" |
| | | @query="getList" |
| | | > |
| | | <ProductCard |
| | | v-for="(item, index) in list" |
| | | :key="index" |
| | | :data="item" |
| | | :map="map" |
| | | @click="toDetail(item.id, item.deviceType)" |
| | | /> |
| | | </z-paging> |
| | | <wd-toast /> |
| | | </view> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import ProductCard from "../product_card/index.vue"; |
| | | import { useUserStore } from "@/store/modules/user"; |
| | | import zPaging from "@/components/z-paging/z-paging.vue"; |
| | | import { useToast } from "wot-design-uni"; |
| | | import ProductCard from "../product_card/index.vue"; |
| | | import { useUserStore } from "@/store/modules/user"; |
| | | import zPaging from "@/components/z-paging/z-paging.vue"; |
| | | import { useToast } from "wot-design-uni"; |
| | | |
| | | const toast = useToast(); |
| | | const userStore = useUserStore(); |
| | | const userInfo : any = computed(() => userStore.userInfo); |
| | | const pagingRef = ref(); |
| | | const toast = useToast(); |
| | | const userStore = useUserStore(); |
| | | const userInfo: any = computed(() => userStore.userInfo); |
| | | const pagingRef = ref(); |
| | | const map = reactive({ |
| | | deviceModel: "deviceModel", |
| | | model: "model", |
| | | firstNo: "firstNo", |
| | | recordDate: "recordDate", |
| | | workShift: "workShift", |
| | | teamName: "teamName", |
| | | poleModel: "poleModel", |
| | | poleNumber: "poleNumber", |
| | | outputNumber: "outputNumber", |
| | | inspectPerson: "inspectPerson", |
| | | status: "status", |
| | | rejectList: [ |
| | | deviceModel: "deviceModel", |
| | | model: "model", |
| | | firstNo: "firstNo", |
| | | recordDate: "recordDate", |
| | | workShift: "workShift", |
| | | teamName: "teamName", |
| | | poleModel: "poleModel", |
| | | poleNumber: "poleNumber", |
| | | outputNumber: "outputNumber", |
| | | inspectPerson: "inspectPerson", |
| | | status: "status", |
| | | productType: "productType", |
| | | recordPosition: "recordPosition", |
| | | rejectList: [ |
| | | { |
| | | rejectPerson: "rejectPerson", |
| | | rejectTime: "rejectTime", |
| | | rejectReason: { |
| | | reason: "reason", |
| | | }, |
| | | }, |
| | | ], // æ¹ä¸ºå¯¹è±¡ï¼å
嫿éçåµå¥å±æ§ |
| | | }); |
| | | const props = defineProps({ |
| | | api: { |
| | | type: Function, |
| | | default: () => {}, |
| | | }, |
| | | ProList: { |
| | | type: Object, |
| | | default: () => {}, |
| | | }, |
| | | }); |
| | | |
| | | const list = ref<any[]>([]); |
| | | |
| | | const toDetail = (id: number, deviceType: number) => { |
| | | console.log("ç¹å»å¡ç", id, deviceType); |
| | | if (deviceType == 1) { |
| | | // ç»çº¿ |
| | | uni.navigateTo({ |
| | | url: `/pages/routingInspection/detail/indexJX?id=${id}&deviceType=${deviceType}`, |
| | | }); |
| | | } else if (deviceType == 0) { |
| | | // æä¸ |
| | | uni.navigateTo({ |
| | | url: `/pages/routingInspection/detail/indexLS?id=${id}&deviceType=${deviceType}`, |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | const getList = async (pageNo = 1, pageSize = 10) => { |
| | | const { code, data } = await props.api({ |
| | | deviceModel: props.ProList.deviceModel, |
| | | status: "0", |
| | | deviceType: props.ProList.deviceType, |
| | | teamName: props.ProList.teamName || "", // çç»åç§°æç´¢ |
| | | current: pageNo, |
| | | size: pageSize, |
| | | }); |
| | | if (code == 200) { |
| | | map.deviceModel = "deviceModel"; |
| | | map.model = "model"; |
| | | map.firstNo = "firstNo"; |
| | | map.recordDate = "recordDate"; |
| | | map.workShift = "workShift"; |
| | | map.teamName = "teamName"; |
| | | map.poleModel = "poleModel"; |
| | | map.poleNumber = "poleNumber"; |
| | | map.outputNumber = "outputNumber"; |
| | | map.inspectPerson = "inspectPerson"; |
| | | map.productType = "productType"; |
| | | map.recordPosition = "recordPosition"; |
| | | map.rejectList = [ |
| | | { |
| | | rejectPerson: "rejectPerson", |
| | | rejectTime: "rejectTime", |
| | | rejectReason: { |
| | | reason: "reason" |
| | | reason: "reason", |
| | | }, |
| | | }, |
| | | ], // æ¹ä¸ºå¯¹è±¡ï¼å
嫿éçåµå¥å±æ§ |
| | | }); |
| | | const props = defineProps({ |
| | | api: { |
| | | type: Function, |
| | | default: () => { }, |
| | | }, |
| | | ProList: { |
| | | type: Object, |
| | | default: () => { }, |
| | | }, |
| | | }); |
| | | |
| | | const list = ref<any[]>([]); |
| | | |
| | | const toDetail = (id: number, deviceType: number) => { |
| | | console.log('ç¹å»å¡ç', id, deviceType); |
| | | if (deviceType == 1) { |
| | | // ç»çº¿ |
| | | uni.navigateTo({ |
| | | url: `/pages/routingInspection/detail/indexJX?id=${id}&deviceType=${deviceType}`, |
| | | }); |
| | | } else if (deviceType == 0) { |
| | | // æä¸ |
| | | uni.navigateTo({ |
| | | url: `/pages/routingInspection/detail/indexLS?id=${id}&deviceType=${deviceType}`, |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | const getList = async () => { |
| | | const { code, data } = await props.api({ |
| | | deviceModel: props.ProList.deviceModel, |
| | | status: "0", |
| | | deviceType: props.ProList.deviceType, |
| | | }); |
| | | if (code == 200) { |
| | | map.deviceModel = "deviceModel"; |
| | | map.model = "model"; |
| | | map.firstNo = "firstNo"; |
| | | map.recordDate = "recordDate"; |
| | | map.workShift = "workShift"; |
| | | map.teamName = "teamName"; |
| | | map.poleModel = "poleModel"; |
| | | map.poleNumber = "poleNumber"; |
| | | map.outputNumber = "outputNumber"; |
| | | map.inspectPerson = "inspectPerson"; |
| | | map.rejectList = [ |
| | | { |
| | | rejectPerson: "rejectPerson", |
| | | rejectTime: "rejectTime", |
| | | rejectReason: { |
| | | reason: "reason" |
| | | }, |
| | | }, |
| | | ]; |
| | | map.status = "status"; |
| | | if (data.total == 0) { |
| | | pagingRef.value.complete(true); |
| | | } else { |
| | | console.log('data.records', data.records); |
| | | pagingRef.value.complete(data.records); |
| | | } |
| | | } |
| | | }; |
| | | ]; |
| | | map.status = "status"; |
| | | if (data.total == 0) { |
| | | pagingRef.value.complete(true); |
| | | } else { |
| | | console.log("data.records", data.records); |
| | | pagingRef.value.complete(data.records); |
| | | } |
| | | } |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .card_box { |
| | | height: calc(100vh - 120px); |
| | | } |
| | | </style> |
| | | .card_box { |
| | | height: calc(100vh - 120px); |
| | | } |
| | | </style> |
| | |
| | | <wd-card class="card_bg" @click="handleCardClick"> |
| | | <template #title> |
| | | <view class="flex justify-between w-full"> |
| | | <text class="font-medium text-[#252525]">æºå°: {{ data[map.deviceModel] }}</text> |
| | | <text class="font-medium text-[#252525]">è®°å½ä½ç½®: {{ data[map.recordPosition] }}</text> |
| | | <wd-tag color="#0D867F" bg-color="#E7F4EC"> |
| | | <text class="text-xs">{{ data[map.model] }}</text> |
| | | </wd-tag> |
| | | </view> |
| | | </template> |
| | | <wd-row class="my-2"> |
| | | <wd-col :span="24"> |
| | | <view class="flex"> |
| | | <view class="icon_box"> |
| | | <wd-icon name="folder" color="#0D867F"></wd-icon> |
| | | </view> |
| | | <text class="text-[#646874] mx-2"> |
| | | 馿£åå·: |
| | | <text class="text-[#252525]">{{ data[map.firstNo] }}</text> |
| | | </text> |
| | | </view> |
| | | </wd-col> |
| | | </wd-row> |
| | | <wd-row class="my-2"> |
| | | <wd-col :span="24"> |
| | | <view class="flex"> |
| | |
| | | </view> |
| | | <text class="text-[#646874] mx-2"> |
| | | çç»: |
| | | <text class="text-[#252525]">{{ data[map.teamName] }}</text> |
| | | <text class="text-[#252525]"> |
| | | {{ data[map.teamName]?.slice(-2) || data[map.teamName] }} |
| | | </text> |
| | | </text> |
| | | </view> |
| | | </wd-col> |
| | | </wd-row> |
| | | <wd-row class="my-2"> |
| | | <wd-row class="my-2" v-if="data[map.productType]"> |
| | | <wd-col :span="24"> |
| | | <view class="flex"> |
| | | <view class="icon_box"> |
| | | <wd-icon name="folder" color="#0D867F"></wd-icon> |
| | | </view> |
| | | <text class="text-[#646874] mx-2"> |
| | | é¢ç¨æå·: |
| | | <text class="text-[#252525]">{{ data[map.poleNumber] }}</text> |
| | | </text> |
| | | </view> |
| | | </wd-col> |
| | | </wd-row> |
| | | <wd-col :span="12"> |
| | | <view class="flex"> |
| | | <view class="icon_box"> |
| | | <wd-icon name="folder" color="#0D867F"></wd-icon> |
| | | </view> |
| | | <text class="text-[#646874] mx-2"> |
| | | æåå·: |
| | | <text class="text-[#252525]">{{ data[map.poleModel] }}</text> |
| | | </text> |
| | | </view> |
| | | </wd-col> |
| | | <wd-row class="my-2"> |
| | | <wd-col :span="12"> |
| | | <view class="flex"> |
| | | <view class="icon_box"> |
| | | <wd-icon name="folder" color="#0D867F"></wd-icon> |
| | | </view> |
| | | <text class="text-[#646874] mx-2"> |
| | | ç产轴æ°: |
| | | <text class="text-[#252525]">{{ data[map.outputNumber] }}</text> |
| | | 产åç±»å«: |
| | | <text class="text-[#252525]">{{ data[map.productType] }}</text> |
| | | </text> |
| | | </view> |
| | | </wd-col> |
| | |
| | | .page-class { |
| | | :deep() { |
| | | .custom-shadow { |
| | | box-shadow: 0 3px 1px -2px rgb(0 0 0 / 20%), 0 2px 2px 0 rgb(0 0 0 / 14%), |
| | | box-shadow: |
| | | 0 3px 1px -2px rgb(0 0 0 / 20%), |
| | | 0 2px 2px 0 rgb(0 0 0 / 14%), |
| | | 0 1px 5px 0 rgb(0 0 0 / 12%); |
| | | } |
| | | } |
| | |
| | | .content { |
| | | padding: 5px; |
| | | } |
| | | </style> |
| | | </style> |
| | |
| | | <view class="attachment-list"> |
| | | <wd-status-tip v-if="attachmentList.length === 0" image="content" tip="ææ éä»¶" /> |
| | | |
| | | <view v-for="item in attachmentList" :key="item.id" class="attachment-card"> |
| | | <view v-for="(item, index) in attachmentList" :key="item.id || index" class="attachment-card"> |
| | | <view class="media-wrapper" @click="previewAttachment(item)"> |
| | | <!-- å¾çé¢è§ --> |
| | | <template v-if="isImageType(item.url)"> |
| | | <image |
| | | v-if="!item.loadError" |
| | | :src="getFullUrl(item.url)" |
| | | mode="aspectFill" |
| | | class="media-preview" |
| | | @error="onImageError(item)" |
| | | @load="onImageLoad(item)" |
| | | style="width: 100%; height: 100%" |
| | | @error="onImageError(item, index)" |
| | | @load="onImageLoad(item, index)" |
| | | :show-menu-by-longpress="true" |
| | | /> |
| | | <!-- å è½½ä¸é®ç½© --> |
| | | <view v-if="item.loading" class="loading-mask"> |
| | | <text class="loading-text">å è½½ä¸...</text> |
| | | </view> |
| | | <!-- å¾çå 载失败æ¾ç¤ºé»è®¤å¾æ --> |
| | | <view v-else class="file-icon-wrapper"> |
| | | <view v-if="item.loadError" class="file-icon-wrapper error-overlay"> |
| | | <wd-icon name="picture" size="48px" color="#ccc" /> |
| | | <text class="file-name error-text">å 载失败</text> |
| | | </view> |
| | |
| | | <!-- è§é¢é¢è§ --> |
| | | <template v-else-if="isVideoType(item.url)"> |
| | | <video |
| | | v-if="!item.loadError" |
| | | :src="getFullUrl(item.url)" |
| | | class="media-preview" |
| | | :controls="false" |
| | | :show-center-play-btn="false" |
| | | @error="onVideoError(item)" |
| | | :show-center-play-btn="true" |
| | | @error="onVideoError(item, index)" |
| | | object-fit="cover" |
| | | /> |
| | | <!-- è§é¢å 载失败æ¾ç¤ºé»è®¤å¾æ --> |
| | | <view v-else class="file-icon-wrapper"> |
| | | <view v-if="item.loadError" class="file-icon-wrapper error-overlay"> |
| | | <wd-icon name="video" size="48px" color="#ccc" /> |
| | | <text class="file-name error-text">å 载失败</text> |
| | | </view> |
| | |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { ref } from "vue"; |
| | | import { ref, computed, watch } from "vue"; |
| | | import { useToast } from "wot-design-uni"; |
| | | import AttachmentAPI from "@/api/product/attachment"; |
| | | |
| | | // H5 ä½¿ç¨ VITE_APP_BASE_API ä½ä¸ºä»£çè·¯å¾ï¼å
¶ä»å¹³å°ä½¿ç¨ VITE_APP_API_URL ä½ä¸ºè¯·æ±è·¯å¾ |
| | | let baseUrl = import.meta.env.VITE_APP_API_URL; |
| | | let baseUrlValue = import.meta.env.VITE_APP_API_URL || ""; |
| | | // #ifdef H5 |
| | | baseUrl = import.meta.env.VITE_APP_BASE_API; |
| | | baseUrlValue = import.meta.env.VITE_APP_BASE_API || ""; |
| | | // #endif |
| | | |
| | | const baseUrl = ref(baseUrlValue); // 使ç¨ref使å
¶å¨æ¨¡æ¿ä¸å¯è®¿é® |
| | | |
| | | // å¤é¨åæ° |
| | | const props = defineProps({ |
| | |
| | | }); |
| | | |
| | | const toast = useToast(); |
| | | const attachmentList = ref<any[]>(props.detailData.files || []); |
| | | const attachmentIds = ref<string[]>(props.detailData.attachmentId || []); |
| | | |
| | | // è·ååå§æ°æ® |
| | | const getInitialData = () => { |
| | | // å¤çä¸åçæ°æ®ç»æ |
| | | let data = props.detailData; |
| | | |
| | | // å¦ææ¯ ref 对象ï¼è·åå
¶ value |
| | | if (data && typeof data === "object" && "value" in data) { |
| | | data = data.value; |
| | | } |
| | | |
| | | // å¦ææ¯æ°ç»ï¼ç´æ¥è¿å |
| | | if (Array.isArray(data)) { |
| | | return data.map((item) => ({ |
| | | ...item, |
| | | loading: false, |
| | | loadError: false, |
| | | })); |
| | | } |
| | | |
| | | // 妿æ files 屿§ |
| | | if (data && data.files) { |
| | | const files = Array.isArray(data.files) ? data.files : []; |
| | | return files.map((item) => ({ |
| | | ...item, |
| | | loading: false, |
| | | loadError: false, |
| | | })); |
| | | } |
| | | |
| | | return []; |
| | | }; |
| | | |
| | | const attachmentList = ref<any[]>(getInitialData()); |
| | | const attachmentIds = ref<string[]>(attachmentList.value.map((item: any) => item.id) || []); |
| | | |
| | | // çå¬ props.detailData åå |
| | | watch( |
| | | () => props.detailData, |
| | | (newVal) => { |
| | | const newData = getInitialData(); |
| | | if (newData.length > 0) { |
| | | attachmentList.value = newData.map((item) => ({ |
| | | ...item, |
| | | loading: false, |
| | | loadError: false, |
| | | })); |
| | | attachmentIds.value = newData.map((item: any) => item.id); |
| | | } |
| | | }, |
| | | { deep: true, immediate: false } |
| | | ); |
| | | |
| | | // è·å宿´çå¾ç/è§é¢ URL |
| | | const getFullUrl = (url: string) => { |
| | | if (!url) return ""; |
| | | |
| | | // å¦æå·²ç»æ¯å®æ´ç URLï¼http æ https å¼å¤´ï¼ï¼ç´æ¥è¿å |
| | | if (url.startsWith("http://") || url.startsWith("https://")) { |
| | | return url; |
| | | } |
| | | |
| | | // æ£æ¥ baseUrl æ¯å¦ææ |
| | | if (!baseUrl.value) { |
| | | console.error("â baseUrlæªé
ç½®ï¼url:", url); |
| | | return url; |
| | | } |
| | | |
| | | // 妿æ¯ç¸å¯¹è·¯å¾ï¼æ¼æ¥åºç¡ URL |
| | | return `${baseUrl}${url.startsWith("/") ? "" : "/"}${url}`; |
| | | const separator = url.startsWith("/") || baseUrl.value.endsWith("/") ? "" : "/"; |
| | | return `${baseUrl.value}${separator}${url}`; |
| | | }; |
| | | |
| | | // å¾çå è½½æå |
| | | const onImageLoad = (item: any) => { |
| | | const onImageLoad = (item: any, index: number) => { |
| | | item.loading = false; |
| | | item.loadError = false; |
| | | attachmentList.value = [...attachmentList.value]; |
| | | }; |
| | | |
| | | // å¾çå 载失败 |
| | | const onImageError = (item: any) => { |
| | | console.error("å¾çå 载失败:", item.url); |
| | | const onImageError = (item: any, index: number) => { |
| | | console.error(`å¾çå 载失败 [${index}]:`, item.url); |
| | | item.loading = false; |
| | | item.loadError = true; |
| | | attachmentList.value = [...attachmentList.value]; |
| | | }; |
| | | |
| | | // è§é¢å 载失败 |
| | | const onVideoError = (item: any) => { |
| | | console.error("è§é¢å 载失败:", item.url); |
| | | const onVideoError = (item: any, index: number) => { |
| | | console.error(`è§é¢å 载失败 [${index}]:`, item.url); |
| | | item.loading = false; |
| | | item.loadError = true; |
| | | attachmentList.value = [...attachmentList.value]; |
| | | }; |
| | | |
| | | // æ°å¢éä»¶ |
| | |
| | | |
| | | .attachment-card { |
| | | width: 100%; |
| | | aspect-ratio: 1; |
| | | position: relative; |
| | | |
| | | // ä½¿ç¨ padding-top å®ç°æ£æ¹å½¢ï¼å
¼å®¹æ§æ´å¥½ï¼ |
| | | &::before { |
| | | content: ""; |
| | | display: block; |
| | | padding-top: 100%; // é«åº¦çäºå®½åº¦ |
| | | } |
| | | } |
| | | } |
| | | |
| | | .media-wrapper { |
| | | position: relative; |
| | | width: 100%; |
| | | height: 100%; |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | border-radius: 8px; |
| | | overflow: hidden; |
| | | background: #f5f5f5; |
| | |
| | | width: 100%; |
| | | height: 100%; |
| | | object-fit: cover; |
| | | display: block; |
| | | } |
| | | |
| | | .loading-mask { |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | background: rgba(0, 0, 0, 0.3); |
| | | z-index: 5; |
| | | |
| | | .loading-text { |
| | | font-size: 12px; |
| | | color: #fff; |
| | | } |
| | | } |
| | | |
| | | .file-icon-wrapper { |
| | |
| | | color: #ff4757; |
| | | } |
| | | } |
| | | |
| | | &.error-overlay { |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | background: rgba(255, 255, 255, 0.9); |
| | | z-index: 5; |
| | | } |
| | | } |
| | | |
| | | .delete-btn { |
| | |
| | | uni.showToast({ |
| | | title: resData.msg || "ä¸å¡å¤ç失败", |
| | | icon: "none", |
| | | duration: 2000, |
| | | }); |
| | | reject({ |
| | | message: resData.msg || "ä¸å¡å¤ç失败", |
| | | code: resData.code, |
| | | duration: 2000, |
| | | }); |
| | | } |
| | | }, |
| | |
| | | reject({ |
| | | message: "ç½ç»è¯·æ±å¤±è´¥", |
| | | error, |
| | | duration: 2000, |
| | | }); |
| | | }, |
| | | }); |