| | |
| | | <template> |
| | | <Splash v-if="showSplash" /> |
| | | <div v-else> |
| | | <router-view /> |
| | | </div> |
| | | <Splash v-if="showSplash" /> |
| | | <view v-else> |
| | | <router-view /> |
| | | </view> |
| | | </template> |
| | | <script setup> |
| | | import { ref, onMounted } from "vue"; |
| | | import Splash from "./components/Splash.vue"; |
| | | import { confirmMessage } from "@/api/login.js"; |
| | | import { ref, onMounted } from "vue"; |
| | | import Splash from "./components/Splash.vue"; |
| | | import { confirmMessage } from "@/api/login.js"; |
| | | |
| | | const showSplash = ref(true); |
| | | const showSplash = ref(true); |
| | | |
| | | onMounted(() => { |
| | | setTimeout(() => { |
| | | showSplash.value = false; |
| | | }, 5000); |
| | | onMounted(() => { |
| | | setTimeout(() => { |
| | | showSplash.value = false; |
| | | }, 5000); |
| | | |
| | | // åå§åæ¨éæå¡,ææ¶æ³¨éï¼å®¢æ·éè¦æå¼ |
| | | // initPushService(); |
| | | }); |
| | | // åå§åæ¨éæå¡ï¼uni-push 1.0ï¼ |
| | | const initPushService = () => { |
| | | // #ifdef APP-PLUS |
| | | console.log("å¼å§åå§åæ¨éæå¡ï¼uni-push 1.0ï¼"); |
| | | if (typeof plus !== "undefined" && plus.push) { |
| | | console.log("plus.push åå¨:", plus.push); |
| | | |
| | | // è·å客æ·ç«¯æ¨éæ è¯ |
| | | console.log("ä½¿ç¨ plus.push.getClientInfo è·å客æ·ç«¯æ è¯"); |
| | | plus.push.getClientInfoAsync(info => { |
| | | console.log("客æ·ç«¯æ¨éæ è¯:", info); |
| | | uni.setStorageSync("clientid", info.clientid); |
| | | |
| | | // è¿éå¯ä»¥å°å®¢æ·ç«¯æ è¯åéå°æå¡å¨ |
| | | }); |
| | | setTimeout(() => { |
| | | console.log("ä½¿ç¨ plus.push.getClientInfoAsync è·å客æ·ç«¯æ è¯"); |
| | | plus.push.getClientInfoAsync(info => { |
| | | console.log("客æ·ç«¯æ¨éæ è¯:", info); |
| | | // è¿éå¯ä»¥å°å®¢æ·ç«¯æ è¯åéå°æå¡å¨ |
| | | }); |
| | | }, 1000); |
| | | |
| | | // ç嬿¨éæ¶æ¯ç¹å»äºä»¶ |
| | | plus.push.addEventListener("click", handlePushClick, false); |
| | | // ç嬿¨éæ¶æ¯æ¥æ¶äºä»¶ |
| | | plus.push.addEventListener("receive", handlePushReceive, false); |
| | | console.log("æ¨éæå¡æ³¨åæå"); |
| | | } else { |
| | | console.log("æ¨éæå¡ä¸å¯ç¨"); |
| | | } |
| | | // #endif |
| | | }; |
| | | |
| | | // åå§åæ¨éæå¡,ææ¶æ³¨éï¼å®¢æ·éè¦æå¼ |
| | | // initPushService(); |
| | | }); |
| | | // åå§åæ¨éæå¡ï¼uni-push 1.0ï¼ |
| | | const initPushService = () => { |
| | | // #ifdef APP-PLUS |
| | | console.log("å¼å§åå§åæ¨éæå¡ï¼uni-push 1.0ï¼"); |
| | | if (typeof plus !== "undefined" && plus.push) { |
| | | console.log("plus.push åå¨:", plus.push); |
| | | // å¤çæ¨éæ¶æ¯ç¹å»äºä»¶ |
| | | const handlePushClick = msg => { |
| | | console.log("ç¹å»æ¨éæ¶æ¯:", msg); |
| | | console.log("è§£æå:", msg.payload.noticeId); |
| | | try { |
| | | if (msg.payload.needMarkRead) { |
| | | confirmMessage(msg.payload.noticeId, 1).then(res => { |
| | | if (msg.payload.url) { |
| | | if (msg.payload.url.indexOf("/") === 0) { |
| | | uni.navigateTo({ |
| | | url: msg.payload.url, |
| | | }); |
| | | } else { |
| | | uni.navigateTo({ |
| | | url: "/" + msg.payload.url, |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | } else { |
| | | if (msg.payload.url) { |
| | | if (msg.payload.url.indexOf("/") === 0) { |
| | | uni.navigateTo({ |
| | | url: msg.payload.url, |
| | | }); |
| | | } else { |
| | | uni.navigateTo({ |
| | | url: "/" + msg.payload.url, |
| | | }); |
| | | } |
| | | } |
| | | } |
| | | } catch (error) { |
| | | uni.showToast({ |
| | | title: "è·¯å¾:" + msg.payload, |
| | | icon: "none", |
| | | }); |
| | | uni.showToast({ |
| | | title: "跳转失败:" + error.message, |
| | | icon: "none", |
| | | }); |
| | | } |
| | | // è§£æå¹¶å¤çæ¨éæ¶æ¯... |
| | | }; |
| | | |
| | | // è·å客æ·ç«¯æ¨éæ è¯ |
| | | console.log("ä½¿ç¨ plus.push.getClientInfo è·å客æ·ç«¯æ è¯"); |
| | | plus.push.getClientInfoAsync(info => { |
| | | console.log("客æ·ç«¯æ¨éæ è¯:", info); |
| | | uni.setStorageSync("clientid", info.clientid); |
| | | |
| | | // è¿éå¯ä»¥å°å®¢æ·ç«¯æ è¯åéå°æå¡å¨ |
| | | }); |
| | | setTimeout(() => { |
| | | console.log("ä½¿ç¨ plus.push.getClientInfoAsync è·å客æ·ç«¯æ è¯"); |
| | | plus.push.getClientInfoAsync(info => { |
| | | console.log("客æ·ç«¯æ¨éæ è¯:", info); |
| | | // è¿éå¯ä»¥å°å®¢æ·ç«¯æ è¯åéå°æå¡å¨ |
| | | }); |
| | | }, 1000); |
| | | |
| | | // ç嬿¨éæ¶æ¯ç¹å»äºä»¶ |
| | | plus.push.addEventListener("click", handlePushClick, false); |
| | | // ç嬿¨éæ¶æ¯æ¥æ¶äºä»¶ |
| | | plus.push.addEventListener("receive", handlePushReceive, false); |
| | | console.log("æ¨éæå¡æ³¨åæå"); |
| | | } else { |
| | | console.log("æ¨éæå¡ä¸å¯ç¨"); |
| | | } |
| | | // #endif |
| | | }; |
| | | |
| | | // å¤çæ¨éæ¶æ¯ç¹å»äºä»¶ |
| | | const handlePushClick = msg => { |
| | | console.log("ç¹å»æ¨éæ¶æ¯:", msg); |
| | | console.log("è§£æå:", msg.payload.noticeId); |
| | | try { |
| | | if (msg.payload.needMarkRead) { |
| | | confirmMessage(msg.payload.noticeId, 1).then(res => { |
| | | if (msg.payload.url) { |
| | | if (msg.payload.url.indexOf("/") === 0) { |
| | | uni.navigateTo({ |
| | | url: msg.payload.url, |
| | | }); |
| | | } else { |
| | | uni.navigateTo({ |
| | | url: "/" + msg.payload.url, |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | } else { |
| | | if (msg.payload.url) { |
| | | if (msg.payload.url.indexOf("/") === 0) { |
| | | uni.navigateTo({ |
| | | url: msg.payload.url, |
| | | }); |
| | | } else { |
| | | uni.navigateTo({ |
| | | url: "/" + msg.payload.url, |
| | | }); |
| | | } |
| | | } |
| | | } |
| | | } catch (error) { |
| | | uni.showToast({ |
| | | title: "è·¯å¾:" + msg.payload, |
| | | icon: "none", |
| | | }); |
| | | uni.showToast({ |
| | | title: "跳转失败:" + error.message, |
| | | icon: "none", |
| | | }); |
| | | } |
| | | // è§£æå¹¶å¤çæ¨éæ¶æ¯... |
| | | }; |
| | | |
| | | // å¤çæ¨éæ¶æ¯æ¥æ¶äºä»¶ |
| | | const handlePushReceive = msg => { |
| | | console.log("æ¶å°æ¨éæ¶æ¯:", msg); |
| | | // å¤çæ¥æ¶çæ¨éæ¶æ¯... |
| | | }; |
| | | // å¤çæ¨éæ¶æ¯æ¥æ¶äºä»¶ |
| | | const handlePushReceive = msg => { |
| | | console.log("æ¶å°æ¨éæ¶æ¯:", msg); |
| | | // å¤çæ¥æ¶çæ¨éæ¶æ¯... |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="scss"> |
| | | @import "uview-plus/index.scss"; |
| | | @import "@/static/scss/index.scss"; |
| | | @import "uview-plus/index.scss"; |
| | | @import "@/static/scss/index.scss"; |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from "@/utils/request"; |
| | | |
| | | export function getDeviceAreaTree(params) { |
| | | return request({ |
| | | url: "/device/area/tree", |
| | | method: "get", |
| | | params, |
| | | }); |
| | | } |
| | | |
| | | export function getDeviceAreaTreeWithDevices(params) { |
| | | return request({ |
| | | url: "/device/area/treeWithDevices", |
| | | method: "get", |
| | | }); |
| | | } |
| | | |
| | | export function getDeviceAreaPage(params) { |
| | | return request({ |
| | | url: "/device/area/page", |
| | | method: "get", |
| | | params, |
| | | }); |
| | | } |
| | | |
| | | export function getDeviceAreaDetail(id) { |
| | | return request({ |
| | | url: `/device/area/${id}`, |
| | | method: "get", |
| | | }); |
| | | } |
| | | |
| | | export function addDeviceArea(data) { |
| | | return request({ |
| | | url: "/device/area", |
| | | method: "post", |
| | | data, |
| | | }); |
| | | } |
| | | |
| | | export function updateDeviceArea(data) { |
| | | return request({ |
| | | url: "/device/area", |
| | | method: "put", |
| | | data, |
| | | }); |
| | | } |
| | | |
| | | export function deleteDeviceArea(ids) { |
| | | return request({ |
| | | url: "/device/area", |
| | | method: "delete", |
| | | data: ids, |
| | | }); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from "@/utils/request"; |
| | | |
| | | export const getEnvironmentalRealData = () => { |
| | | return request({ |
| | | url: "/iot/getRealData", |
| | | method: "get", |
| | | }); |
| | | }; |
| | |
| | | // éè´å°è´¦é¡µé¢æ¥å£ |
| | | import request from "@/utils/request"; |
| | | |
| | | // å页æ¥è¯¢ |
| | | /** 仿¬¾å°è´¦ - ä¾åºå徿¥æ±æ» */ |
| | | export function paymentLedgerList(query) { |
| | | return request({ |
| | | url: "/purchase/paymentRegistration/supplierNameListPage", |
| | | url: "/purchase/report/supplierTransactions", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // å页æ¥è¯¢ |
| | | export function paymentRecordList(supplierId) { |
| | | /** 仿¬¾å°è´¦ - ä¾åºå徿¥æç» */ |
| | | export function paymentRecordList(params) { |
| | | return request({ |
| | | url: "/purchase/paymentRegistration/supplierNameListPageDetails", |
| | | url: "/purchase/report/supplierTransactionsDetails", |
| | | method: "get", |
| | | params: supplierId, |
| | | params, |
| | | }); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // åè´§å°è´¦é¡µé¢æ¥å£ |
| | | import request from "@/utils/request"; |
| | | |
| | | // å页æ¥è¯¢åè´§å°è´¦ï¼æ ¹æ®å®¢æ·IDï¼ |
| | | export function deliveryLedgerListPage(query) { |
| | | return request({ |
| | | url: "/shippingInfo/listPage", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // ææ ç»è®¡é¡µé¢æ¥å£ |
| | | import request from "@/utils/request"; |
| | | |
| | | // 头é¨ç»è®¡æ¥å£ |
| | | export function getTotalStatistics(query) { |
| | | return request({ |
| | | url: "/metricStatistics/total", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // æ±ç¶å¾æ°æ®æ¥å£ |
| | | export function getStatisticsTable(query) { |
| | | return request({ |
| | | url: "/metricStatistics/statisticsTable", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // 客æ·å¾æ¥å表 |
| | | export function customewTransactions(query) { |
| | | return request({ |
| | | url: "/metricStatistics/customewTransactions", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // 客æ·å¾æ¥æç» |
| | | export function customewTransactionsDetails(query) { |
| | | return request({ |
| | | url: "/metricStatistics/customewTransactionsDetails", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | |
| | | // åºç¨å
¨å±é
ç½® |
| | | const config = { |
| | | baseUrl: "http://1.15.17.182:9048", |
| | | fileUrl: "http://1.15.17.182:9049", |
| | | baseUrl: "http://1.15.17.182:9073", |
| | | fileUrl: "http://1.15.17.182:9072", |
| | | // åºç¨ä¿¡æ¯ |
| | | appInfo: { |
| | | // åºç¨åç§° |
| | |
| | | import { OA_NAV } from "./oaPaths.js"; |
| | | |
| | | /** |
| | | * OA 模ååç»ï¼å·¥ä½å°å±ç¤º / ææ¡£å¯¹ç
§ï¼ |
| | | * 注ï¼äººäºç®¡ç/åå¤ç®¡ç/æ¥é管ç/审æ¹ç®¡ç å·²è¿ç§»è³å¯¹åºä¸å¡æ¨¡å |
| | | */ |
| | | export const OA_MODULES = [ |
| | | { |
| | | key: "HrManage", |
| | | name: "人äºç®¡ç", |
| | | children: [ |
| | | // { label: "å工档æ¡", icon: "/static/images/icon/renyuanxinzi.svg", path: OA_NAV.staffArchive }, |
| | | // { label: "åå·¥åå", icon: "/static/images/icon/hetongguanli.svg", path: OA_NAV.staffContract }, |
| | | { label: "转æ£ç³è¯·", icon: "/static/images/icon/hetongguanli.svg", path: OA_NAV.regularApply }, |
| | | { label: "è°å²ç³è¯·", icon: "/static/images/icon/renyuanxinzi.svg", path: OA_NAV.transferApply }, |
| | | // { label: "离èç³è¯·", icon: "/static/images/icon/qingjiaguanli.svg", path: OA_NAV.resignApply }, |
| | | { label: "å·¥ä½äº¤æ¥", icon: "/static/images/icon/gongchuguanli.svg", path: OA_NAV.workHandover }, |
| | | // { label: "å²ä½ç®¡ç", icon: "/static/images/icon/gongxuguanli.svg", path: OA_NAV.postManage }, |
| | | ], |
| | | }, |
| | | { |
| | | key: "AttendManage", |
| | | name: "åå¤ç®¡ç", |
| | | children: [ |
| | | { label: "请åç³è¯·", icon: "/static/images/icon/qingjiaguanli.svg", path: OA_NAV.leaveApply }, |
| | | { label: "å çç³è¯·", icon: "/static/images/icon/dakaqiandao.svg", path: OA_NAV.overtimeApply }, |
| | | ], |
| | | }, |
| | | { |
| | | key: "ReimburseManage", |
| | | name: "æ¥é管ç", |
| | | children: [ |
| | | { label: "å·®æ
æ¥é", icon: "/static/images/icon/chuchaiguanli.svg", path: OA_NAV.travelReimburse }, |
| | | { label: "è´¹ç¨æ¥é", icon: "/static/images/icon/baoxiaoguanli.svg", path: OA_NAV.costReimburse }, |
| | | ], |
| | | }, |
| | | // { |
| | | // key: "ContractManage", |
| | | // name: "åå管ç", |
| | | // children: [ |
| | | // { label: "éè´åå", icon: "/static/images/icon/caigoutaizhang.svg", path: OA_NAV.purchaseContract }, |
| | | // { label: "éå®åå", icon: "/static/images/icon/xiaoshoutaizhang.svg", path: OA_NAV.saleContract }, |
| | | // ], |
| | | // }, |
| | | { |
| | | key: "ApproveManage", |
| | | name: "审æ¹ç®¡ç", |
| | | children: [ |
| | | { label: "审æ¹å表", icon: "/static/images/icon/xietongshenpi.svg", path: OA_NAV.approveList }, |
| | | { label: "å®¡æ¹æ¨¡æ¿", icon: "/static/images/icon/guizhangzhidu.svg", path: OA_NAV.approveTemplate }, |
| | | ], |
| | | }, |
| | | // { |
| | | // key: "EnterpriseNews", |
| | | // name: "ä¼ä¸æ°é»", |
| | | // children: [ |
| | | // { label: "ä¼ä¸æ°é»", icon: "/static/images/icon/zhishiku.svg", path: OA_NAV.enterpriseNews }, |
| | | // ], |
| | | // }, |
| | | // { |
| | | // key: "NoticeAnnouncement", |
| | | // name: "å
¬åéç¥", |
| | | // children: [ |
| | | // { label: "å
¬åéç¥", icon: "/static/images/icon/tongzhigonggao.svg", path: OA_NAV.noticeAnnouncement }, |
| | | // ], |
| | | // }, |
| | | ]; |
| | | export const OA_MODULES = []; |
| | | |
| | | /** å·¥ä½å°æå¹³èåï¼çº¯å端é
ç½®ï¼ */ |
| | | export const OA_WORKBENCH_ITEMS = OA_MODULES.flatMap(module => |
| | |
| | | { |
| | | "name" : "ä¿¡æ¯ç®¡çPro-OA", |
| | | "appid" : "__UNI__751174B", |
| | | "name" : "æ°ç大ç½ç´ 马éè¯", |
| | | "appid" : "__UNI__21B3383", |
| | | "description" : "", |
| | | "versionName" : "1.1.5", |
| | | "versionCode" : 100, |
| | |
| | | } |
| | | }, |
| | | { |
| | | "path": "pages/inventoryManagement/environmentalMonitoring/index", |
| | | "style": { |
| | | "navigationBarTitleText": "ç¯å¢æ£æµ", |
| | | "navigationStyle": "custom" |
| | | } |
| | | }, |
| | | { |
| | | "path": "pages/safeProduction/safeQualifications/index", |
| | | "style": { |
| | | "navigationBarTitleText": "è§ç¨ä¸èµè´¨", |
| | |
| | | { |
| | | "path": "pages/qualityManagement/materialInspection/index", |
| | | "style": { |
| | | "navigationBarTitleText": "åæææ£éª", |
| | | "navigationBarTitleText": "åææ£éª", |
| | | "navigationStyle": "custom" |
| | | } |
| | | }, |
| | |
| | | @back="goBack" /> |
| | | <!-- 页é¢å
容 --> |
| | | <view class="attachment-content"> |
| | | <!-- åç±»æ ç¾é¡µ --> |
| | | <view class="attachment-tabs"> |
| | | <view class="tab-item" |
| | | :class="{ active: currentViewType === 'before' }" |
| | | @click="switchViewType('before')"> |
| | | ç产å ({{ getAttachmentsByType(0).length }}) |
| | | </view> |
| | | <view class="tab-item" |
| | | :class="{ active: currentViewType === 'after' }" |
| | | @click="switchViewType('after')"> |
| | | çäº§ä¸ ({{ getAttachmentsByType(1).length }}) |
| | | </view> |
| | | <view class="tab-item" |
| | | :class="{ active: currentViewType === 'issue' }" |
| | | @click="switchViewType('issue')"> |
| | | ç产å ({{ getAttachmentsByType(2).length }}) |
| | | </view> |
| | | </view> |
| | | <!-- å½ååç±»çéä»¶å表 --> |
| | | <!-- éä»¶å表 --> |
| | | <view class="attachment-list-container"> |
| | | <view v-if="getCurrentViewAttachments().length > 0" |
| | | <view v-if="attachmentList.length > 0" |
| | | class="attachment-list"> |
| | | <view v-for="(file, index) in getCurrentViewAttachments()" |
| | | <view v-for="(file, index) in attachmentList" |
| | | :key="index" |
| | | class="attachment-item" |
| | | @click="previewAttachment(file)"> |
| | |
| | | </view> |
| | | <view v-else |
| | | class="attachment-empty"> |
| | | <text class="empty-text">该åç±»ææ éä»¶</text> |
| | | <text class="empty-text">ææ éä»¶</text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | |
| | | // éä»¶å表 |
| | | const attachmentList = ref([]); |
| | | |
| | | // å½åæ¥çç±»å |
| | | const currentViewType = ref("before"); // 'before', 'after', 'issue' |
| | | |
| | | // è§é¢é¢è§ç¸å
³ç¶æ |
| | | const showVideoDialog = ref(false); |
| | | const currentVideoFile = ref(null); |
| | |
| | | } |
| | | }); |
| | | |
| | | // å è½½éä»¶æ°æ® |
| | | // å è½½éä»¶æ°æ®ï¼ç»ä¸ä½¿ç¨ commonFileListVOï¼ |
| | | const loadAttachments = () => { |
| | | const task = taskInfo.value; |
| | | if (!task) return; |
| | | |
| | | attachmentList.value = []; |
| | | |
| | | // åç«¯åæ¾åæ®µ (VOä¼å
) |
| | | const beforeList = Array.isArray(task?.commonFileListBeforeVO) |
| | | ? task.commonFileListBeforeVO |
| | | : Array.isArray(task?.commonFileListBefore) |
| | | ? task.commonFileListBefore |
| | | : []; |
| | | |
| | | const duringList = Array.isArray(task?.commonFileListVO) |
| | | const fileList = Array.isArray(task?.commonFileListVO) |
| | | ? task.commonFileListVO |
| | | : Array.isArray(task?.commonFileListAfter) |
| | | ? task.commonFileListAfter |
| | | : []; // å
¼å®¹æ§é»è¾æå½åä¸ä¸è´ |
| | | |
| | | const afterList = Array.isArray(task?.commonFileListAfterVO) |
| | | ? task.commonFileListAfterVO |
| | | : Array.isArray(task?.commonFileListIssue) |
| | | ? task.commonFileListIssue |
| | | : []; |
| | | |
| | | // 妿 VO 齿²¡æï¼å°è¯ä» commonFileList è¿æ»¤ |
| | | const allList = Array.isArray(task?.commonFileList) |
| | | ? task.commonFileList |
| | | : []; |
| | | |
| | | const finalBefore = |
| | | beforeList.length > 0 ? beforeList : allList.filter(f => f?.type === 10); |
| | | const finalDuring = |
| | | duringList.length > 0 ? duringList : allList.filter(f => f?.type === 11); |
| | | const finalAfter = |
| | | afterList.length > 0 ? afterList : allList.filter(f => f?.type === 12); |
| | | |
| | | const mapToViewFile = (file, viewType) => { |
| | | // å
¼å®¹ previewURL, previewUrl, url, downloadURL, downloadUrl |
| | | attachmentList.value = fileList.map(file => { |
| | | const rawUrl = |
| | | file?.previewURL || |
| | | file?.previewUrl || |
| | |
| | | |
| | | return { |
| | | ...file, |
| | | type: viewType, |
| | | name: |
| | | file?.originalFilename || file?.bucketFilename || file?.name || "éä»¶", |
| | | name: file?.originalFilename || file?.bucketFilename || file?.name || "éä»¶", |
| | | bucketFilename: file?.bucketFilename || file?.name, |
| | | originalFilename: file?.originalFilename || file?.name, |
| | | url: u, |
| | | downloadUrl: u, |
| | | size: file?.byteSize || file?.size || 0, |
| | | }; |
| | | }; |
| | | |
| | | attachmentList.value.push(...finalBefore.map(f => mapToViewFile(f, 0))); |
| | | attachmentList.value.push(...finalDuring.map(f => mapToViewFile(f, 1))); |
| | | attachmentList.value.push(...finalAfter.map(f => mapToViewFile(f, 2))); |
| | | }); |
| | | }; |
| | | |
| | | // å°å端è¿åçæä»¶å°åè§èæå¯è®¿é®URL |
| | |
| | | uni.navigateBack(); |
| | | }; |
| | | |
| | | // 忢æ¥çç±»å |
| | | const switchViewType = type => { |
| | | currentViewType.value = type; |
| | | }; |
| | | |
| | | // æ ¹æ®typeè·å对åºåç±»çéä»¶ |
| | | const getAttachmentsByType = typeValue => { |
| | | return attachmentList.value.filter(file => file.type === typeValue) || []; |
| | | }; |
| | | |
| | | // è·åå½åæ¥çç±»åçéä»¶ |
| | | const getCurrentViewAttachments = () => { |
| | | switch (currentViewType.value) { |
| | | case "before": |
| | | return getAttachmentsByType(0); |
| | | case "after": |
| | | return getAttachmentsByType(1); |
| | | case "issue": |
| | | return getAttachmentsByType(2); |
| | | default: |
| | | return []; |
| | | } |
| | | }; |
| | | |
| | | // 夿æ¯å¦ä¸ºå¾çæä»¶ |
| | | const isImageFile = file => { |
| | | if (file.contentType && file.contentType.startsWith("image/")) { |
| | |
| | | // é¢è§éä»¶ |
| | | const previewAttachment = file => { |
| | | if (isImageFile(file)) { |
| | | const imageUrls = getCurrentViewAttachments() |
| | | const imageUrls = attachmentList.value |
| | | .filter(f => isImageFile(f)) |
| | | .map(f => f.url || f.downloadUrl); |
| | | |
| | |
| | | |
| | | .attachment-content { |
| | | padding: 15px; |
| | | } |
| | | |
| | | /* æ ç¾é¡µæ ·å¼ */ |
| | | .attachment-tabs { |
| | | display: flex; |
| | | background: #fff; |
| | | border-radius: 12px; |
| | | margin-bottom: 15px; |
| | | padding: 4px; |
| | | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); |
| | | } |
| | | |
| | | .tab-item { |
| | | flex: 1; |
| | | text-align: center; |
| | | padding: 12px 8px; |
| | | font-size: 14px; |
| | | color: #666; |
| | | border-radius: 8px; |
| | | transition: all 0.3s ease; |
| | | } |
| | | |
| | | .tab-item.active { |
| | | background: #409eff; |
| | | color: #fff; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | /* éä»¶åè¡¨æ ·å¼ */ |
| | |
| | | <template> |
| | | <u-popup |
| | | v-model="dialogVisitable" |
| | | mode="center" |
| | | <u-popup |
| | | v-model="dialogVisitable" |
| | | mode="center" |
| | | :round="10" |
| | | :closeable="true" |
| | | @close="cancel" |
| | |
| | | <view class="popup-header"> |
| | | <text class="popup-title">å·¡æ£è®°å½ä¸ä¼ </text> |
| | | </view> |
| | | |
| | | |
| | | <view class="upload-container"> |
| | | <!-- å¼å¸¸ç¶æéæ© --> |
| | | <view class="form-container"> |
| | | <view class="title">å·¡æ£ç¶æ</view> |
| | | <view class="exception-section"> |
| | | <view class="exception-options"> |
| | | <view |
| | | class="exception-option" |
| | | <view |
| | | class="exception-option" |
| | | :class="{ active: hasException === false }" |
| | | @click="setExceptionStatus(false)" |
| | | > |
| | | <u-icon name="checkmark-circle" size="20" color="#52c41a"></u-icon> |
| | | <text class="option-text">æ£å¸¸</text> |
| | | </view> |
| | | <view |
| | | class="exception-option" |
| | | <view |
| | | class="exception-option" |
| | | :class="{ active: hasException === true }" |
| | | @click="setExceptionStatus(true)" |
| | | > |
| | |
| | | :customStyle="{ padding: '10px', backgroundColor: '#f5f5f5' }" |
| | | /> |
| | | </view> |
| | | |
| | | |
| | | <!-- ä¸ä¼ åºåï¼ä»
å¨å¼å¸¸æ¶æ¾ç¤ºï¼ --> |
| | | <template v-if="hasException === true"> |
| | | <view class="form-container"> |
| | | <view class="title">ç产å</view> |
| | | <u-upload |
| | | :fileList="beforeModelValue" |
| | | @afterRead="afterRead" |
| | | @delete="deleteFile" |
| | | name="before" |
| | | multiple |
| | | :maxCount="10" |
| | | :maxSize="5 * 1024 * 1024" |
| | | accept="image/*" |
| | | :previewFullImage="true" |
| | | ></u-upload> |
| | | </view> |
| | | |
| | | <view class="form-container"> |
| | | <view class="title">ç产å</view> |
| | | <u-upload |
| | | :fileList="afterModelValue" |
| | | @afterRead="afterRead" |
| | | @delete="deleteFile" |
| | | name="after" |
| | | multiple |
| | | :maxCount="10" |
| | | :maxSize="5 * 1024 * 1024" |
| | | accept="image/*" |
| | | :previewFullImage="true" |
| | | ></u-upload> |
| | | </view> |
| | | |
| | | <view class="form-container"> |
| | | <view class="title">ç产é®é¢</view> |
| | | <u-upload |
| | | :fileList="issueModelValue" |
| | | @afterRead="afterRead" |
| | | @delete="deleteFile" |
| | | name="issue" |
| | | multiple |
| | | :maxCount="10" |
| | | :maxSize="5 * 1024 * 1024" |
| | | accept="image/*" |
| | | :previewFullImage="true" |
| | | ></u-upload> |
| | | </view> |
| | | </template> |
| | | <view class="form-container" v-if="hasException === true"> |
| | | <view class="title">ä¸ä¼ éä»¶</view> |
| | | <text class="upload-count">å·²ä¸ä¼ : {{ fileList.length }}个æä»¶</text> |
| | | <u-upload |
| | | :fileList="fileList" |
| | | @afterRead="afterRead" |
| | | @delete="deleteFile" |
| | | name="attachment" |
| | | multiple |
| | | :maxCount="30" |
| | | :maxSize="5 * 1024 * 1024" |
| | | accept="image/*" |
| | | :previewFullImage="true" |
| | | ></u-upload> |
| | | </view> |
| | | |
| | | <!-- æ£å¸¸ç¶ææç¤º --> |
| | | <view class="form-container normal-tip" v-if="hasException === false"> |
| | |
| | | <text class="tip-text">设å¤è¿è¡æ£å¸¸ï¼æ éä¸ä¼ ç
§ç</text> |
| | | </view> |
| | | </view> |
| | | |
| | | |
| | | <view class="popup-footer"> |
| | | <u-button @click="cancel" :customStyle="{ marginRight: '10px' }">åæ¶</u-button> |
| | | <u-button type="primary" @click="submitForm">ä¿å</u-button> |
| | |
| | | const emit = defineEmits(['closeDia']) |
| | | |
| | | const dialogVisitable = ref(false) |
| | | const beforeModelValue = ref([]) |
| | | const afterModelValue = ref([]) |
| | | const issueModelValue = ref([]) |
| | | const fileList = ref([]) |
| | | const infoData = ref(null) |
| | | |
| | | // å¼å¸¸ç¶æï¼null=æªéæ©, false=æ£å¸¸, true=å¼å¸¸ |
| | |
| | | // 计ç®ä¸ä¼ URL |
| | | const uploadFileUrl = computed(() => { |
| | | let baseUrl = ''; |
| | | |
| | | |
| | | if (process.env.VUE_APP_BASE_API) { |
| | | baseUrl = process.env.VUE_APP_BASE_API; |
| | | } else { |
| | | baseUrl = config.baseUrl; |
| | | } |
| | | |
| | | |
| | | return baseUrl + '/file/upload'; |
| | | }) |
| | | |
| | |
| | | |
| | | // æä»¶ä¸ä¼ å¤ç |
| | | const afterRead = (event) => { |
| | | const { name, file } = event |
| | | |
| | | // æ ¹æ®ä¸ä¼ ç±»å设置ä¸åçtypeå¼ |
| | | let typeValue = 10 // é»è®¤å¼ |
| | | if (name === 'before') { |
| | | typeValue = 10 // ç产å |
| | | } else if (name === 'after') { |
| | | typeValue = 11 // çäº§ä¸ |
| | | } else if (name === 'issue') { |
| | | typeValue = 12 // ç产å |
| | | } |
| | | |
| | | const { file } = event |
| | | const files = Array.isArray(file) ? file : [file] |
| | | Promise.resolve().then(async () => { |
| | | for (const f of files) { |
| | | const uploaded = await uploadSingleFile(f, typeValue) |
| | | if (name === 'before') { |
| | | beforeModelValue.value.push(uploaded) |
| | | } else if (name === 'after') { |
| | | afterModelValue.value.push(uploaded) |
| | | } else if (name === 'issue') { |
| | | issueModelValue.value.push(uploaded) |
| | | } |
| | | const uploaded = await uploadSingleFile(f, 10) |
| | | fileList.value.push(uploaded) |
| | | } |
| | | uni.showToast({ title: 'ä¸ä¼ æå', icon: 'success' }) |
| | | }).catch((err) => { |
| | |
| | | |
| | | // å 餿件 |
| | | const deleteFile = (event) => { |
| | | const { name, index } = event |
| | | |
| | | if (name === 'before') { |
| | | beforeModelValue.value.splice(index, 1) |
| | | } else if (name === 'after') { |
| | | afterModelValue.value.splice(index, 1) |
| | | } else if (name === 'issue') { |
| | | issueModelValue.value.splice(index, 1) |
| | | } |
| | | const { index } = event |
| | | fileList.value.splice(index, 1) |
| | | } |
| | | |
| | | // 设置å¼å¸¸ç¶æ |
| | |
| | | |
| | | // 妿æ¯å¼å¸¸ç¶æï¼æ£æ¥æ¯å¦æä¸ä¼ æä»¶ |
| | | if (hasException.value === true) { |
| | | const totalFiles = beforeModelValue.value.length + afterModelValue.value.length + issueModelValue.value.length |
| | | if (totalFiles === 0) { |
| | | if (fileList.value.length === 0) { |
| | | uni.showToast({ |
| | | title: '请ä¸ä¼ å¼å¸¸ç
§ç', |
| | | icon: 'none' |
| | |
| | | } |
| | | } |
| | | |
| | | let arr = [] |
| | | if (beforeModelValue.value.length > 0) { |
| | | arr.push(...beforeModelValue.value.map(item => ({ ...item, statusType: 0 }))) |
| | | } |
| | | if (afterModelValue.value.length > 0) { |
| | | arr.push(...afterModelValue.value.map(item => ({ ...item, statusType: 1 }))) |
| | | } |
| | | if (issueModelValue.value.length > 0) { |
| | | arr.push(...issueModelValue.value.map(item => ({ ...item, statusType: 2 }))) |
| | | } |
| | | |
| | | // æäº¤æ°æ® |
| | | infoData.value.storageBlobDTO = arr |
| | | infoData.value.commonFileListDTO = fileList.value |
| | | infoData.value.hasException = hasException.value |
| | | infoData.value.exceptionDescription = exceptionDescription.value |
| | | await submitInspectionRecord({ ...infoData.value }) |
| | | |
| | | |
| | | uni.showToast({ |
| | | title: 'æäº¤æå', |
| | | icon: 'success' |
| | | }) |
| | | |
| | | |
| | | cancel() |
| | | } catch (error) { |
| | | console.error('æäº¤å¤±è´¥:', error) |
| | |
| | | const openDialog = async (row) => { |
| | | infoData.value = row |
| | | dialogVisitable.value = true |
| | | |
| | | |
| | | // æ¸
空ä¹åçæ°æ® |
| | | beforeModelValue.value = [] |
| | | afterModelValue.value = [] |
| | | issueModelValue.value = [] |
| | | fileList.value = [] |
| | | hasException.value = null |
| | | exceptionDescription.value = '' |
| | | } |
| | |
| | | |
| | | .form-container { |
| | | margin-bottom: 20px; |
| | | |
| | | |
| | | &:last-child { |
| | | margin-bottom: 0; |
| | | } |
| | | } |
| | | |
| | | .upload-count { |
| | | display: block; |
| | | font-size: 12px; |
| | | color: #999; |
| | | margin-bottom: 8px; |
| | | padding-left: 10px; |
| | | } |
| | | |
| | | .title { |
| | |
| | | padding-left: 10px; |
| | | position: relative; |
| | | margin: 6px 0 10px; |
| | | |
| | | |
| | | &::before { |
| | | content: ""; |
| | | position: absolute; |
| | |
| | | cursor: pointer; |
| | | transition: all 0.3s; |
| | | background-color: #fff; |
| | | |
| | | |
| | | &.active { |
| | | border-color: #1890ff; |
| | | background-color: #e6f7ff; |
| | | } |
| | | |
| | | |
| | | &:active { |
| | | opacity: 0.8; |
| | | } |
| | |
| | | background-color: #f6ffed; |
| | | border: 1px dashed #b7eb8f; |
| | | border-radius: 8px; |
| | | |
| | | |
| | | .tip-text { |
| | | margin-top: 15px; |
| | | font-size: 14px; |
| | |
| | | </u-input> |
| | | </u-form-item> |
| | | |
| | | <u-form-item label="éä»¶" prop="storageBlobDTO" labelWidth="80"> |
| | | <u-form-item label="éä»¶" prop="commonFileListDTO" labelWidth="80"> |
| | | <view class="upload-container"> |
| | | <ImageUpload |
| | | v-model="form.storageBlobDTO" |
| | | v-model="form.commonFileListDTO" |
| | | :limit="10" |
| | | :fileSize="50" |
| | | :fileType="['jpg', 'jpeg', 'png', 'mp4', 'mov']" |
| | | :maxVideoDuration="60" |
| | | :statusType="0" |
| | | @update:modelValue="handleStorageBlobUpdate" |
| | | @update:modelValue="handleFileListUpdate" |
| | | /> |
| | | </view> |
| | | </u-form-item> |
| | |
| | | scannerName: '', |
| | | scannerId: '', |
| | | scanTime: '', |
| | | storageBlobDTO: [], |
| | | commonFileListDTO: [], |
| | | qrCode: { |
| | | id: '' |
| | | } |
| | |
| | | } |
| | | }) |
| | | |
| | | // å¤çstorageBlobDTOæ°æ®æ´æ° |
| | | const handleStorageBlobUpdate = (value) => { |
| | | form.storageBlobDTO = value || [] |
| | | // å¤çcommonFileListDTOæ°æ®æ´æ° |
| | | const handleFileListUpdate = (value) => { |
| | | form.commonFileListDTO = value || [] |
| | | } |
| | | |
| | | // è·åå½åä½ç½® |
| | |
| | | form.deviceName = row.deviceName || '' |
| | | form.location = row.location || '' |
| | | form.qrCodeId = row.qrCodeId |
| | | form.storageBlobDTO = [] |
| | | form.commonFileListDTO = [] |
| | | console.log('å¼¹æ¡è¡¨åæ°æ®:', form) |
| | | |
| | | // å¼ºå¶æ´æ°è§å¾ |
| | |
| | | scannerName: form.scannerName, |
| | | scannerId: form.scannerId, |
| | | scanTime: form.scanTime, |
| | | storageBlobDTO: form.storageBlobDTO.map(file => ({ |
| | | id: file.id, // æ·»å idåæ®µ |
| | | commonFileListDTO: form.commonFileListDTO.map(file => ({ |
| | | id: file.id, |
| | | url: file.url, |
| | | bucketFilename: file.bucketFilename || file.name, |
| | | downloadUrl: file.downloadUrl || file.url, |
| | |
| | | maxlength="500" |
| | | placeholder="请æè¿°å¼å¸¸æ
åµ..." /> |
| | | </view> |
| | | <!-- åç±»æ ç¾é¡µï¼ä»
å¨å¼å¸¸æ¶æ¾ç¤ºï¼ --> |
| | | <!-- ä¸ä¼ åºåï¼ä»
å¨å¼å¸¸æ¶æ¾ç¤ºï¼ --> |
| | | <view class="section-card" |
| | | v-if="hasException === true"> |
| | | <view class="upload-tabs"> |
| | | <view class="tab-item" |
| | | :class="{ active: currentUploadType === 'before' }" |
| | | @click="switchUploadType('before')"> |
| | | ç产å |
| | | </view> |
| | | <view class="tab-item" |
| | | :class="{ active: currentUploadType === 'after' }" |
| | | @click="switchUploadType('after')"> |
| | | çäº§ä¸ |
| | | </view> |
| | | <view class="tab-item" |
| | | :class="{ active: currentUploadType === 'issue' }" |
| | | @click="switchUploadType('issue')"> |
| | | ç产å |
| | | </view> |
| | | </view> |
| | | <!-- å½ååç±»çä¸ä¼ åºå --> |
| | | <view class="section-title">ä¸ä¼ éä»¶</view> |
| | | <view class="upload-area"> |
| | | <view class="upload-buttons"> |
| | | <u-button type="primary" |
| | | @click="chooseMedia('image')" |
| | | :loading="uploading" |
| | | :disabled="getCurrentFiles().length >= uploadConfig.limit" |
| | | :disabled="fileList.length >= uploadConfig.limit" |
| | | :customStyle="{ marginRight: '10px', flex: 1 }"> |
| | | <u-icon name="camera" |
| | | size="18" |
| | |
| | | <u-button type="success" |
| | | @click="chooseMedia('video')" |
| | | :loading="uploading" |
| | | :disabled="getCurrentFiles().length >= uploadConfig.limit" |
| | | :disabled="fileList.length >= uploadConfig.limit" |
| | | :customStyle="{ flex: 1 }"> |
| | | <uni-icons type="videocam" |
| | | size="18" |
| | |
| | | :showText="true" |
| | | activeColor="#409eff"></u-line-progress> |
| | | </view> |
| | | <!-- å½ååç±»çæä»¶å表 --> |
| | | <view v-if="getCurrentFiles().length > 0" |
| | | <!-- æä»¶å表 --> |
| | | <view v-if="fileList.length > 0" |
| | | class="file-list"> |
| | | <view v-for="(file, index) in getCurrentFiles()" |
| | | <view v-for="(file, index) in fileList" |
| | | :key="index" |
| | | class="file-item"> |
| | | <view class="file-preview-container"> |
| | |
| | | style="margin-right: 5px"></uni-icons> |
| | | <text class="video-text">è§é¢</text> |
| | | </view> |
| | | <!-- å é¤æé® --> |
| | | <view class="delete-btn" |
| | | @click="removeFile(index)"> |
| | | <u-icon name="close" |
| | |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <view v-if="getCurrentFiles().length === 0" |
| | | <view v-if="fileList.length === 0" |
| | | class="empty-state"> |
| | | <text>è¯·éæ©è¦ä¸ä¼ ç{{ getUploadTypeText() }}å¾çæè§é¢</text> |
| | | <text>è¯·éæ©è¦ä¸ä¼ çå¾çæè§é¢</text> |
| | | </view> |
| | | </view> |
| | | <!-- ç»è®¡ä¿¡æ¯ --> |
| | | <view class="upload-summary"> |
| | | <text class="summary-text"> |
| | | ç产å: {{ beforeModelValue.length }}个æä»¶ | |
| | | ç产ä¸: {{ afterModelValue.length }}个æä»¶ | |
| | | ç产å: {{ issueModelValue.length }}个æä»¶ |
| | | </text> |
| | | <text class="summary-text">å·²ä¸ä¼ : {{ fileList.length }}个æä»¶</text> |
| | | </view> |
| | | </view> |
| | | <!-- æ£å¸¸ç¶ææç¤º --> |
| | |
| | | const uploading = ref(false); |
| | | const uploadProgress = ref(0); |
| | | |
| | | // ä¸ä¸ªåç±»çä¸ä¼ ç¶æ |
| | | const beforeModelValue = ref([]); // ç产å |
| | | const afterModelValue = ref([]); // çäº§ä¸ |
| | | const issueModelValue = ref([]); // ç产å |
| | | |
| | | // å½åæ¿æ´»çä¸ä¼ ç±»å |
| | | const currentUploadType = ref("before"); // 'before', 'after', 'issue' |
| | | // ç»ä¸çæä»¶å表 |
| | | const fileList = ref([]); |
| | | |
| | | // å¼å¸¸ç¶æ |
| | | const hasException = ref(null); // null: æªéæ©, true: åå¨å¼å¸¸, false: æ£å¸¸ |
| | |
| | | const info = JSON.parse(decodeURIComponent(options.taskInfo)); |
| | | taskInfo.value = info; |
| | | |
| | | // åæ¾é»è¾ï¼ä» taskInfo 䏿¢å¤å·²ä¸ä¼ çæä»¶ |
| | | const mapFiles = list => { |
| | | if (!list || !Array.isArray(list)) return []; |
| | | return list.map(item => { |
| | | // å¤ç URLï¼å»é¤å¯è½çç©ºæ ¼ |
| | | const finalUrl = (item.url || item.previewURL || "").trim(); |
| | | // èªå¨æ¨ææä»¶ç±»å |
| | | let fileType = item.type; |
| | | if (!fileType && item.contentType) { |
| | | fileType = item.contentType.startsWith("video") ? "video" : "image"; |
| | | } else if (!fileType) { |
| | | fileType = "image"; // é»è®¤å¾ç |
| | | } |
| | | // åæ¾é»è¾ï¼ä» commonFileListVO æ¢å¤å·²ä¸ä¼ çæä»¶ |
| | | const fileVOList = Array.isArray(info.commonFileListVO) ? info.commonFileListVO : []; |
| | | fileList.value = fileVOList.map(item => { |
| | | const finalUrl = (item.url || item.previewURL || "").trim(); |
| | | let fileType = item.type; |
| | | if (!fileType && item.contentType) { |
| | | fileType = item.contentType.startsWith("video") ? "video" : "image"; |
| | | } else if (!fileType) { |
| | | fileType = "image"; |
| | | } |
| | | return { |
| | | ...item, |
| | | url: finalUrl, |
| | | name: item.name || item.originalFilename, |
| | | tempId: item.tempId || item.id || item.tempFileId, |
| | | size: item.size || item.byteSize || 0, |
| | | type: fileType, |
| | | status: "success", |
| | | }; |
| | | }); |
| | | |
| | | return { |
| | | ...item, |
| | | url: finalUrl, |
| | | name: item.name || item.originalFilename, |
| | | tempId: item.tempId || item.id || item.tempFileId, |
| | | size: item.size || item.byteSize || 0, // æ å°å¤§å°å段 |
| | | type: fileType, |
| | | status: "success", |
| | | }; |
| | | }); |
| | | }; |
| | | |
| | | // ä¿®æ£å段æ å°ï¼BeforeVO(ç产å), VO(ç产ä¸), AfterVO(ç产å) |
| | | if ( |
| | | info.commonFileListBeforeVO && |
| | | Array.isArray(info.commonFileListBeforeVO) |
| | | ) { |
| | | beforeModelValue.value = mapFiles(info.commonFileListBeforeVO); |
| | | } |
| | | console.log(beforeModelValue.value, "beforeModelValue"); |
| | | |
| | | if (info.commonFileListVO && Array.isArray(info.commonFileListVO)) { |
| | | afterModelValue.value = mapFiles(info.commonFileListVO); |
| | | } |
| | | if ( |
| | | info.commonFileListAfterVO && |
| | | Array.isArray(info.commonFileListAfterVO) |
| | | ) { |
| | | issueModelValue.value = mapFiles(info.commonFileListAfterVO); |
| | | } |
| | | |
| | | // 妿æå¼å¸¸æè¿°ï¼ä¹æ¢å¤ |
| | | if (info.abnormalDescription) { |
| | | abnormalDescription.value = info.abnormalDescription; |
| | | } |
| | | // 妿æå¼å¸¸ç¶æï¼ä¹æ¢å¤ |
| | | if (info.hasException !== undefined && info.hasException !== null) { |
| | | hasException.value = info.hasException; |
| | | } else if ( |
| | | info.inspectionResult !== undefined && |
| | | info.inspectionResult !== null |
| | | ) { |
| | | // 0-å¼å¸¸ï¼1-æ£å¸¸ |
| | | } else if (info.inspectionResult !== undefined && info.inspectionResult !== null) { |
| | | hasException.value = String(info.inspectionResult) === "0"; |
| | | } |
| | | |
| | | // èªå¨å
åºï¼å¦æåå¨å·²ä¸ä¼ æä»¶ï¼åå¿
ç¶æ¯å¼å¸¸ç¶æï¼ç¡®ä¿ UI æ£å¸¸æ¾ç¤º |
| | | if ( |
| | | !hasException.value && |
| | | (beforeModelValue.value.length > 0 || |
| | | afterModelValue.value.length > 0 || |
| | | issueModelValue.value.length > 0) |
| | | ) { |
| | | if (!hasException.value && fileList.value.length > 0) { |
| | | hasException.value = true; |
| | | } |
| | | } catch (e) { |
| | |
| | | // è¿åä¸ä¸é¡µ |
| | | const goBack = () => { |
| | | uni.navigateBack(); |
| | | }; |
| | | |
| | | // 忢ä¸ä¼ ç±»å |
| | | const switchUploadType = type => { |
| | | currentUploadType.value = type; |
| | | }; |
| | | |
| | | // è·åå½ååç±»çæä»¶å表 |
| | | const getCurrentFiles = () => { |
| | | switch (currentUploadType.value) { |
| | | case "before": |
| | | return beforeModelValue.value || []; |
| | | case "after": |
| | | return afterModelValue.value || []; |
| | | case "issue": |
| | | return issueModelValue.value || []; |
| | | default: |
| | | return []; |
| | | } |
| | | }; |
| | | |
| | | // è·åä¸ä¼ ç±»åææ¬ |
| | | const getUploadTypeText = () => { |
| | | switch (currentUploadType.value) { |
| | | case "before": |
| | | return "ç产å"; |
| | | case "after": |
| | | return "ç产ä¸"; |
| | | case "issue": |
| | | return "ç产å"; |
| | | default: |
| | | return ""; |
| | | } |
| | | }; |
| | | |
| | | // 设置å¼å¸¸ç¶æ |
| | |
| | | inspector: taskInfo.value?.inspector, |
| | | hasException: hasException.value, |
| | | inspectionResult: hasException.value ? 0 : 1, // 0-å¼å¸¸ï¼1-æ£å¸¸ |
| | | commonFileListBeforeDTO: beforeModelValue.value, |
| | | commonFileListDTO: afterModelValue.value, |
| | | commonFileListAfterDTO: issueModelValue.value, |
| | | uploadedFiles: { |
| | | before: beforeModelValue.value, |
| | | after: afterModelValue.value, |
| | | issue: issueModelValue.value, |
| | | }, |
| | | commonFileListDTO: fileList.value, |
| | | uploadedFiles: fileList.value, |
| | | }; |
| | | |
| | | uni.setStorageSync("repairTaskInfo", JSON.stringify(taskData)); |
| | |
| | | |
| | | // 妿æ¯å¼å¸¸ç¶æï¼æ£æ¥æ¯å¦æä¸ä¼ æä»¶åæè¿° |
| | | if (hasException.value === true) { |
| | | const totalFiles = |
| | | beforeModelValue.value.length + |
| | | afterModelValue.value.length + |
| | | issueModelValue.value.length; |
| | | if (totalFiles === 0) { |
| | | if (fileList.value.length === 0) { |
| | | uni.showToast({ |
| | | title: "请ä¸ä¼ å¼å¸¸ç
§ç", |
| | | icon: "none", |
| | |
| | | mask: true, |
| | | }); |
| | | |
| | | // æç
§é»è¾åå¹¶ææåç±»çæä»¶ç¨äºæåID |
| | | const allFiles = [ |
| | | ...beforeModelValue.value, |
| | | ...afterModelValue.value, |
| | | ...issueModelValue.value, |
| | | ]; |
| | | |
| | | // ä¼ ç»å端çä¸´æ¶æä»¶IDå表 |
| | | let tempFileIds = []; |
| | | if (allFiles.length > 0) { |
| | | tempFileIds = allFiles |
| | | if (fileList.value.length > 0) { |
| | | tempFileIds = fileList.value |
| | | .map(item => item?.tempId ?? item?.tempFileId ?? item?.id) |
| | | .filter(v => v !== undefined && v !== null && v !== ""); |
| | | } |
| | |
| | | // æäº¤æ°æ® |
| | | const submitData = { |
| | | ...taskInfo.value, |
| | | commonFileListBeforeDTO: beforeModelValue.value, // ç产å |
| | | commonFileListDTO: afterModelValue.value, // çäº§ä¸ |
| | | commonFileListAfterDTO: issueModelValue.value, // ç产å |
| | | commonFileListDTO: fileList.value, |
| | | hasException: hasException.value, |
| | | inspectionResult: hasException.value ? 0 : 1, // 0-å¼å¸¸ï¼1-æ£å¸¸ |
| | | abnormalDescription: abnormalDescription.value, |
| | |
| | | |
| | | // æç
§/æè§é¢ |
| | | const chooseMedia = type => { |
| | | if (getCurrentFiles().length >= uploadConfig.limit) { |
| | | if (fileList.value.length >= uploadConfig.limit) { |
| | | uni.showToast({ |
| | | title: `æå¤åªè½éæ©${uploadConfig.limit}个æä»¶`, |
| | | icon: "none", |
| | |
| | | return; |
| | | } |
| | | |
| | | const remaining = uploadConfig.limit - getCurrentFiles().length; |
| | | const remaining = uploadConfig.limit - fileList.value.length; |
| | | |
| | | // ä¼å
ä½¿ç¨ chooseMedia |
| | | if (typeof uni.chooseMedia === "function") { |
| | |
| | | Authorization: `Bearer ${token}`, |
| | | }, |
| | | formData: { |
| | | type: getTabType(), |
| | | type: 10, |
| | | }, |
| | | success: res => { |
| | | try { |
| | |
| | | status: "success", |
| | | }; |
| | | |
| | | // æ ¹æ®å½åç±»åæ·»å å°å¯¹åºæ°ç» |
| | | if (currentUploadType.value === "before") { |
| | | beforeModelValue.value.push(uploadedFile); |
| | | } else if (currentUploadType.value === "after") { |
| | | afterModelValue.value.push(uploadedFile); |
| | | } else if (currentUploadType.value === "issue") { |
| | | issueModelValue.value.push(uploadedFile); |
| | | } |
| | | fileList.value.push(uploadedFile); |
| | | |
| | | uni.showToast({ title: "ä¸ä¼ æå", icon: "success" }); |
| | | } else { |
| | |
| | | }); |
| | | }; |
| | | |
| | | // è·åtypeå¼ |
| | | const getTabType = () => { |
| | | switch (currentUploadType.value) { |
| | | case "before": |
| | | return 10; |
| | | case "after": |
| | | return 11; |
| | | case "issue": |
| | | return 12; |
| | | default: |
| | | return 10; |
| | | } |
| | | }; |
| | | |
| | | // å 餿件 |
| | | const removeFile = index => { |
| | | const files = getCurrentFiles(); |
| | | const files = fileList.value; |
| | | files.splice(index, 1); |
| | | }; |
| | | </script> |
| | |
| | | outline: none; |
| | | border-color: #409eff; |
| | | background: #fff; |
| | | } |
| | | |
| | | /* åç±»æ ç¾é¡µ */ |
| | | .upload-tabs { |
| | | display: flex; |
| | | gap: 10px; |
| | | margin-bottom: 15px; |
| | | } |
| | | |
| | | .tab-item { |
| | | flex: 1; |
| | | padding: 10px; |
| | | text-align: center; |
| | | background: #f5f5f5; |
| | | border-radius: 6px; |
| | | font-size: 13px; |
| | | color: #666; |
| | | cursor: pointer; |
| | | transition: all 0.3s; |
| | | } |
| | | |
| | | .tab-item.active { |
| | | background: #409eff; |
| | | color: #fff; |
| | | } |
| | | |
| | | /* ä¸ä¼ åºå */ |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <view class="environment-page"> |
| | | <PageHeader title="ç¯å¢çæµ" @back="goBack" /> |
| | | |
| | | <scroll-view scroll-y class="page-scroll"> |
| | | <view class="summary-card"> |
| | | <view class="summary-header"> |
| | | <text class="summary-title">宿¶ç¯å¢æ¦è§</text> |
| | | <text class="summary-desc">æ¯15ç§èªå¨å·æ°ä¸æ¬¡è®¾å¤ç¯å¢æ°æ®</text> |
| | | </view> |
| | | |
| | | <view v-if="deviceCards.length" class="summary-grid"> |
| | | <view class="summary-item"> |
| | | <text class="summary-label">è®¾å¤æ°é</text> |
| | | <text class="summary-value">{{ deviceCards.length }}</text> |
| | | </view> |
| | | <view class="summary-item"> |
| | | <text class="summary-label">平忏©åº¦</text> |
| | | <text class="summary-value">{{ averageMetrics.temperature }}</text> |
| | | </view> |
| | | <view class="summary-item"> |
| | | <text class="summary-label">平忹¿åº¦</text> |
| | | <text class="summary-value">{{ averageMetrics.humidity }}</text> |
| | | </view> |
| | | <view class="summary-item"> |
| | | <text class="summary-label">å¹³åå
ç
§</text> |
| | | <text class="summary-value">{{ averageMetrics.light }}</text> |
| | | </view> |
| | | </view> |
| | | |
| | | <view v-else class="empty-block"> |
| | | <text class="empty-text">ææ ç¯å¢æ°æ®</text> |
| | | </view> |
| | | </view> |
| | | |
| | | <view class="section-block"> |
| | | <view class="section-header"> |
| | | <text class="section-title">设å¤çæµå表</text> |
| | | </view> |
| | | |
| | | <view v-if="deviceCards.length" class="device-list"> |
| | | <view |
| | | v-for="item in deviceCards" |
| | | :key="item.name" |
| | | class="device-card" |
| | | > |
| | | <view class="device-card__header"> |
| | | <view class="device-base"> |
| | | <text class="device-name">{{ item.name }}</text> |
| | | <text class="device-meta">设å¤ç¼ç ï¼{{ item.guid || "--" }}</text> |
| | | <text class="device-meta">åæ¾ä½ç½®ï¼{{ item.storageLocation || "--" }}</text> |
| | | </view> |
| | | <text class="device-tag">å¨çº¿çæµ</text> |
| | | </view> |
| | | |
| | | <view class="metrics-grid"> |
| | | <view |
| | | v-for="metric in metricConfig" |
| | | :key="metric.key" |
| | | class="metric-item" |
| | | > |
| | | <text class="metric-label">{{ metric.label }}</text> |
| | | <text class="metric-value" :style="{ color: metric.color }"> |
| | | {{ item[metric.key] }} |
| | | </text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <view v-else class="empty-block"> |
| | | <text class="empty-text">ææ è®¾å¤çæµä¿¡æ¯</text> |
| | | </view> |
| | | </view> |
| | | </scroll-view> |
| | | </view> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { computed, ref } from "vue"; |
| | | import { onHide, onShow, onUnload } from "@dcloudio/uni-app"; |
| | | import PageHeader from "@/components/PageHeader.vue"; |
| | | import { getEnvironmentalRealData } from "@/api/inventoryManagement/environmentalMonitoring"; |
| | | |
| | | const POLL_INTERVAL = 17000; |
| | | const TEMP_MARK_1 = "\u2103"; |
| | | const TEMP_MARK_2 = "\u00B0C"; |
| | | const TEMP_UNIT = TEMP_MARK_2; |
| | | |
| | | const latestDevices = ref([]); |
| | | let pollTimer = null; |
| | | |
| | | const metricConfig = [ |
| | | { key: "temperature", label: "温度", color: "#ff7a59", unit: TEMP_UNIT }, |
| | | { key: "humidity", label: "湿度", color: "#1ea7fd", unit: "%RH" }, |
| | | { key: "co2", label: "CO2", color: "#12c48b", unit: "ppm" }, |
| | | { key: "light", label: "å
ç
§", color: "#8b5cf6", unit: "Lux" }, |
| | | ]; |
| | | |
| | | const extractNumericValue = (rawValue) => { |
| | | const matched = String(rawValue ?? "").match(/-?\d+(\.\d+)?/); |
| | | return matched ? Number(matched[0]) : 0; |
| | | }; |
| | | |
| | | const normalizeMetricObject = (source, index) => { |
| | | const normalized = { |
| | | name: source?.deviceName || source?.name || source?.deviceNo || `设å¤${index + 1}`, |
| | | guid: source?.guid || source?.deviceGuid || source?.id || "", |
| | | deviceCode: source?.deviceCode || source?.deviceNo || source?.code || "", |
| | | storageLocation: source?.storageLocation || "", |
| | | temperature: 0, |
| | | humidity: 0, |
| | | co2: 0, |
| | | light: 0, |
| | | }; |
| | | |
| | | Object.entries(source || {}).forEach(([key, value]) => { |
| | | const rawText = String(value ?? ""); |
| | | |
| | | if (rawText.includes(TEMP_MARK_1) || rawText.includes(TEMP_MARK_2)) { |
| | | normalized.temperature = extractNumericValue(rawText); |
| | | return; |
| | | } |
| | | if (rawText.includes("%RH")) { |
| | | normalized.humidity = extractNumericValue(rawText); |
| | | return; |
| | | } |
| | | if (rawText.includes("ppm")) { |
| | | normalized.co2 = extractNumericValue(rawText); |
| | | return; |
| | | } |
| | | if (rawText.includes("Lux")) { |
| | | normalized.light = extractNumericValue(rawText); |
| | | return; |
| | | } |
| | | |
| | | if (key === "temperature") { |
| | | normalized.temperature = extractNumericValue(rawText); |
| | | } else if (key === "humidity") { |
| | | normalized.humidity = extractNumericValue(rawText); |
| | | } else if (key === "co2") { |
| | | normalized.co2 = extractNumericValue(rawText); |
| | | } else if (key === "light") { |
| | | normalized.light = extractNumericValue(rawText); |
| | | } |
| | | }); |
| | | |
| | | return normalized; |
| | | }; |
| | | |
| | | const formatMetric = (value, unit) => `${Number(value || 0).toFixed(2)}${unit}`; |
| | | |
| | | const deviceCards = computed(() => |
| | | latestDevices.value.map((item) => ({ |
| | | name: item.name, |
| | | guid: item.guid, |
| | | deviceCode: item.deviceCode, |
| | | storageLocation: item.storageLocation, |
| | | temperature: formatMetric(item.temperature, TEMP_UNIT), |
| | | humidity: formatMetric(item.humidity, "%RH"), |
| | | co2: formatMetric(item.co2, "ppm"), |
| | | light: formatMetric(item.light, "Lux"), |
| | | })) |
| | | ); |
| | | |
| | | const averageMetrics = computed(() => { |
| | | if (!latestDevices.value.length) { |
| | | return { |
| | | temperature: `0.00${TEMP_UNIT}`, |
| | | humidity: "0.00%RH", |
| | | light: "0.00Lux", |
| | | }; |
| | | } |
| | | |
| | | const total = latestDevices.value.reduce( |
| | | (result, item) => { |
| | | result.temperature += Number(item.temperature || 0); |
| | | result.humidity += Number(item.humidity || 0); |
| | | result.light += Number(item.light || 0); |
| | | return result; |
| | | }, |
| | | { temperature: 0, humidity: 0, light: 0 } |
| | | ); |
| | | |
| | | const count = latestDevices.value.length; |
| | | |
| | | return { |
| | | temperature: formatMetric(total.temperature / count, TEMP_UNIT), |
| | | humidity: formatMetric(total.humidity / count, "%RH"), |
| | | light: formatMetric(total.light / count, "Lux"), |
| | | }; |
| | | }); |
| | | |
| | | const fetchRealData = async () => { |
| | | try { |
| | | const res = await getEnvironmentalRealData(); |
| | | const dataList = Array.isArray(res?.data) ? res.data : []; |
| | | latestDevices.value = dataList.map((item, index) => normalizeMetricObject(item, index)); |
| | | } catch (error) { |
| | | latestDevices.value = []; |
| | | } |
| | | }; |
| | | |
| | | const clearPolling = () => { |
| | | if (pollTimer) { |
| | | clearInterval(pollTimer); |
| | | pollTimer = null; |
| | | } |
| | | }; |
| | | |
| | | const startPolling = () => { |
| | | clearPolling(); |
| | | fetchRealData(); |
| | | pollTimer = setInterval(fetchRealData, POLL_INTERVAL); |
| | | }; |
| | | |
| | | const goBack = () => { |
| | | uni.navigateBack(); |
| | | }; |
| | | |
| | | onShow(() => { |
| | | startPolling(); |
| | | }); |
| | | |
| | | onHide(() => { |
| | | clearPolling(); |
| | | }); |
| | | |
| | | onUnload(() => { |
| | | clearPolling(); |
| | | }); |
| | | |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .environment-page { |
| | | min-height: 100vh; |
| | | background: #f4f7fb; |
| | | } |
| | | |
| | | .page-scroll { |
| | | height: calc(100vh - 88rpx); |
| | | padding: 24rpx; |
| | | box-sizing: border-box; |
| | | } |
| | | |
| | | .summary-card, |
| | | .section-block { |
| | | background: #ffffff; |
| | | border-radius: 24rpx; |
| | | padding: 28rpx; |
| | | box-shadow: 0 8rpx 24rpx rgba(31, 54, 88, 0.06); |
| | | } |
| | | |
| | | .section-block { |
| | | margin-top: 24rpx; |
| | | } |
| | | |
| | | .summary-header, |
| | | .section-header { |
| | | margin-bottom: 24rpx; |
| | | } |
| | | |
| | | .summary-title, |
| | | .section-title { |
| | | display: block; |
| | | font-size: 32rpx; |
| | | font-weight: 600; |
| | | color: #1d344f; |
| | | } |
| | | |
| | | .summary-desc { |
| | | display: block; |
| | | margin-top: 12rpx; |
| | | font-size: 24rpx; |
| | | color: #7b8aa0; |
| | | } |
| | | |
| | | .summary-grid, |
| | | .metrics-grid { |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | gap: 20rpx; |
| | | } |
| | | |
| | | .summary-item { |
| | | width: calc(50% - 10rpx); |
| | | padding: 24rpx; |
| | | border-radius: 20rpx; |
| | | background: linear-gradient(135deg, #f8fbff 0%, #eef5ff 100%); |
| | | box-sizing: border-box; |
| | | } |
| | | |
| | | .summary-label, |
| | | .metric-label { |
| | | display: block; |
| | | font-size: 24rpx; |
| | | color: #7b8aa0; |
| | | } |
| | | |
| | | .summary-value, |
| | | .metric-value { |
| | | display: block; |
| | | margin-top: 14rpx; |
| | | font-size: 30rpx; |
| | | font-weight: 600; |
| | | color: #1d344f; |
| | | } |
| | | |
| | | .device-list { |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 20rpx; |
| | | } |
| | | |
| | | .device-card { |
| | | padding: 24rpx; |
| | | border-radius: 20rpx; |
| | | background: #f8fbff; |
| | | } |
| | | |
| | | .device-card__header { |
| | | display: flex; |
| | | align-items: flex-start; |
| | | justify-content: space-between; |
| | | margin-bottom: 20rpx; |
| | | gap: 20rpx; |
| | | } |
| | | |
| | | .device-base { |
| | | min-width: 0; |
| | | flex: 1; |
| | | } |
| | | |
| | | .device-name { |
| | | display: block; |
| | | font-size: 30rpx; |
| | | font-weight: 600; |
| | | color: #1d344f; |
| | | } |
| | | |
| | | .device-meta { |
| | | display: block; |
| | | margin-top: 8rpx; |
| | | font-size: 22rpx; |
| | | color: #7b8aa0; |
| | | word-break: break-all; |
| | | } |
| | | |
| | | .device-tag { |
| | | flex-shrink: 0; |
| | | padding: 8rpx 16rpx; |
| | | border-radius: 999rpx; |
| | | background: rgba(18, 196, 139, 0.12); |
| | | font-size: 22rpx; |
| | | color: #12c48b; |
| | | } |
| | | |
| | | .metric-item { |
| | | width: calc(50% - 10rpx); |
| | | padding: 20rpx; |
| | | border-radius: 16rpx; |
| | | background: #ffffff; |
| | | box-sizing: border-box; |
| | | } |
| | | |
| | | .empty-block { |
| | | padding: 60rpx 0; |
| | | text-align: center; |
| | | } |
| | | |
| | | .empty-text { |
| | | font-size: 26rpx; |
| | | color: #98a6b9; |
| | | } |
| | | </style> |
| | |
| | | getTravelStandardByTier, |
| | | } from "../_utils/travelReimburseUtils.js"; |
| | | |
| | | const userStore = useUserStore(); |
| | | // å»¶è¿åå§å userStoreï¼é¿å
卿¨¡åå è½½æ¶è°ç¨ |
| | | let userStore = null; |
| | | function getUserStore() { |
| | | if (!userStore) { |
| | | userStore = useUserStore(); |
| | | } |
| | | return userStore; |
| | | } |
| | | |
| | | function buildOverBudgetWarnings(f, detailTotal, hotelLimit, transportLimit, mealLimit) { |
| | | const warnings = []; |
| | |
| | | /** æ°å¢æ¶é»è®¤å¸¦åºå½åç»å½äººï¼åå°é人æ¥éª¤ */ |
| | | function tryApplyCurrentUser() { |
| | | if (modeRef.value === "edit" || form.applicantId) return; |
| | | const id = userStore.id; |
| | | const store = getUserStore(); |
| | | const id = store.id; |
| | | if (!id) return; |
| | | let u = userById(id); |
| | | if (!u) { |
| | | u = { |
| | | userId: id, |
| | | nickName: userStore.nickName, |
| | | userName: userStore.name, |
| | | nickName: store.nickName, |
| | | userName: store.name, |
| | | }; |
| | | } |
| | | fillApplicantFromUser(u); |
| | |
| | | <!-- 使ç¨éç¨é¡µé¢å¤´é¨ç»ä»¶ --> |
| | | <PageHeader title="ä¾åºå徿¥è¯¦æ
" |
| | | @back="goBack" /> |
| | | <!-- ç»è®¡ä¿¡æ¯ --> |
| | | <view class="summary-info" |
| | | v-if="tableData.length > 0"> |
| | | <view class="summary-item"> |
| | | <text class="summary-label">æ»è®°å½æ°</text> |
| | | <text class="summary-value">{{ tableData.length }}</text> |
| | | </view> |
| | | <view class="summary-item"> |
| | | <text class="summary-label">å¼ç¥¨æ»éé¢</text> |
| | | <text class="summary-value">{{ formatAmount(invoiceTotal) }}</text> |
| | | </view> |
| | | <view class="summary-item"> |
| | | <text class="summary-label">忬¾æ»éé¢</text> |
| | | <text class="summary-value highlight">{{ formatAmount(receiptTotal) }}</text> |
| | | </view> |
| | | <view class="summary-item"> |
| | | <text class="summary-label">åºæ¶æ»éé¢</text> |
| | | <text class="summary-value danger">{{ formatAmount(unReceiptTotal) }}</text> |
| | | </view> |
| | | </view> |
| | | <!-- 忬¾è®°å½æç»å表 --> |
| | | <!-- éè´å°è´¦æç» --> |
| | | <view class="detail-list" |
| | | v-if="tableData.length > 0"> |
| | | <view v-for="(item, index) in tableData" |
| | |
| | | size="16" |
| | | color="#ffffff"></up-icon> |
| | | </view> |
| | | <text class="item-index">{{ index + 1 }}</text> |
| | | <text class="item-index">{{ item.purchaseContractNumber }}</text> |
| | | </view> |
| | | <view class="item-date">{{ item.happenTime }}</view> |
| | | <view class="item-status"> |
| | | <text class="status-tag" |
| | | :class="getReceiptStatusClass(item.status)">{{ receiptStatusText[item.status] || 'æªç¥ç¶æ' }}</text> |
| | | </view> |
| | | </view> |
| | | <up-divider></up-divider> |
| | | <view class="item-details"> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">å票éé¢(å
)</text> |
| | | <text class="detail-value">{{ formatAmount(item.invoiceAmount) }}</text> |
| | | <text class="detail-label">ååç¾è®¢æ¥æ</text> |
| | | <text class="detail-value">{{ item.executionDate }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">仿¬¾éé¢(å
)</text> |
| | | <text class="detail-value highlight">{{ formatAmount(item.currentPaymentAmount) }}</text> |
| | | <text class="detail-label">项ç®åç§°</text> |
| | | <text class="detail-value">{{ item.projectName }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">åºä»éé¢(å
)</text> |
| | | <text class="detail-value danger">{{ formatAmount(item.payableAmount) }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">åçæ¥æ</text> |
| | | <text class="detail-value">{{ item.paymentDate }}</text> |
| | | <text class="detail-label">ååéé¢(å
)</text> |
| | | <text class="detail-value">{{ formatAmount(item.contractAmount) }}</text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <view v-else |
| | | class="no-data"> |
| | | <text>ææ åæ¬¾è®°å½</text> |
| | | <text>ææ éè´å°è´¦è®°å½</text> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, computed, onMounted } from "vue"; |
| | | import { onShow } from "@dcloudio/uni-app"; |
| | | import { |
| | | paymentLedgerList, |
| | | paymentRecordList, |
| | | } from "@/api/procurementManagement/paymentLedger"; |
| | | import { ref, onMounted } from "vue"; |
| | | import { gePurchaseListPage } from "@/api/procurementManagement/invoiceEntry.js"; |
| | | |
| | | // 客æ·ä¿¡æ¯ |
| | | const supplierId = ref(""); |
| | | const supplierName = ref(""); |
| | | |
| | | // è¡¨æ ¼æ°æ® |
| | | const tableData = ref([]); |
| | | |
| | | const invoiceTotal = computed(() => { |
| | | return tableData.value.reduce((sum, item) => { |
| | | return sum + (parseFloat(item.invoiceAmount) || 0); |
| | | }, 0); |
| | | }); |
| | | // æ¶è´§ç¶æææ¬æ å° |
| | | const receiptStatusText = { |
| | | 1: 'å¾
æ¶è´§', |
| | | 2: 'æ¶è´§ä¸', |
| | | 3: 'å·²æ¶è´§' |
| | | }; |
| | | |
| | | const receiptTotal = computed(() => { |
| | | return tableData.value.reduce((sum, item) => { |
| | | return sum + (parseFloat(item.receiptAmount) || 0); |
| | | }, 0); |
| | | }); |
| | | |
| | | const unReceiptTotal = computed(() => { |
| | | return tableData.value.reduce((sum, item) => { |
| | | return sum + (parseFloat(item.unReceiptAmount) || 0); |
| | | }, 0); |
| | | }); |
| | | // æ¶è´§ç¶ææ ç¾æ ·å¼ |
| | | const getReceiptStatusClass = (status) => { |
| | | const classMap = { |
| | | 1: 'status-info', |
| | | 2: 'status-warning', |
| | | 3: 'status-success' |
| | | }; |
| | | return classMap[status] || 'status-info'; |
| | | }; |
| | | |
| | | // è¿åä¸ä¸é¡µ |
| | | const goBack = () => { |
| | | uni.removeStorageSync("supplierId"); |
| | | uni.removeStorageSync("supplierName"); |
| | | uni.navigateBack(); |
| | | }; |
| | | |
| | | // è·å页é¢åæ° |
| | | const getPageParams = () => { |
| | | // 仿¬å°åå¨è·åä¾åºåID |
| | | const storedSupplierId = uni.getStorageSync("supplierId"); |
| | | if (storedSupplierId) { |
| | | supplierId.value = storedSupplierId; |
| | | const storedSupplierName = uni.getStorageSync("supplierName"); |
| | | if (storedSupplierName) { |
| | | supplierName.value = storedSupplierName; |
| | | } |
| | | }; |
| | | |
| | | // æ¥è¯¢å表 |
| | | const getList = () => { |
| | | if (!supplierId.value) { |
| | | if (!supplierName.value) { |
| | | uni.showToast({ |
| | | title: "客æ·ä¿¡æ¯ç¼ºå¤±", |
| | | title: "ä¾åºåä¿¡æ¯ç¼ºå¤±", |
| | | icon: "error", |
| | | }); |
| | | return; |
| | | } |
| | | showLoadingToast("å è½½ä¸..."); |
| | | paymentRecordList({ supplierId: supplierId.value }) |
| | | gePurchaseListPage({ supplierName: supplierName.value, current: 1, size: 1000 }) |
| | | .then(res => { |
| | | tableData.value = res.data; |
| | | let orders = []; |
| | | if (res.data) { |
| | | if (Array.isArray(res.data)) { |
| | | orders = res.data; |
| | | } else if (res.data.records && Array.isArray(res.data.records)) { |
| | | orders = res.data.records; |
| | | } |
| | | } |
| | | tableData.value = orders; |
| | | closeToast(); |
| | | }) |
| | | .catch(() => { |
| | |
| | | |
| | | .u-divider { |
| | | margin: 0 !important; |
| | | } |
| | | |
| | | .summary-info { |
| | | background: #ffffff; |
| | | margin: 20px 20px 0 20px; |
| | | border-radius: 12px; |
| | | padding: 16px; |
| | | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); |
| | | } |
| | | |
| | | .summary-item { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | margin-bottom: 8px; |
| | | |
| | | &:last-child { |
| | | margin-bottom: 0; |
| | | } |
| | | } |
| | | |
| | | .summary-label { |
| | | font-size: 14px; |
| | | color: #666; |
| | | } |
| | | |
| | | .summary-value { |
| | | font-size: 14px; |
| | | color: #333; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | .summary-value.highlight { |
| | | color: #2979ff; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | .summary-value.danger { |
| | | color: #ff4757; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | .detail-list { |
| | |
| | | color: #666; |
| | | } |
| | | |
| | | .item-status { |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | .status-tag { |
| | | font-size: 12px; |
| | | padding: 2px 8px; |
| | | border-radius: 4px; |
| | | } |
| | | |
| | | .status-success { |
| | | color: #67c23a; |
| | | background: rgba(103, 194, 58, 0.1); |
| | | } |
| | | |
| | | .status-warning { |
| | | color: #e6a23c; |
| | | background: rgba(230, 162, 60, 0.1); |
| | | } |
| | | |
| | | .status-info { |
| | | color: #909399; |
| | | background: rgba(144, 147, 153, 0.1); |
| | | } |
| | | |
| | | .item-details { |
| | | padding: 16px 0; |
| | | } |
| | |
| | | text-align: right; |
| | | flex: 1; |
| | | margin-left: 16px; |
| | | } |
| | | |
| | | .detail-value.highlight { |
| | | color: #2979ff; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | .detail-value.danger { |
| | | color: #ff4757; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | .no-data { |
| | |
| | | <view class="item-details"> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">ååéé¢(å
)</text> |
| | | <text class="detail-value">{{ formattedNumber(item.invoiceAmount) }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">仿¬¾éé¢(å
)</text> |
| | | <text class="detail-value">{{ formattedNumber(item.paymentAmount) }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">åºä»éé¢(å
)</text> |
| | | <text class="detail-value highlight danger">{{ formattedNumber(item.payableAmount) }}</text> |
| | | <text class="detail-value">{{ formattedNumber(item.contractAmounts) }}</text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | |
| | | |
| | | const rowClickMethod = (row) => { |
| | | // ä½¿ç¨ uni.setStorageSync åå¨ä¾åºåä¿¡æ¯ |
| | | uni.setStorageSync('supplierId', row.supplierId); |
| | | uni.setStorageSync('supplierName', row.supplierName); |
| | | // 跳转å°åæ¬¾è®°å½æç»é¡µé¢ |
| | | uni.navigateTo({ |
| | | url: '/pages/procurementManagement/paymentLedger/detail' |
| | |
| | | <u-button type="primary" |
| | | size="small" |
| | | class="action-btn" |
| | | :disabled="item.inspectState" |
| | | :disabled="!!item.inspectState" |
| | | @click.stop="startInspection(item)"> |
| | | ç¼è¾ |
| | | </u-button> |
| | |
| | | <u-button type="success" |
| | | size="small" |
| | | class="action-btn" |
| | | :disabled="item.inspectState" |
| | | :disabled="!!item.inspectState" |
| | | @click.stop="submitInspection(item)"> |
| | | æäº¤ |
| | | </u-button> |
| | |
| | | <u-button type="warning" |
| | | size="small" |
| | | class="action-btn" |
| | | :disabled="item.inspectState || item.checkName !== ''" |
| | | :disabled="!!item.inspectState || item.checkName !== ''" |
| | | @click.stop="assignInspector(item)"> |
| | | åé
æ£éªå |
| | | </u-button> |
| | |
| | | <template> |
| | | <view class="material-inspection-page"> |
| | | <!-- 使ç¨éç¨é¡µé¢å¤´é¨ç»ä»¶ --> |
| | | <PageHeader title="åæææ£éª" |
| | | <PageHeader title="åææ£éª" |
| | | @back="goBack" /> |
| | | <!-- æç´¢åºå --> |
| | | <view class="search-section"> |
| | |
| | | <u-button type="primary" |
| | | size="small" |
| | | class="action-btn" |
| | | :disabled="item.inspectState" |
| | | :disabled="!!item.inspectState" |
| | | @click.stop="startInspection(item)"> |
| | | ç¼è¾ |
| | | </u-button> |
| | |
| | | <u-button type="success" |
| | | size="small" |
| | | class="action-btn" |
| | | :disabled="item.inspectState" |
| | | :disabled="!!item.inspectState" |
| | | @click.stop="submitInspection(item)"> |
| | | æäº¤ |
| | | </u-button> |
| | |
| | | <u-button type="warning" |
| | | size="small" |
| | | class="action-btn" |
| | | :disabled="item.inspectState || item.checkName !== ''" |
| | | :disabled="!!item.inspectState || item.checkName !== ''" |
| | | @click.stop="assignInspector(item)"> |
| | | åé
æ£éªå |
| | | </u-button> |
| | |
| | | <u-button type="primary" |
| | | size="small" |
| | | class="action-btn" |
| | | :disabled="item.inspectState" |
| | | :disabled="!!item.inspectState" |
| | | @click.stop="startInspection(item)"> |
| | | ç¼è¾ |
| | | </u-button> |
| | |
| | | <u-button type="success" |
| | | size="small" |
| | | class="action-btn" |
| | | :disabled="item.inspectState" |
| | | :disabled="!!item.inspectState" |
| | | @click.stop="submitInspection(item)"> |
| | | æäº¤ |
| | | </u-button> |
| | |
| | | <u-button type="warning" |
| | | size="small" |
| | | class="action-btn" |
| | | :disabled="item.inspectState || item.checkName !== ''" |
| | | :disabled="!!item.inspectState || item.checkName !== ''" |
| | | @click.stop="assignInspector(item)"> |
| | | åé
æ£éªå |
| | | </u-button> |
| | |
| | | <!-- 使ç¨éç¨é¡µé¢å¤´é¨ç»ä»¶ --> |
| | | <PageHeader title="客æ·å¾æ¥è¯¦æ
" |
| | | @back="goBack" /> |
| | | <!-- ç»è®¡ä¿¡æ¯ --> |
| | | <view class="summary-info" |
| | | v-if="tableData.length > 0"> |
| | | <view class="summary-item"> |
| | | <text class="summary-label">æ»è®°å½æ°</text> |
| | | <text class="summary-value">{{ tableData.length }}</text> |
| | | </view> |
| | | <view class="summary-item"> |
| | | <text class="summary-label">å¼ç¥¨æ»éé¢</text> |
| | | <text class="summary-value">{{ formatAmount(invoiceTotal) }}</text> |
| | | </view> |
| | | <view class="summary-item"> |
| | | <text class="summary-label">忬¾æ»éé¢</text> |
| | | <text class="summary-value highlight">{{ formatAmount(receiptTotal) }}</text> |
| | | </view> |
| | | <view class="summary-item"> |
| | | <text class="summary-label">åºæ¶æ»éé¢</text> |
| | | <text class="summary-value danger">{{ formatAmount(unReceiptTotal) }}</text> |
| | | </view> |
| | | </view> |
| | | <!-- 忬¾è®°å½æç»å表 --> |
| | | <!-- åè´§å°è´¦æç» --> |
| | | <view class="detail-list" |
| | | v-if="tableData.length > 0"> |
| | | <view v-for="(item, index) in tableData" |
| | |
| | | size="16" |
| | | color="#ffffff"></up-icon> |
| | | </view> |
| | | <text class="item-index">{{ index + 1 }}</text> |
| | | <text class="item-index">{{ item.salesContractNo }}</text> |
| | | </view> |
| | | <view class="item-date">{{ item.happenTime }}</view> |
| | | <view class="item-status"> |
| | | <text class="status-tag" |
| | | :class="getStatusClass(item.status)">{{ item.status || '--' }}</text> |
| | | </view> |
| | | </view> |
| | | <up-divider></up-divider> |
| | | <view class="item-details"> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">å¼ç¥¨éé¢(å
)</text> |
| | | <text class="detail-value">{{ formatAmount(item.invoiceTotal) }}</text> |
| | | <text class="detail-label">客æ·åç§°</text> |
| | | <text class="detail-value">{{ item.customerName }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">忬¾éé¢(å
)</text> |
| | | <text class="detail-value highlight">{{ formatAmount(item.receiptPaymentAmount) }}</text> |
| | | <text class="detail-label">产ååç§°</text> |
| | | <text class="detail-value">{{ item.productName }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">åºæ¶éé¢(å
)</text> |
| | | <text class="detail-value danger">{{ formatAmount(item.unReceiptPaymentAmount) }}</text> |
| | | <text class="detail-label">è§æ ¼åå·</text> |
| | | <text class="detail-value">{{ item.specificationModel }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">åçæ¥æ</text> |
| | | <text class="detail-value">{{ item.receiptPaymentDate }}</text> |
| | | <text class="detail-label">åè´§æ¶é´</text> |
| | | <text class="detail-value">{{ item.shippingDate }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">åè´§æ°é</text> |
| | | <text class="detail-value">{{ item.totalQuantity }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">åºåºåå·</text> |
| | | <text class="detail-value">{{ item.outboundBatches }}</text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <view v-else |
| | | class="no-data"> |
| | | <text>ææ åæ¬¾è®°å½</text> |
| | | <text>ææ åè´§è®°å½</text> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, computed, onMounted } from "vue"; |
| | | import { ref, onMounted } from "vue"; |
| | | import { onShow } from "@dcloudio/uni-app"; |
| | | import { customerInteractions } from "@/api/salesManagement/receiptPayment.js"; |
| | | import { deliveryLedgerListPage } from "@/api/salesManagement/deliveryLedger.js"; |
| | | |
| | | // 客æ·ä¿¡æ¯ |
| | | const customerId = ref(""); |
| | | |
| | | // è¡¨æ ¼æ°æ® |
| | | const tableData = ref([]); |
| | | |
| | | const invoiceTotal = computed(() => { |
| | | return tableData.value.reduce((sum, item) => { |
| | | return sum + (parseFloat(item.invoiceTotal) || 0); |
| | | }, 0); |
| | | }); |
| | | |
| | | const receiptTotal = computed(() => { |
| | | return tableData.value.reduce((sum, item) => { |
| | | return sum + (parseFloat(item.receiptPaymentAmount) || 0); |
| | | }, 0); |
| | | }); |
| | | |
| | | const unReceiptTotal = computed(() => { |
| | | return tableData.value.reduce((sum, item) => { |
| | | return sum + (parseFloat(item.unReceiptPaymentAmount) || 0); |
| | | }, 0); |
| | | }); |
| | | |
| | | // è¿åä¸ä¸é¡µ |
| | | const goBack = () => { |
| | |
| | | |
| | | // è·å页é¢åæ° |
| | | const getPageParams = () => { |
| | | // 仿¬å°åå¨è·å客æ·ID |
| | | const storedCustomerId = uni.getStorageSync("customerId"); |
| | | if (storedCustomerId) { |
| | | customerId.value = storedCustomerId; |
| | |
| | | } |
| | | |
| | | showLoadingToast("å è½½ä¸..."); |
| | | const param = { |
| | | deliveryLedgerListPage({ |
| | | customerId: customerId.value, |
| | | current: -1, |
| | | size: -1, |
| | | }; |
| | | |
| | | customerInteractions(param) |
| | | current: 1, |
| | | size: 1000, |
| | | }) |
| | | .then(res => { |
| | | tableData.value = res.data; |
| | | let orders = []; |
| | | if (res.data) { |
| | | if (Array.isArray(res.data)) { |
| | | orders = res.data; |
| | | } else if (res.data.records && Array.isArray(res.data.records)) { |
| | | orders = res.data.records; |
| | | } |
| | | } |
| | | tableData.value = orders; |
| | | closeToast(); |
| | | }) |
| | | .catch(() => { |
| | |
| | | }); |
| | | }; |
| | | |
| | | // æ ¼å¼åéé¢ |
| | | const formatAmount = amount => { |
| | | return amount ? parseFloat(amount).toFixed(2) : "0.00"; |
| | | // åè´§ç¶ææ ·å¼ |
| | | const getStatusClass = (status) => { |
| | | const statusMap = { |
| | | 'å·²åè´§': 'status-success', |
| | | 'å®¡æ ¸éè¿': 'status-success', |
| | | 'å®¡æ ¸ä¸': 'status-warning', |
| | | 'å®¡æ ¸ä¸éè¿': 'status-danger', |
| | | }; |
| | | return statusMap[status] || 'status-info'; |
| | | }; |
| | | |
| | | // æ¾ç¤ºå è½½æç¤º |
| | |
| | | |
| | | .u-divider { |
| | | margin: 0 !important; |
| | | } |
| | | |
| | | .summary-info { |
| | | background: #ffffff; |
| | | margin: 20px 20px 0 20px; |
| | | border-radius: 12px; |
| | | padding: 16px; |
| | | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); |
| | | } |
| | | |
| | | .summary-item { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | margin-bottom: 8px; |
| | | |
| | | &:last-child { |
| | | margin-bottom: 0; |
| | | } |
| | | } |
| | | |
| | | .summary-label { |
| | | font-size: 14px; |
| | | color: #666; |
| | | } |
| | | |
| | | .summary-value { |
| | | font-size: 14px; |
| | | color: #333; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | .summary-value.highlight { |
| | | color: #2979ff; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | .summary-value.danger { |
| | | color: #ff4757; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | .detail-list { |
| | |
| | | color: #666; |
| | | } |
| | | |
| | | .item-status { |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | .status-tag { |
| | | font-size: 12px; |
| | | padding: 2px 8px; |
| | | border-radius: 4px; |
| | | } |
| | | |
| | | .status-success { |
| | | color: #67c23a; |
| | | background: rgba(103, 194, 58, 0.1); |
| | | } |
| | | |
| | | .status-warning { |
| | | color: #e6a23c; |
| | | background: rgba(230, 162, 60, 0.1); |
| | | } |
| | | |
| | | .status-danger { |
| | | color: #f56c6c; |
| | | background: rgba(245, 108, 108, 0.1); |
| | | } |
| | | |
| | | .status-info { |
| | | color: #909399; |
| | | background: rgba(144, 147, 153, 0.1); |
| | | } |
| | | |
| | | .item-details { |
| | | padding: 16px 0; |
| | | } |
| | |
| | | margin-left: 16px; |
| | | } |
| | | |
| | | .detail-value.highlight { |
| | | color: #2979ff; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | .detail-value.danger { |
| | | color: #ff4757; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | .no-data { |
| | | padding: 40px 0; |
| | | text-align: center; |
| | | color: #999; |
| | | } |
| | | |
| | | </style> |
| | |
| | | <up-divider></up-divider> |
| | | <view class="item-details"> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">å¼ç¥¨éé¢(å
)</text> |
| | | <text class="detail-value">{{ formattedNumber(item.invoiceTotal) }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">忬¾éé¢(å
)</text> |
| | | <text class="detail-value">{{ formattedNumber(item.receiptPaymentAmount) }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">åºæ¶éé¢(å
)</text> |
| | | <text class="detail-value highlight danger">{{ formattedNumber(item.unReceiptPaymentAmount) }}</text> |
| | | <text class="detail-label">ååéé¢(å
)</text> |
| | | <text class="detail-value">{{ formattedNumber(item.contractAmounts) }}</text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | |
| | | <script setup> |
| | | import { onMounted, ref, reactive, toRefs } from "vue"; |
| | | import { onShow } from "@dcloudio/uni-app"; |
| | | import { invoiceLedgerSalesAccount } from "@/api/salesManagement/invoiceLedger"; |
| | | import { customewTransactions } from "@/api/salesManagement/indicatorStats.js"; |
| | | |
| | | const tableData = ref([]); |
| | | |
| | |
| | | |
| | | const getList = () => { |
| | | showLoadingToast("å è½½ä¸..."); |
| | | invoiceLedgerSalesAccount({ ...searchForm.value, ...page }) |
| | | customewTransactions({ ...searchForm.value, ...page }) |
| | | .then(res => { |
| | | tableData.value = res.data.records; |
| | | closeToast(); |
| | |
| | | |
| | | const rowClickMethod = row => { |
| | | // ä½¿ç¨ uni.setStorageSync åå¨å®¢æ·ä¿¡æ¯ |
| | | uni.setStorageSync("customerId", row.id); |
| | | uni.setStorageSync("customerId", row.customerId); |
| | | // 跳转å°åæ¬¾è®°å½æç»é¡µé¢ |
| | | uni.navigateTo({ |
| | | url: "/pages/sales/receiptPaymentLedger/detail", |
| | |
| | | |
| | | <script setup> |
| | | import { ref, onMounted, nextTick, reactive, computed } from "vue"; |
| | | import { onShow } from "@dcloudio/uni-app"; |
| | | import { userLoginFacotryList } from "@/api/login"; |
| | | import { getProductWorkOrderById } from "@/api/productionManagement/productionReporting"; |
| | | import { createVersionUpgradeChecker } from "@/utils/versionUpgrade"; |
| | | import DownloadProgressMask from "@/components/DownloadProgressMask.vue"; |
| | | import { OA_WORKBENCH_ITEMS } from "@/config/oaWorkbench.js"; |
| | | import modal from "@/plugins/modal"; |
| | | import useUserStore from "@/store/modules/user"; |
| | | |
| | | const userStore = useUserStore(); |
| | | const { triggerVersionCheck } = createVersionUpgradeChecker({ logPrefix: "[version-works]" }); |
| | | const show = ref(false); |
| | | const factoryList = ref([]); |
| | | const factoryListTem = ref([]); |
| | |
| | | icon: "/static/images/icon/kucunguanli.svg", |
| | | label: "åºå管ç", |
| | | }, |
| | | { |
| | | icon: "/static/images/icon/weixianzuoye.svg", |
| | | label: "ç¯å¢æ£æµ", |
| | | }, |
| | | ]); |
| | | |
| | | const humanResourcesItems = reactive([ |
| | |
| | | icon: "/static/images/icon/hetongguanli.svg", |
| | | label: "åå管ç", |
| | | }, |
| | | { |
| | | icon: "/static/images/icon/hetongguanli.svg", |
| | | label: "转æ£ç³è¯·", |
| | | path: "/pages/oa/HrManage/regular-apply/index", |
| | | }, |
| | | { |
| | | icon: "/static/images/icon/renyuanxinzi.svg", |
| | | label: "è°å²ç³è¯·", |
| | | path: "/pages/oa/HrManage/transfer-apply/index", |
| | | }, |
| | | { |
| | | icon: "/static/images/icon/gongchuguanli.svg", |
| | | label: "å·¥ä½äº¤æ¥", |
| | | path: "/pages/oa/HrManage/work-handover/index", |
| | | }, |
| | | ]); |
| | | const qualityItems = reactive([ |
| | | { |
| | | icon: "/static/images/icon/yuancailiaojianyan.svg", |
| | | label: "åæææ£éª", |
| | | label: "åææ£éª", |
| | | }, |
| | | { |
| | | icon: "/static/images/icon/guochengjianyan.svg", |
| | |
| | | { |
| | | icon: "/static/images/icon/kehubaifang.svg", |
| | | label: "å®¢æ·æè®¿", |
| | | }, |
| | | { |
| | | icon: "/static/images/icon/qingjiaguanli.svg", |
| | | label: "请åç³è¯·", |
| | | path: "/pages/oa/AttendManage/leave-apply/index", |
| | | }, |
| | | { |
| | | icon: "/static/images/icon/dakaqiandao.svg", |
| | | label: "å çç³è¯·", |
| | | path: "/pages/oa/AttendManage/overtime-apply/index", |
| | | }, |
| | | { |
| | | icon: "/static/images/icon/chuchaiguanli.svg", |
| | | label: "å·®æ
æ¥é", |
| | | path: "/pages/oa/ReimburseManage/travel-reimburse/index", |
| | | }, |
| | | { |
| | | icon: "/static/images/icon/baoxiaoguanli.svg", |
| | | label: "è´¹ç¨æ¥é", |
| | | path: "/pages/oa/ReimburseManage/cost-reimburse/index", |
| | | }, |
| | | { |
| | | icon: "/static/images/icon/xietongshenpi.svg", |
| | | label: "审æ¹å表", |
| | | path: "/pages/oa/ApproveManage/approve-list/index", |
| | | }, |
| | | { |
| | | icon: "/static/images/icon/guizhangzhidu.svg", |
| | | label: "å®¡æ¹æ¨¡æ¿", |
| | | path: "/pages/oa/ApproveManage/approve-template/index", |
| | | }, |
| | | ]); |
| | | |
| | |
| | | url: "/pages/humanResources/contractManagement/index", |
| | | }); |
| | | break; |
| | | case "åæææ£éª": |
| | | case "åææ£éª": |
| | | uni.navigateTo({ |
| | | url: "/pages/qualityManagement/materialInspection/index", |
| | | }); |
| | |
| | | url: "/pages/inventoryManagement/stockManagement/index", |
| | | }); |
| | | break; |
| | | case "ç¯å¢æ£æµ": |
| | | uni.navigateTo({ |
| | | url: "/pages/inventoryManagement/environmentalMonitoring/index", |
| | | }); |
| | | break; |
| | | case "åé¦ç»è®°": |
| | | uni.navigateTo({ |
| | | url: "/pages/customerService/feedbackRegistration/index", |
| | |
| | | currentLoginTime: "", |
| | | roles: Array(), |
| | | permissions: [], |
| | | routers: [], // è·¯ç±æéæ°æ® |
| | | routers: [], |
| | | }), |
| | | actions: { |
| | | // é¨é¨ç»å½ |
| | | loginCheckFactory(userInfo: any) { |
| | | const userName = userInfo.userName.trim(); |
| | | const password = userInfo.password; |
| | |
| | | return new Promise((resolve, reject) => { |
| | | loginCheckFactory(userName, password, factoryId) |
| | | .then((res: any) => { |
| | | const token = res.token || res.data?.token; |
| | | const token = res.token || (res.data && res.data.token); |
| | | if (token) { |
| | | setToken(token); |
| | | this.token = token; |
| | |
| | | }); |
| | | }); |
| | | }, |
| | | // è·åç¨æ·ä¿¡æ¯ |
| | | getInfo() { |
| | | return new Promise((resolve, reject) => { |
| | | getInfo() |
| | |
| | | }); |
| | | }); |
| | | }, |
| | | // éåºç³»ç» |
| | | logOut() { |
| | | return new Promise<null>((resolve, reject) => { |
| | | logout() |
| | |
| | | const seconds = String(now.getSeconds()).padStart(2, "0"); // ç§æ°è¡¥é¶ |
| | | return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; |
| | | }, |
| | | // è·åè·¯ç±æé |
| | | getRouters() { |
| | | return new Promise((resolve, reject) => { |
| | | getRoutersApi() |
| | |
| | | } |
| | | |
| | | async function getCurrentVersion(logPrefix) { |
| | | let currentVersion = config?.appInfo?.version || "1.0.0"; |
| | | let currentVersion = (config && config.appInfo && config.appInfo.version) || "1.0.0"; |
| | | console.log(`${logPrefix} å¼å§è·åå½åçæ¬ï¼é»è®¤å¼:`, currentVersion); |
| | | // #ifdef MP-WEIXIN |
| | | try { |
| | | const accountInfo = uni.getAccountInfoSync(); |
| | | if (accountInfo?.miniProgram?.version) { |
| | | if (accountInfo && accountInfo.miniProgram && accountInfo.miniProgram.version) { |
| | | currentVersion = accountInfo.miniProgram.version; |
| | | console.log(`${logPrefix} å½åç¯å¢=MP-WEIXINï¼çæ¬=`, currentVersion); |
| | | return currentVersion; |
| | |
| | | // APP-PLUS ä¸ï¼plus.runtime.version 䏿¯ä¸å¡çæ¬å·ï¼ç»å¸¸æ¯è¿è¡æ¶/SDKçæ¬ï¼ï¼ |
| | | // è¿éæ¹ç¨ getProperty åç³»ç»å±é¢ç app versionã |
| | | // @ts-ignore |
| | | if (plus?.runtime?.getProperty) { |
| | | if (plus && plus.runtime && plus.runtime.getProperty) { |
| | | // @ts-ignore |
| | | const appid = plus.runtime.appid; |
| | | const appInfo = await new Promise((resolve) => { |
| | | // @ts-ignore |
| | | plus.runtime.getProperty(appid, (info) => resolve(info || {})); |
| | | }); |
| | | const v = appInfo?.version || appInfo?.versionName || appInfo?.appVersion || ""; |
| | | const v = (appInfo && appInfo.version) || (appInfo && appInfo.versionName) || (appInfo && appInfo.appVersion) || ""; |
| | | if (v) { |
| | | currentVersion = String(v); |
| | | console.log(`${logPrefix} å½åç¯å¢=APP-PLUSï¼çæ¬=`, currentVersion); |
| | |
| | | }, |
| | | (err) => { |
| | | console.log(`${logPrefix} å®è£
失败:`, err); |
| | | uni.showToast({ title: err?.message || "å®è£
æ´æ°å
失败", icon: "none" }); |
| | | uni.showToast({ title: (err && err.message) || "å®è£
æ´æ°å
失败", icon: "none" }); |
| | | } |
| | | ); |
| | | // #endif |
| | |
| | | if (!u) return ""; |
| | | // å·²ç»æ¯ç»å¯¹å°åï¼ç´æ¥è¿å |
| | | if (/^https?:\/\//i.test(u)) return u; |
| | | const base = String(config?.fileUrl || config?.baseUrl || "").replace(/\/+$/, ""); |
| | | const base = String((config && config.fileUrl) || (config && config.baseUrl) || "").replace(/\/+$/, ""); |
| | | const path = u.startsWith("/") ? u : `/${u}`; |
| | | return `${base}${path}`; |
| | | } |
| | |
| | | build: { |
| | | minify: true, |
| | | outDir: 'dist', |
| | | target: 'es2015', |
| | | }, |
| | | esbuild: { |
| | | target: 'es2015', |
| | | }, |
| | | server: { |
| | | port: '80' |
| | |
| | | css: { |
| | | preprocessorOptions: { |
| | | scss: { |
| | | api: 'modern-compiler' |
| | | api: 'legacy' |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | optimizeDeps: { |
| | | esbuildOptions: { |
| | | target: 'es2015', |
| | | }, |
| | | }, |
| | | } |
| | | }) |
| | | }) |