From 7c2192a2f000d94add173b77b6bd4c8c4fc6a5e4 Mon Sep 17 00:00:00 2001 From: xwt <2740516069@qq.com> Date: 星期三, 17 九月 2025 09:41:47 +0800 Subject: [PATCH] SJ穴模数 --- pages/QC/XJ/Add.vue | 1423 ++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 files changed, 1,260 insertions(+), 163 deletions(-) diff --git a/pages/QC/XJ/Add.vue b/pages/QC/XJ/Add.vue index 7140538..75c91a8 100644 --- a/pages/QC/XJ/Add.vue +++ b/pages/QC/XJ/Add.vue @@ -40,20 +40,16 @@ <view v-else class="info-value">{{ formData.daa020 }}</view> </view> <view class="info-item"> - <view class="info-label">鐗╂枡缂栫爜</view> - <picker v-if="isUpdate" class="picker-input" name="selector" :range="ItemList" - @change="onItemChange"> - <view class="picker-value">{{ ItemList[ItemIndex] || '璇烽�夋嫨' }}</view> - </picker> - <view v-else class="info-value">{{ formData.itemNo }}</view> - </view> - <view class="info-item"> <view class="info-label">宸ュ崟鍗曞彿</view> <picker v-if="isUpdate" class="picker-input" name="selector" :range="DAA001List" @change="onDaa001Change"> <view class="picker-value">{{ DAA001List[DAA001Index] || '璇烽�夋嫨' }}</view> </picker> <view v-else class="info-value">{{ formData.billNo }}</view> + </view> + <view class="info-item"> + <view class="info-label">鐗╂枡缂栫爜</view> + <view class="info-value">{{ formData.itemNo }}</view> </view> <view class="info-item"> <view class="info-label">鐗╂枡鍚嶇О</view> @@ -101,7 +97,7 @@ <view v-if="item.result==null || item.result=='鏈畬鎴�'" class="watermark pending"> {{ getStatusText(item.result) }} </view> - <view class="description-text">{{ item.projName }}</view> + <view class="description-text">{{ getInspectionDescription(item) }}</view> </td> <td> <button v-if="item.isCheck >= item.levelNum" class="record-btn" @click="toDetail(item)">鏌ョ湅</button> @@ -114,17 +110,26 @@ </view> </view> - <!-- 鎿嶄綔鎸夐挳 --> - <view class="action-buttons"> - <button class="action-btn primary" v-if="isUpdate && !isShowTable" @click="getItem">鍒涘缓妫�楠屽崟骞剁敓鎴愰儴鍒嗛粯璁ゅ��</button> - <button class="action-btn secondary" v-if="!isUpdate && !isShowTable" @click="toImage">涓婁紶/鏌ョ湅鍥剧墖</button> - <button class="action-btn danger" v-if="!isUpdate && !formData.fcheckResu && !isShowTable" @click="removeXJ">鍒犻櫎鍗曟嵁</button> - <button class="action-btn warning" v-if="!isUpdate && !isShowTable" @click="saveRemarks">娣诲姞涓嶅悎鏍兼弿杩�</button> - <button class="action-btn primary" v-if="isShowTable" @click="getTable">鑾峰彇妫�楠岄」鐩�</button> - <button class="action-btn primary" v-if="isShowTable && isUpdate" @click="saveTable">鐢熸垚妫�楠岄」鐩�</button> - <button class="action-btn success" v-if="!isUpdate && !isShowTable" @click="getGenUpdate">鑾峰彇妫�楠岄」鐩�</button> - <button class="action-btn success" v-if="!isUpdate && !isShowTable" @click="submitInspection">鎻愪氦妫�楠�</button> - </view> + <!-- 鎿嶄綔鎸夐挳 --> + <view class="action-buttons"> + <!-- 鏂板缓鍗曟嵁鏃剁殑鍒涘缓鎸夐挳 --> + <button class="action-btn primary" v-if="isUpdate && !isShowTable" @click="save"> + 鍒涘缓妫�楠屽崟骞剁敓鎴愰儴鍒嗛粯璁ゅ�� + </button> + + <!-- 宸叉湁鍗曟嵁鐨勬搷浣滄寜閽� --> + <button class="action-btn secondary" v-if="!isUpdate && !isShowTable" @click="toImage">涓婁紶/鏌ョ湅鍥剧墖</button> + <button class="action-btn secondary" v-if="!isUpdate && !isShowTable" @click="viewAttachmentInfo">鏌ョ湅闄勪欢淇℃伅</button> + + <button class="action-btn danger" v-if="!isUpdate && !formData.fcheckResu && !isShowTable && formData.fsubmit !== 1" @click="removeXJ">鍒犻櫎鍗曟嵁</button> + <button class="action-btn warning" v-if="!isUpdate && !isShowTable && formData.fsubmit !== 1" @click="saveRemarks">娣诲姞涓嶅悎鏍兼弿杩�</button> + + <!-- 妫�楠岄」鐩鐞嗘寜閽� --> + <button class="action-btn primary" v-if="isShowTable" @click="getTable">鑾峰彇妫�楠岄」鐩�</button> + <button class="action-btn primary" v-if="isShowTable && isUpdate" @click="saveTable">鐢熸垚妫�楠岄」鐩�</button> + <button class="action-btn success" v-if="!isUpdate && !isShowTable && formData.fsubmit !== 1" @click="getGenUpdate">鑾峰彇妫�楠岄」鐩�</button> + <button class="action-btn success" v-if="!isUpdate && !isShowTable && formData.fsubmit !== 1" @click="submitInspection">鎻愪氦妫�楠�</button> + </view> <!-- 淇敼涓嶅悎鏍兼弿杩板脊鍑烘 --> <view v-if="remarksPopup" class="overlay"> <view class="popup"> @@ -143,6 +148,169 @@ </view> </view> </view> + + <!-- 闄勪欢鍒楄〃寮圭獥 --> + <view v-if="showAttachmentPopup" class="overlay"> + <view class="popup attachment-list-popup"> + <div class="attachment-popup-header"> + <h3 class="attachment-popup-title">闄勪欢鍒楄〃</h3> + <button class="attachment-close-btn" @click="closeAttachmentPopup">鍏抽棴</button> + </div> + + <div class="attachment-popup-content"> + <div v-if="attachmentsLoading" class="attachment-loading"> + <div class="loading-spinner"></div> + <span class="loading-text">姝e湪鍔犺浇闄勪欢...</span> + </div> + + <div v-else-if="attachments.length === 0" class="attachment-empty"> + <div class="empty-icon">馃搧</div> + <div class="empty-text">鏆傛棤闄勪欢</div> + <div class="empty-hint">璇ョ墿鏂欐殏鏈笂浼犱换浣曢檮浠�</div> + </div> + + <div v-else class="attachment-list"> + <div v-for="item in attachments" :key="item.id" class="attachment-item"> + <div class="attachment-info"> + <div class="file-type-badge" :class="getFileTypeClass(item.fattach)"> + {{ getFileTypeIcon(item.fattach) }} + </div> + <div class="attachment-details"> + <div class="attachment-name" @click="showAttachmentDetailDialog(item)"> + {{ item.fattach }} + </div> + <div class="attachment-meta"> + <span class="meta-type">{{ item.ftype || '鏈煡绫诲瀷' }}</span> + <span v-if="item.fversion" class="meta-version">v{{ item.fversion }}</span> + <span v-if="item.fdate" class="meta-date">{{ formatDate(item.fdate) }}</span> + </div> + </div> + </div> + + <div class="attachment-actions"> + <button class="btn-secondary" @click="showAttachmentDetailDialog(item)">璇︽儏</button> + <button v-if="isPreviewable(item.fattach)" + class="btn-primary" + @click="previewFtpFile(item)">棰勮</button> + <button class="btn-success" @click="downloadAttachment(item)">涓嬭浇</button> + </div> + </div> + </div> + </div> + </view> + </view> + + <!-- 闄勪欢璇︽儏寮圭獥 --> + <view v-if="showAttachmentDetail" class="overlay"> + <view class="popup attachment-detail-popup"> + <div class="attachment-popup-header"> + <h3 class="attachment-popup-title">闄勪欢璇︽儏</h3> + <button class="attachment-close-btn" @click="closeAttachmentDetail">杩斿洖</button> + </div> + + <div class="attachment-popup-content"> + <div v-if="selectedAttachment" class="attachment-detail-content"> + <div class="attachment-detail-header"> + <div class="file-type-badge large" :class="getFileTypeClass(selectedAttachment.fattach)"> + {{ getFileTypeIcon(selectedAttachment.fattach) }} + </div> + <div class="attachment-detail-title"> + {{ selectedAttachment.fattach }} + </div> + </div> + + <div class="attachment-detail-info"> + <div class="info-row"> + <div class="info-item"> + <text class="info-label">ID</text> + <text class="info-content">{{ Math.trunc(selectedAttachment.id) }}</text> + </div> + <div class="info-item"> + <text class="info-label">绫诲瀷</text> + <text class="info-content">{{ selectedAttachment.ftype || '鏈煡绫诲瀷' }}</text> + </div> + </div> + + <div class="info-row" v-if="selectedAttachment.fversion"> + <div class="info-item"> + <text class="info-label">鐗堟湰</text> + <text class="info-content">{{ selectedAttachment.fversion }}</text> + </div> + <div class="info-item" v-if="selectedAttachment.fdate"> + <text class="info-label">鍙楁帶鏃ユ湡</text> + <text class="info-content">{{ formatDate(selectedAttachment.fdate) }}</text> + </div> + </div> + + <div class="info-row" v-if="selectedAttachment.createBy"> + <div class="info-item"> + <text class="info-label">涓婁紶浜�</text> + <text class="info-content">{{ selectedAttachment.createBy }}</text> + </div> + <div class="info-item" v-if="selectedAttachment.createDate"> + <text class="info-label">涓婁紶鏃堕棿</text> + <text class="info-content">{{ formatDate(selectedAttachment.createDate) }}</text> + </div> + </div> + </div> + + <div class="attachment-detail-actions"> + <button v-if="isPreviewable(selectedAttachment.fattach)" + class="btn-primary" + @click="previewFtpFile(selectedAttachment)">棰勮</button> + <button class="btn-success" @click="downloadAttachment(selectedAttachment)">涓嬭浇</button> + </div> + </div> + <div v-else class="attachment-detail-empty"> + <div class="empty-icon">鉂�</div> + <div class="empty-text">鏆傛棤闄勪欢淇℃伅</div> + </div> + </div> + </view> + </view> + + <!-- 鏂囦欢棰勮寮圭獥 --> + <view v-if="showFilePreviewPopup" class="overlay"> + <view class="popup file-preview-popup"> + <h3 class="file-preview-title">{{ previewTitle }}</h3> + <div class="file-preview-divider"></div> + <div class="file-preview-content"> + <!-- 鏂囨湰鍐呭棰勮 --> + <pre v-if="previewType === 'text'">{{ previewContent }}</pre> + + <!-- 鍥剧墖鍐呭棰勮 --> + <view v-else-if="previewType === 'image'" class="image-preview-container"> + <image + :src="previewContent" + mode="aspectFit" + class="preview-image-clickable" + @click="previewImageInPopup" + style="width: 100%; max-height: 400px; cursor: pointer;" + /> + <div class="image-zoom-hint">鐐瑰嚮鍥剧墖鍙斁澶ф煡鐪�</div> + </view> + + <!-- Excel 绛� Office 鏂囦欢鎻愮ず --> + <view v-else-if="previewType === 'excel'" class="unsupported-preview"> + <view class="unsupported-icon">馃搳</view> + <view class="unsupported-text">Excel 鏂囦欢鏆備笉鏀寔鍦ㄧ嚎棰勮</view> + <view class="unsupported-hint">璇风偣鍑讳笅杞芥寜閽幏鍙栧畬鏁存枃浠�</view> + </view> + + <!-- 涓嶆敮鎸佺殑鏂囦欢绫诲瀷 --> + <view v-else class="unsupported-preview"> + <view class="unsupported-icon">馃搫</view> + <view class="unsupported-text">姝ゆ枃浠舵牸寮忔殏涓嶆敮鎸侀瑙�</view> + <view class="unsupported-hint">璇风偣鍑讳笅杞芥寜閽幏鍙栧畬鏁存枃浠�</view> + </view> + </div> + <div class="file-preview-actions"> + <button v-if="previewType !== 'text'" class="file-preview-btn download-btn" @click="downloadPreviewFile">馃摜 涓嬭浇鏂囦欢</button> + <button class="file-preview-btn close-btn" @click="closeFilePreview">鍏抽棴</button> + </div> + </view> + </view> + </view> </template> @@ -151,38 +319,38 @@ export default { data() { return { - formData: { - id: "", - releaseNo: "", - createBy: "", - createDate: "", - daa020: "", - itemNo: "", - billNo: "", - catQty: "", - detailMem: "", - taskNo: "", - fcheckResu: "", - boardModel: "", - planQty: "", - mocode: "", - boardStyle: "" - }, + formData: { + id: "", + releaseNo: "", + createBy: "", + createDate: "", + daa020: "", + daa002: "", // 娣诲姞浜у搧ID瀛楁 + itemNo: "", + itemName: "", // 娣诲姞鐗╂枡鍚嶇О + itemModel: "", // 娣诲姞瑙勬牸鍨嬪彿 + billNo: "", + catQty: "", + detailMem: "", + taskNo: "", + fcheckResu: "", + fsubmit: 0, // 娣诲姞鎻愪氦鐘舵�佸瓧娈� + boardModel: "", + planQty: "", + mocode: "", + boardStyle: "" + }, DAA020List: [], DAA020Index: -1, filteredDAA020List: [], - DAA001List: [], + DAA001List: [], DAA001Index: -1, schemeResult: [], - - isShowTable: false, - - ItemList: [], - ItemIndex: -1, - boardItems: [], - + + isShowTable: false, + lineList: [], lineNo: "", @@ -200,6 +368,19 @@ departmentList: [], selectedDepartment: '', WORKSHOP: '', + + // 闄勪欢鐩稿叧鏁版嵁 + showAttachmentPopup: false, + showAttachmentDetail: false, + showFilePreviewPopup: false, + attachments: [], + attachmentsLoading: false, + selectedAttachment: null, + previewTitle: '', + previewContent: '', + previewType: '', + previewFileUrl: '' + }; }, onLoad(options) { @@ -213,6 +394,13 @@ this.formData.releaseNo = params["releaseNo"]; //getQaItemXj02 this.init(); + + // 濡傛灉鏄粠鍒楄〃椤甸潰鐐瑰嚮鏌ョ湅闄勪欢鎸夐挳璺宠浆杩囨潵鐨勶紝鑷姩鎵撳紑闄勪欢寮圭獥 + if (params["showAttachments"] === "true") { + this.$nextTick(() => { + this.viewAttachmentInfo(); + }); + } } else { //鍒濆鍖栨楠屽崟鍙� this.$post({ @@ -258,6 +446,15 @@ } }, + getInspectionDescription(item) { + // 鍙朓TEM_MOD瀛楁鐨勫�� + if (item.itemMod && item.itemMod.trim() !== '') { + return item.itemMod; + } else { + return '妫�楠岄」鐩鎯�'; + } + }, + removeXJ() { if (this.formData.id) { this.$post({ @@ -278,29 +475,75 @@ this.$showMessage("璇峰厛閫夋嫨妫�楠屽崟鍙�"); } }, - getItem() { - + save() { + // 楠岃瘉蹇呭~瀛楁 - 鍊熼壌SJ鐨勯獙璇侀�昏緫锛屼絾淇濇寔XJ鐨勫瓧娈甸獙璇� + if (!this.formData.billNo) { + this.$showMessage("璇烽�夋嫨宸ュ崟鍗曞彿"); + return; + } + + if (!this.formData.itemNo) { + this.$showMessage("鐗╂枡淇℃伅鑾峰彇澶辫触锛岃閲嶆柊閫夋嫨宸ュ崟"); + return; + } + + if (!this.tableData || this.tableData.length === 0) { + this.$showMessage("姝ょ墿鏂欐病鏈夊惎鐢ㄧ殑妫�楠岄」鐩紝璇风淮鎶�!"); + return; + } - - if (!this.formData.billNo) { - this.$showMessage("璇烽�夋嫨宸ュ崟鍗曞彿"); - return; - } - - this.$post({ - url: "/XJ/save", - data: { - from: this.formData, - userNo: this.$loginInfo.account, - items: this.tableData - } - }).then(res => { - this.formData.id = res.data.tbBillList; - this.$showMessage("鐢熸垚妫�楠岄」鐩垚鍔�"); - this.init(); - this.isUpdate = false; - }); - }, + const saveData = { + ReleaseNo: this.formData.releaseNo, + ItemNo: this.formData.itemNo, + BillNo: this.formData.billNo, + DepartmentId: this.selectedDepartment, // 鍙娇鐢ㄩ儴闂↖D + WorkShop: null, // 鏄庣‘璁剧疆涓簄ull锛岄伩鍏嶆暟鎹簱瀛楁閿欒 + ItemId: this.formData.daa002, // 浣跨敤宸ュ崟涓殑浜у搧ID + PlanQty: this.formData.planQty, + CreateBy: this.formData.createBy, + CreateDate: this.formData.createDate, + FcheckDate: new Date(), + Remarks: this.formData.remarks || "" + }; + + // 璋冭瘯淇℃伅 + console.log("鍒涘缓妫�楠屽崟鏁版嵁:", { + formData: this.formData, + selectedDepartment: this.selectedDepartment, + WORKSHOP: this.WORKSHOP, + saveData: saveData, + tableData: this.tableData + }); + + this.$post({ + url: "/XJ/save", + data: { + from: saveData, + userNo: this.$loginInfo.account, + items: this.tableData + } + }).then(res => { + if (res.data.tbBillList) { + this.formData.id = res.data.tbBillList; + + // 濡傛灉杩斿洖浜嗗畬鏁寸殑妫�楠岄」鐩俊鎭紝鏇存柊tableData + if (res.data.xjDto && res.data.xjDto.items) { + this.tableData = res.data.xjDto.items; + } + + this.$showMessage("鍒涘缓妫�楠屽崟骞剁敓鎴愰粯璁ゅ�兼垚鍔�"); + this.isUpdate = false; + + // 鏇存柊formData鐨勫叾浠栧瓧娈� + this.formData = { ...this.formData, ...saveData }; + } else { + this.$showMessage("鍒涘缓妫�楠屽崟澶辫触锛岃妫�鏌ユ暟鎹�"); + } + }).catch(err => { + console.error("鍒涘缓妫�楠屽崟閿欒:", err); + this.$showMessage("鍒涘缓妫�楠屽崟澶辫触锛�" + (err.message || "鏈煡閿欒")); + }); + }, // 鍔犺浇閮ㄩ棬鍒楄〃 loadDepartments() { @@ -376,126 +619,115 @@ }); }, - //鐢熶骇绾垮埆閫夋嫨骞跺垵濮嬭瘽宸ュ崟鍙� + //鐢熶骇绾垮埆閫夋嫨骞跺垵濮嬪寲宸ュ崟鍙� onDaa020Change(event) { //鑾峰彇鐢熶骇绾垮埆鐨勪笅鏍囧湴鍧� this.DAA020Index = event.mp.detail.value; - + this.lineNo = this.lineList[this.DAA020Index].lineNo; - + // 璁剧疆绾夸綋缂栧彿鍒癴ormData + this.formData.daa020 = this.lineList[this.DAA020Index].lineName; + this.$post({ - url: "/XJ/getBoardItem", + url: "/XJ/getWorkOrderWithItem", // 璋冪敤鏂扮殑API鑾峰彇宸ュ崟璇︾粏淇℃伅 data: { - lineNo: this.lineNo - } - }).then(res => { - //濉厖宸ュ崟鍙风殑鏁版嵁婧� - this.boardItems = res.data.tbBillList; - this.ItemList = this.boardItems.map(item => item.itemNo); - //鍙樹负榛樿绌哄�肩殑鐘舵�� - this.ItemIndex = -1; - }) - - }, - onItemChange(event) { - this.ItemIndex = event.mp.detail.value; - this.formData.itemNo = this.boardItems[this.ItemIndex].itemNo;//涓昏鏄敼杩欓噷 - this.formData.itemId = this.boardItems[this.ItemIndex].id;//涓昏鏄敼杩欓噷 - this.formData.itemName = this.boardItems[this.ItemIndex].itemName;//涓昏鏄敼杩欓噷 - this.formData.itemModel = this.boardItems[this.ItemIndex].itemModel;//涓昏鏄敼杩欓噷 - this.$post({ - url: "/XJ/getDaa001", - data: { - daa020: this.lineNo, - item: this.formData.itemNo + daa020: this.lineNo } }).then(res => { //濉厖宸ュ崟鍙风殑鏁版嵁婧� this.schemeResult = res.data.tbBillList; - this.DAA001List = this.schemeResult.map(s => s.daa001); + this.DAA001List = this.schemeResult.map(s => s.daa001); // 淇敼涓哄皬鍐� //鍙樹负榛樿绌哄�肩殑鐘舵�� this.DAA001Index = -1; - + this.formData.billNo = ""; + // 娓呯┖鐗╂枡淇℃伅 + this.formData.itemNo = ""; + this.formData.itemName = ""; + this.formData.itemModel = ""; + this.formData.planQty = ""; + this.tableData = []; }) + }, - //閫夊彇宸ュ崟濉厖鐗╂枡鍙峰拰鍏朵粬淇℃伅 + + //閫夊彇宸ュ崟濉厖鐗╂枡鍙峰拰鍏朵粬淇℃伅 onDaa001Change(event) { this.DAA001Index = event.mp.detail.value; - this.formData.billNo = this.schemeResult[this.DAA001Index].daa001; - this.formData.planQty = this.schemeResult[this.DAA001Index].daa008; - //琛ㄥ崟涓殑閮ㄥ垎瀛楁璧嬪�� + const selectedWorkOrder = this.schemeResult[this.DAA001Index]; + + // 璁剧疆宸ュ崟淇℃伅 + this.formData.billNo = selectedWorkOrder.daa001; // 淇敼涓哄皬鍐� + this.formData.planQty = selectedWorkOrder.daa008; // 淇敼涓哄皬鍐� + this.formData.daa002 = selectedWorkOrder.daa002; // 璁剧疆浜у搧ID + + // 浠庡伐鍗曟暟鎹腑鑾峰彇鐗╂枡淇℃伅 + this.formData.itemNo = selectedWorkOrder.itemNo; // 淇敼涓哄皬鍐� + this.formData.itemName = selectedWorkOrder.itemName; // 淇敼涓哄皬鍐� + this.formData.itemModel = selectedWorkOrder.itemModel; // 淇敼涓哄皬鍐� + + // 鑾峰彇妫�楠岄」鐩� this.$post({ - url: "/XJ/getItem", + url: "/XJ/setJYItem", data: { - daa001: this.formData.billNo + itemNo: this.formData.itemNo } }).then(res => { - let data = res.data.tbBillList[0]; - //褰撹繑鍥炵殑缁撴灉闆嗕负绌烘椂缃┖鍘熸湁鐨勫�� - if (!data) { - this.formData.billNo = ""; - this.formData.itemNo = ""; - this.formData.planQty = ""; + if (res.data.tbBillList.length > 0) { + this.tableData = res.data.tbBillList; + this.isSubmit = false; + } else { + this.$showMessage("姝ょ墿鏂欐病鏈夊惎鐢ㄧ殑妫�楠岄」鐩紝璇风淮鎶�!"); + this.isSubmit = true; this.tableData = []; - return; } - - this.$post({ - url: "/XJ/setJYItem", - data: { - itemNo: this.formData.itemNo - } - }).then(res => { - if (res.data.tbBillList.length > 0) { - this.tableData = res.data.tbBillList; // 鍦ㄧ澶村嚱鏁颁腑锛宼his 鎸囧悜澶栧眰浣滅敤鍩熺殑 this - this.isSubmit = false; - } else { - this.$showMessage("姝ょ墿鏂欐病鏈夊惎鐢ㄧ殑妫�楠岄」鐩紝璇风淮鎶�!"); - this.isSubmit = true; - this.tableData = []; - } - }); + }).catch(err => { + console.error("鑾峰彇妫�楠岄」鐩敊璇�:", err); + this.$showMessage("鑾峰彇妫�楠岄」鐩け璐�"); + this.tableData = []; }); }, - init() { - this.$post({ - url: "/XJ/getPage", - data: { - id: this.formData.id, - pageIndex: 1, - limit: 1, - } - }).then(res => { - let data = res.data.tbBillList[0]; - if (data) { - this.formData = data; - - this.$post({ - url: "/XJ/getJYItem", - data: { - pid: this.formData.id - } - }).then(res1 => { - let tableData = res1.data.tbBillList - //褰撳凡妫�楠屼釜鏁伴兘涓嶄负绌烘椂鎸夌収妫�娴嬬粨鏋勬帓搴� - tableData.sort((a, b) => { - if (a.result === '鏈畬鎴�' && b.result === '鍚堟牸') { - return -1; - } else if (a.result === '鍚堟牸' && b.result === '鏈畬鎴�') { - return 1; - } else { - return 0; - } - }); - this.tableData = tableData; - if (this.tableData.length === 0) { - this.isShowTable = true; - } - }) - } - }); - }, + init() { + this.$post({ + url: "/XJ/getPage", + data: { + id: this.formData.id, + pageIndex: 1, + limit: 1, + } + }).then(res => { + let data = res.data.tbBillList[0]; + if (data) { + this.formData = data; + + // 涓嶅啀鏍规嵁fsubmit瀛楁淇敼isUpdate鐘舵�� + // 鑰屾槸閫氳繃鎸夐挳鐨剉-if鏉′欢鏉ユ帶鍒舵樉绀� + + this.$post({ + url: "/XJ/getJYItem", + data: { + pid: this.formData.id + } + }).then(res1 => { + let tableData = res1.data.tbBillList + //褰撳凡妫�楠屼釜鏁伴兘涓嶄负绌烘椂鎸夌収妫�娴嬬粨鏋勬帓搴� + tableData.sort((a, b) => { + if (a.result === '鏈畬鎴�' && b.result === '鍚堟牸') { + return -1; + } else if (a.result === '鍚堟牸' && b.result === '鏈畬鎴�') { + return 1; + } else { + return 0; + } + }); + this.tableData = tableData; + if (this.tableData.length === 0) { + this.isShowTable = true; + } + }) + } + }); + }, toDetail(item) { if (this.isUpdate) { uni.showToast({ @@ -609,7 +841,233 @@ this.$showMessage(res.data.message || "鑾峰彇澶辫触"); } }); - } + }, + + // 闄勪欢鐩稿叧鏂规硶 + viewAttachmentInfo() { + this.showAttachmentPopup = true; + this.attachmentsLoading = true; + this.attachments = []; + this.$post({ + url: "/XJ/getAttachments", + data: { itemNo: this.formData.itemNo } + }).then(res => { + this.attachmentsLoading = false; + if (res.status === 0) { + this.attachments = res.data.tbBillList; + // 涓烘瘡涓檮浠惰缃粯璁ゅ彲鐢ㄧ姸鎬� + this.attachments.forEach((item, index) => { + this.$set(item, 'ftpAvailable', true); + this.$set(item, 'checking', false); + }); + } else if (res.status === 1 && res.message === "璇ユ楠屽崟鏈笂浼犻檮浠朵俊鎭紒") { + uni.showToast({ title: res.message, icon: "none" }); + } else { + uni.showToast({ title: "鑾峰彇闄勪欢澶辫触", icon: "none" }); + } + }); + }, + + closeAttachmentPopup() { + this.showAttachmentPopup = false; + }, + + showAttachmentDetailDialog(item) { + this.selectedAttachment = item; + this.showAttachmentPopup = false; + this.showAttachmentDetail = true; + }, + + closeAttachmentDetail() { + this.showAttachmentDetail = false; + this.selectedAttachment = null; + this.showAttachmentPopup = true; + }, + + isPreviewable(filename) { + if (!filename) return false; + const ext = filename.trim().split('.').pop().toLowerCase(); + return [ + 'pdf', + 'jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', + 'txt', 'log', 'md', + 'doc', 'docx', + 'xls', 'xlsx', + 'ppt', 'pptx', + 'csv' + ].includes(ext); + }, + + // 鑾峰彇鏂囦欢绫诲瀷鍥炬爣 + getFileTypeIcon(filename) { + if (!filename) return '馃搫'; + const ext = filename.trim().split('.').pop().toLowerCase(); + const iconMap = { + 'pdf': '馃摃', + 'jpg': '馃柤锔�', 'jpeg': '馃柤锔�', 'png': '馃柤锔�', 'gif': '馃柤锔�', 'bmp': '馃柤锔�', 'webp': '馃柤锔�', + 'txt': '馃摑', 'log': '馃摑', 'md': '馃摑', + 'doc': '馃摌', 'docx': '馃摌', + 'xls': '馃搳', 'xlsx': '馃搳', + 'ppt': '馃摍', 'pptx': '馃摍', + 'csv': '馃搳', + 'zip': '馃摝', 'rar': '馃摝', '7z': '馃摝', + 'dwg': '馃彈锔�', 'dxf': '馃彈锔�' + }; + return iconMap[ext] || '馃搫'; + }, + + // 鑾峰彇鏂囦欢绫诲瀷CSS绫� + getFileTypeClass(filename) { + if (!filename) return 'file-unknown'; + const ext = filename.trim().split('.').pop().toLowerCase(); + const classMap = { + 'pdf': 'file-pdf', + 'jpg': 'file-image', 'jpeg': 'file-image', 'png': 'file-image', 'gif': 'file-image', 'bmp': 'file-image', 'webp': 'file-image', + 'txt': 'file-text', 'log': 'file-text', 'md': 'file-text', + 'doc': 'file-word', 'docx': 'file-word', + 'xls': 'file-excel', 'xlsx': 'file-excel', + 'ppt': 'file-powerpoint', 'pptx': 'file-powerpoint', + 'csv': 'file-excel', + 'zip': 'file-archive', 'rar': 'file-archive', '7z': 'file-archive', + 'dwg': 'file-cad', 'dxf': 'file-cad' + }; + return classMap[ext] || 'file-unknown'; + }, + + // 鏍煎紡鍖栨棩鏈� + formatDate(dateString) { + if (!dateString) return ''; + try { + const date = new Date(dateString); + return date.toLocaleDateString('zh-CN', { + year: 'numeric', + month: '2-digit', + day: '2-digit', + hour: '2-digit', + minute: '2-digit' + }); + } catch (e) { + return dateString; + } + }, + + downloadAttachment(item) { + const fileName = item.fattach.replace(/[\s\u3000\r\n]+/g, '').trim(); + const downloadUrl = this.$store.state.serverInfo.serverAPI + "/XJ/DownloadFtpFile?itemNo=" + + encodeURIComponent(item.itemNo) + "&fileName=" + encodeURIComponent(fileName) + + "&ftpServer=" + encodeURIComponent(this.$store.state.serverInfo.ftpServer); + + uni.downloadFile({ + url: downloadUrl, + success: (res) => { + if (res.statusCode === 200) { + uni.showToast({ title: '涓嬭浇鎴愬姛', icon: 'success' }); + } else { + uni.showToast({ title: '涓嬭浇澶辫触', icon: 'none' }); + } + }, + fail: (err) => { + console.error('涓嬭浇澶辫触锛�', err); + uni.showToast({ title: '涓嬭浇澶辫触锛岃閲嶈瘯', icon: 'none' }); + } + }); + }, + + previewFtpFile(item) { + const fileName = item.fattach.replace(/[\s\u3000\r\n]+/g, '').trim(); + const fileExt = fileName.split('.').pop().toLowerCase(); + + if (!this.isPreviewable(fileName)) { + uni.showModal({ + title: '涓嶆敮鎸侀瑙�', + content: '璇ユ枃浠剁被鍨嬩笉鏀寔鍦ㄧ嚎棰勮锛岃涓嬭浇鍚庢煡鐪�', + showCancel: false + }); + return; + } + + const previewUrl = this.$store.state.serverInfo.serverAPI + "/XJ/PreviewFtpFile?itemNo=" + + encodeURIComponent(item.itemNo) + "&fileName=" + encodeURIComponent(fileName) + + "&ftpServer=" + encodeURIComponent(this.$store.state.serverInfo.ftpServer); + + if (['pdf'].includes(fileExt)) { + this.previewPdfFile(previewUrl, fileName); + } else if (['jpg', 'jpeg', 'png', 'gif', 'bmp'].includes(fileExt)) { + this.previewImageFile(previewUrl, fileName); + } else if (['txt'].includes(fileExt)) { + this.previewTextFile(previewUrl, fileName); + } else { + this.previewOfficeFile(previewUrl, fileName); + } + }, + + previewPdfFile(url, fileName) { + this.previewTitle = fileName; + this.previewContent = url; + this.previewType = 'pdf'; + this.previewFileUrl = url; + this.showFilePreviewPopup = true; + this.showAttachmentDetail = false; + }, + + previewImageFile(url, fileName) { + this.previewTitle = fileName; + this.previewContent = url; + this.previewType = 'image'; + this.previewFileUrl = url; + this.showFilePreviewPopup = true; + this.showAttachmentDetail = false; + }, + + previewTextFile(url, fileName) { + this.previewTitle = fileName; + this.previewType = 'text'; + this.previewFileUrl = url; + this.showFilePreviewPopup = true; + this.showAttachmentDetail = false; + + uni.request({ + url: url, + method: 'GET', + success: (res) => { + this.previewContent = res.data; + }, + fail: (err) => { + this.previewContent = '棰勮澶辫触锛岃涓嬭浇鍚庢煡鐪�'; + } + }); + }, + + previewOfficeFile(url, fileName) { + this.previewTitle = fileName; + this.previewContent = ''; + this.previewType = 'excel'; + this.previewFileUrl = url; + this.showFilePreviewPopup = true; + this.showAttachmentDetail = false; + }, + + closeFilePreview() { + this.showFilePreviewPopup = false; + this.showAttachmentDetail = true; + }, + + downloadPreviewFile() { + if (this.previewFileUrl && this.selectedAttachment) { + this.downloadAttachment(this.selectedAttachment); + } + }, + + previewImageInPopup() { + // 鍦ㄦ柊绐楀彛涓墦寮�鍥剧墖杩涜鏀惧ぇ鏌ョ湅 + if (this.previewContent) { + uni.previewImage({ + urls: [this.previewContent], + current: this.previewContent + }); + } + } + }, onShow() { //姣忔杩涘叆椤甸潰閮戒細鎵ц鐨勬柟娉� @@ -859,6 +1317,16 @@ color: white; } + .action-btn.info { + background-color: #17a2b8; + color: white; + } + + .action-btn.small { + padding: 6px 12px; + font-size: 12px; + } + /* 寮瑰嚭妗嗘牱寮� */ .overlay { position: fixed; @@ -919,6 +1387,56 @@ background-color: white; } + /* 闄勪欢鐩稿叧鏍峰紡 */ + .no-attachments { + text-align: center; + padding: 40px 20px; + color: #7f8c8d; + } + + .attachments-list { + max-height: 400px; + overflow-y: auto; + } + + .attachment-item { + display: flex; + justify-content: space-between; + align-items: center; + padding: 12px; + border: 1px solid #eee; + border-radius: 4px; + margin-bottom: 8px; + background-color: #f8f9fa; + } + + .attachment-info { + flex: 1; + display: flex; + flex-direction: column; + gap: 4px; + } + + .attachment-name { + font-weight: 500; + color: #2c3e50; + } + + .attachment-type { + font-size: 12px; + color: #7f8c8d; + } + + .attachment-date { + font-size: 12px; + color: #95a5a6; + } + + .attachment-actions { + display: flex; + gap: 8px; + } + .popup-actions { padding: 20px; border-top: 1px solid #eee; @@ -927,6 +1445,504 @@ justify-content: flex-end; } + /* 闄勪欢寮圭獥鏍峰紡 */ + .attachment-list { + padding: 0; + margin: 0; + list-style: none; + max-height: 300px; + overflow-y: auto; + } + + .attachment-list li { + display: flex; + align-items: center; + justify-content: space-between; + padding: 12px 0; + border-bottom: 1px solid #f0f0f0; + } + + .attachment-info { + flex: 1; + margin-right: 10px; + } + + .attachment-name { + color: #3498db; + cursor: pointer; + font-weight: 500; + transition: color 0.2s; + display: block; + margin-bottom: 4px; + } + + .attachment-name:hover { + color: #217dbb; + text-decoration: underline; + } + + .attachment-meta { + font-size: 12px; + } + + .attachment-type { + color: #7f8c8d; + font-style: italic; + } + + .attachment-actions { + display: flex; + gap: 8px; + flex-shrink: 0; + } + + .attachment-list .secondary-btn { + padding: 4px 10px; + font-size: 13px; + border-radius: 3px; + background: #f5f7fa; + color: #333; + border: 1px solid #dbe2ea; + transition: background 0.2s, color 0.2s; + } + + .attachment-list .secondary-btn:hover { + background: #e6f0fa; + color: #1976d2; + } + + .preview-btn { + background: #e8f5e8 !important; + color: #2e7d2e !important; + border-color: #a5d6a5 !important; + } + + .preview-btn:hover { + background: #d4eecc !important; + color: #1e5f1e !important; + } + + /* 闄勪欢寮圭獥閫氱敤鏍峰紡 */ + .attachment-list-popup { + width: 80vw; + max-width: 800px; + max-height: 85vh; + } + + .attachment-detail-popup { + width: 70vw; + max-width: 600px; + } + + .attachment-popup-header { + padding: 16px; + border-bottom: 1px solid #eee; + display: flex; + justify-content: space-between; + align-items: center; + background-color: white; + } + + .attachment-popup-title { + font-size: 16px; + font-weight: 600; + color: #2c3e50; + margin: 0; + } + + .attachment-close-btn { + padding: 8px 16px; + border: 1px solid #ddd; + border-radius: 4px; + background-color: white; + font-size: 14px; + transition: all 0.2s; + color: #2c3e50; + } + + .attachment-close-btn:hover { + background-color: #f8f9fa; + } + + .attachment-popup-content { + padding: 16px; + max-height: 60vh; + overflow-y: auto; + } + + /* 鍔犺浇鐘舵�� */ + .attachment-loading { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 40px 20px; + gap: 16px; + } + + .loading-spinner { + width: 32px; + height: 32px; + border: 3px solid #f3f3f3; + border-top: 3px solid #3498db; + border-radius: 50%; + animation: spin 1s linear infinite; + } + + @keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } + } + + .loading-text { + font-size: 14px; + color: #7f8c8d; + } + + /* 绌虹姸鎬� */ + .attachment-empty { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 40px 20px; + gap: 12px; + text-align: center; + } + + .empty-icon { + font-size: 36px; + opacity: 0.6; + } + + .empty-text { + font-size: 16px; + color: #7f8c8d; + font-weight: 500; + } + + .empty-hint { + font-size: 14px; + color: #95a5a6; + } + + /* 闄勪欢鍒楄〃甯冨眬 - 鎸夌収LLJ鐨勫崱鐗囬鏍� */ + .attachment-list { + display: flex; + flex-direction: column; + gap: 16px; + } + + .attachment-item { + background-color: white; + border-radius: 8px; + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05); + overflow: hidden; + transition: all 0.3s; + border: 1px solid #eee; + } + + .attachment-item:hover { + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1); + } + + .attachment-info { + padding: 16px; + border-bottom: 1px solid #eee; + display: flex; + align-items: center; + gap: 16px; + } + + .file-type-badge { + width: 40px; + height: 40px; + border-radius: 8px; + display: flex; + align-items: center; + justify-content: center; + font-size: 20px; + background: #f8f9fa; + border: 2px solid #e9ecef; + flex-shrink: 0; + } + + .file-type-badge.large { + width: 56px; + height: 56px; + font-size: 28px; + } + + .file-type-badge.file-pdf { background: #ffe6e6; border-color: #ffcccc; } + .file-type-badge.file-image { background: #e6f3ff; border-color: #cce7ff; } + .file-type-badge.file-text { background: #e6ffe6; border-color: #ccffcc; } + .file-type-badge.file-word { background: #e6f0ff; border-color: #cce0ff; } + .file-type-badge.file-excel { background: #e6ffe6; border-color: #ccffcc; } + .file-type-badge.file-powerpoint { background: #fff0e6; border-color: #ffe0cc; } + .file-type-badge.file-archive { background: #f0e6ff; border-color: #e0ccff; } + .file-type-badge.file-cad { background: #e6fff0; border-color: #ccffe0; } + .file-type-badge.file-unknown { background: #f5f5f5; border-color: #e0e0e0; } + + .attachment-details { + flex: 1; + min-width: 0; + } + + .attachment-name { + font-size: 16px; + font-weight: 600; + color: #2c3e50; + cursor: pointer; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + margin-bottom: 8px; + transition: color 0.2s; + } + + .attachment-name:hover { + color: #3498db; + } + + .attachment-card-body { + padding: 16px 20px 20px; + } + + .attachment-meta { + display: flex; + gap: 16px; + font-size: 12px; + color: #95a5a6; + } + + .meta-type { + background-color: #ecf0f1; + padding: 2px 6px; + border-radius: 10px; + color: #7f8c8d; + } + + .meta-version { + background-color: #e8f5e8; + padding: 2px 6px; + border-radius: 10px; + color: #2e7d32; + } + + .meta-date { + background-color: #fff3e0; + padding: 2px 6px; + border-radius: 10px; + color: #f57c00; + } + + .attachment-actions { + padding: 12px 16px; + border-top: 1px solid #eee; + display: flex; + gap: 8px; + background-color: #f8f9fa; + } + + /* 鎸夐挳鏍峰紡 - 鎸夌収LLJ椋庢牸 */ + .btn-secondary { + padding: 8px 16px; + border: 1px solid #ddd; + border-radius: 4px; + background-color: white; + font-size: 14px; + transition: all 0.2s; + color: #2c3e50; + flex: 1; + } + + .btn-secondary:hover { + background-color: #f8f9fa; + } + + .btn-primary { + padding: 8px 16px; + border: 1px solid #3498db; + border-radius: 4px; + background-color: #3498db; + color: white; + font-size: 14px; + transition: all 0.2s; + flex: 1; + } + + .btn-primary:hover { + background-color: #2980b9; + } + + .btn-success { + padding: 8px 16px; + border: 1px solid #2ecc71; + border-radius: 4px; + background-color: #2ecc71; + color: white; + font-size: 14px; + transition: all 0.2s; + flex: 1; + } + + .btn-success:hover { + background-color: #27ae60; + } + + + + /* 闄勪欢璇︽儏鏍峰紡 */ + .attachment-detail-header { + display: flex; + align-items: center; + gap: 20px; + margin-bottom: 20px; + padding-bottom: 16px; + border-bottom: 1px solid #eee; + } + + .attachment-detail-title { + font-size: 18px; + font-weight: 600; + color: #2c3e50; + flex: 1; + word-break: break-all; + } + + .attachment-detail-info { + margin-bottom: 20px; + } + + .info-row { + display: flex; + margin-bottom: 12px; + gap: 16px; + } + + .info-item { + flex: 1; + } + + .info-label { + display: block; + font-size: 12px; + color: #7f8c8d; + margin-bottom: 4px; + } + + .info-content { + font-size: 14px; + color: #2c3e50; + line-height: 1.5; + } + + .attachment-detail-actions { + padding: 12px 16px; + border-top: 1px solid #eee; + display: flex; + gap: 8px; + background-color: #f8f9fa; + } + + /* 鏂囦欢棰勮寮圭獥鏍峰紡 */ + .file-preview-popup { + width: 80vw; + max-width: 800px; + max-height: 80vh; + } + + .file-preview-title { + padding: 20px; + margin: 0; + font-size: 16px; + font-weight: 600; + color: #2c3e50; + border-bottom: 1px solid #eee; + word-break: break-all; + } + + .file-preview-content { + padding: 20px; + max-height: 60vh; + overflow-y: auto; + } + + .file-preview-content pre { + white-space: pre-wrap; + word-wrap: break-word; + font-family: 'Courier New', monospace; + font-size: 12px; + line-height: 1.4; + background: #f8f9fa; + padding: 15px; + border-radius: 4px; + border: 1px solid #e9ecef; + } + + .image-preview-container { + text-align: center; + } + + .image-zoom-hint { + margin-top: 10px; + font-size: 12px; + color: #7f8c8d; + } + + .unsupported-preview { + text-align: center; + padding: 40px 20px; + } + + .unsupported-icon { + font-size: 48px; + margin-bottom: 16px; + } + + .unsupported-text { + font-size: 16px; + color: #7f8c8d; + margin-bottom: 8px; + } + + .unsupported-hint { + font-size: 14px; + color: #95a5a6; + } + + .file-preview-actions { + padding: 15px 20px; + border-top: 1px solid #eee; + display: flex; + gap: 10px; + justify-content: center; + } + + .file-preview-btn { + padding: 8px 16px; + border-radius: 4px; + border: none; + font-size: 14px; + cursor: pointer; + transition: all 0.2s; + } + + .file-preview-btn.download-btn { + background: #2ecc71; + color: white; + } + + .file-preview-btn.close-btn { + background: #95a5a6; + color: white; + } + + .file-preview-btn:hover { + transform: translateY(-1px); + box-shadow: 0 2px 8px rgba(0,0,0,0.15); + } + /* 鍝嶅簲寮忚璁� */ @media (max-width: 768px) { .info-grid { @@ -936,5 +1952,86 @@ .action-buttons { flex-direction: column; } + + /* 闄勪欢寮圭獥鍝嶅簲寮� */ + .attachment-list-popup { + width: 95vw; + margin: 10px; + } + + .attachment-detail-popup { + width: 95vw; + margin: 10px; + } + + .file-preview-popup { + width: 95vw; + } + + .attachment-grid { + grid-template-columns: 1fr; + gap: 16px; + } + + .attachment-card { + margin: 0; + } + + .attachment-card-actions { + flex-direction: column; + gap: 8px; + } + + .action-btn { + width: 100%; + justify-content: center; + } + + .attachment-detail-actions { + flex-direction: column; + gap: 12px; + } + + .detail-action-btn { + width: 100%; + } + + .attachment-popup-header { + padding: 16px 20px; + } + + .attachment-popup-title { + font-size: 18px; + } + + .attachment-icon { + font-size: 20px; + } + } + + @media (max-width: 480px) { + .attachment-popup-content { + padding: 16px; + } + + .attachment-card-header { + padding: 16px 16px 12px; + } + + .attachment-card-body { + padding: 12px 16px 16px; + } + + .file-type-icon { + width: 40px; + height: 40px; + font-size: 20px; + } + + .file-type-icon.large { + width: 56px; + height: 56px; + font-size: 28px; + } } </style> \ No newline at end of file -- Gitblit v1.9.3