From 28d9b65d2738f5d71e375576bec91fdec2ba6496 Mon Sep 17 00:00:00 2001 From: wx-jincw Date: Mon, 23 Mar 2026 22:47:04 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20app=E9=80=9A=E7=9F=A5=E9=99=84=E4=BB=B6?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E5=8A=A0=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/package-lock.json | 28 +- app/pages/supply_chain/complaint/index.vue | 214 ++++++++++++ app/pages/supply_chain/notice/index.vue | 115 +------ .../supply_chain/notice_detail/index.vue | 316 ++++++++++++------ 4 files changed, 458 insertions(+), 215 deletions(-) diff --git a/app/package-lock.json b/app/package-lock.json index abebf47..ee8d0b9 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -1,8 +1,34 @@ { "name": "app", "version": "1.0.0", - "lockfileVersion": 1, + "lockfileVersion": 2, "requires": true, + "packages": { + "": { + "name": "app", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "json-bigint": "^1.0.0" + } + }, + "node_modules/bignumber.js": { + "version": "9.3.1", + "resolved": "https://registry.npmmirror.com/bignumber.js/-/bignumber.js-9.3.1.tgz", + "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==", + "engines": { + "node": "*" + } + }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "dependencies": { + "bignumber.js": "^9.0.0" + } + } + }, "dependencies": { "bignumber.js": { "version": "9.3.1", diff --git a/app/pages/supply_chain/complaint/index.vue b/app/pages/supply_chain/complaint/index.vue index f397815..ef9c8e2 100644 --- a/app/pages/supply_chain/complaint/index.vue +++ b/app/pages/supply_chain/complaint/index.vue @@ -79,6 +79,27 @@ {{ form.csContent.length }}/300 + + 上传图片(选填) + + + + + × + + + + 添加图片 + + + 最多上传9张图片 + + + 备注(选填) + + + + + @@ -182,11 +219,14 @@ import { listComplaintSuggestion, deleteComplaintSuggestion } from '@/api/property.js'; +import request from '@/utils/request.js'; +import { HTTP_ADMIN_URL } from '@/config/app'; export default { dicts: ['cs_type'], data() { return { + HTTP_ADMIN_URL, activeTab: 'form', form: { csType: '', @@ -196,6 +236,7 @@ export default { phone: '', }, typeIndex: 0, + images: [], records: [], page: 1, limit: 10, @@ -239,6 +280,61 @@ export default { this.form.csType = types[index].dictValue; } }, + chooseImage() { + // #ifndef MP-WEIXIN + uni.chooseImage({ + count: 9 - this.images.length, + sizeType: ['compressed'], + sourceType: ['album', 'camera'], + success: (res) => { + this.uploadImages(res.tempFilePaths); + }, + fail: (err) => { + console.error('选择图片失败:', err); + } + }); + // #endif + // #ifdef MP-WEIXIN + uni.chooseMedia({ + count: 9 - this.images.length, + mediaType: ['image'], + sourceType: ['album', 'camera'], + sizeType: ['compressed'], + success: (res) => { + const tempFilePaths = res.tempFiles.map(file => file.tempFilePath); + this.uploadImages(tempFilePaths); + }, + fail: (err) => { + console.error('选择图片失败:', err); + } + }); + // #endif + }, + async uploadImages(filePaths) { + for (let i = 0; i < filePaths.length; i++) { + try { + uni.showLoading({ title: '上传中...', mask: true }); + const result = await request.uploadFile(filePaths[i], 'multipart', {}, { + params: { + model: 'app-complaint', + pid: 10 + } + }); + this.images.push(result); + } catch (e) { + console.error('上传图片失败:', e); + uni.showToast({ + title: '上传失败:' + (typeof e === 'string' ? e : '未知错误'), + icon: 'none' + }); + } finally { + uni.hideLoading(); + } + } + }, + deleteImage(index) { + this.images.splice(index, 1); + }, async submitComplaint() { if (!this.form.csContent.trim()) { uni.showToast({ @@ -248,12 +344,28 @@ export default { return; } + const imageFiles = this.images.map(file => { + let attDir = file.url; + return { + attId: file.id + '', + name: file.fileName, + attDir, + attSize: file.fileSize, + attType: file.type, + fileName: file.fileName, + filePath: attDir, + url: attDir, + originalFileName: file.fileName + }; + }); + const payload = { csType: this.form.csType, submitChannel: this.form.submitChannel, csContent: this.form.csContent.trim(), remark: this.form.remark.trim(), phone: this.form.phone.trim(), + files: imageFiles }; try { @@ -267,6 +379,7 @@ export default { this.form.csContent = ''; this.form.remark = ''; + this.images = []; this.page = 1; this.records = []; @@ -327,6 +440,17 @@ export default { if (status === '3') return '已处理'; return status; }, + previewRecordImages(files, index) { + if (!files || !files.length) return; + const urls = files.map(file => { + const path = file.url || file.attDir || file.filePath; + return this.HTTP_ADMIN_URL + '/' + path; + }); + uni.previewImage({ + current: index, + urls + }); + }, async handleDelete(id) { uni.showModal({ title: '确认删除', @@ -477,6 +601,74 @@ export default { color: #333; box-sizing: border-box; } + + .upload-section { + .upload-list { + display: flex; + flex-wrap: wrap; + gap: 20rpx; + + .upload-item { + width: 180rpx; + height: 180rpx; + position: relative; + border-radius: 10rpx; + overflow: hidden; + border: 1rpx solid #e5e5e5; + + image { + width: 100%; + height: 100%; + } + + .delete-btn { + position: absolute; + top: 10rpx; + right: 10rpx; + width: 36rpx; + height: 36rpx; + background-color: rgba(0, 0, 0, 0.6); + color: #fff; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-size: 28rpx; + line-height: 1; + } + } + + .upload-btn { + width: 180rpx; + height: 180rpx; + border: 1rpx dashed #d9d9d9; + border-radius: 10rpx; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + background-color: #fafafa; + + .iconfont { + font-size: 40rpx; + color: #bfbfbf; + margin-bottom: 10rpx; + } + + text { + font-size: 24rpx; + color: #999; + } + } + } + + .hint { + display: block; + margin-top: 16rpx; + font-size: 20rpx; + color: #999; + } + } } .remark-item { @@ -590,6 +782,28 @@ export default { color: #333; } } + + .image-grid { + margin-top: 12rpx; + margin-left: 0; + display: flex; + flex-wrap: wrap; + gap: 12rpx; + + .image-item { + width: calc((100% - 24rpx) / 3); + aspect-ratio: 1 / 1; + border-radius: 8rpx; + overflow: hidden; + background-color: #f5f5f5; + + image { + width: 100%; + height: 100%; + display: block; + } + } + } } } diff --git a/app/pages/supply_chain/notice/index.vue b/app/pages/supply_chain/notice/index.vue index c1863bd..8abf459 100644 --- a/app/pages/supply_chain/notice/index.vue +++ b/app/pages/supply_chain/notice/index.vue @@ -42,20 +42,9 @@ {{ item.noticeTitle || '未命名通知' }} - - - {{ typeText(item.type) }} - - - {{ statusText(item.status) }} - - - {{ smsText(item.smsStatus) }} - - - {{ formatDate(item.noticeTime) }} + {{ item.noticeTime }} @@ -68,12 +57,8 @@ {{ item.noticeScope || '—' }} - 拟稿单位: - {{ item.draftDept || '—' }} - - - 通知来源: - {{ item.noticeSource }} + 通知单位: + {{ item.draftDeptName || '—' }} @@ -97,6 +82,7 @@ import { pubnoticeListApi } from '@/api/pubnotice.js'; export default { + dicts: ['sys_notice_type'], data() { return { query: { @@ -109,21 +95,7 @@ export default { limit: 10, loading: false, finished: false, - typeClassMap: { - 1: 'tag-internal', - 2: 'tag-external', - '__default__': '' - }, - statusClassMap: { - 0: 'status-draft', - 1: 'status-submit', - '__default__': '' - }, - smsClassMap: { - 0: 'sms-unsent', - 1: 'sms-sent', - '__default__': '' - } + }; }, onLoad() { @@ -202,38 +174,14 @@ export default { }, contentPreview(content) { if (content === undefined || content === null) return ''; - const s = String(content).replace(/\s+/g, ' ').trim(); + const s = String(content) + .replace(/<[^>]+>/g, ' ') + .replace(/\s+/g, ' ') + .trim(); if (!s) return ''; return s.length > 80 ? s.slice(0, 80) + '...' : s; }, - formatDate(val) { - if (!val) return ''; - if (typeof val === 'string') { - return val.replace('T', ' ').slice(0, 19); - } - if (val instanceof Date) { - const pad = (n) => (n < 10 ? '0' + n : '' + n); - return `${val.getFullYear()}-${pad(val.getMonth() + 1)}-${pad(val.getDate())} ${pad( - val.getHours() - )}:${pad(val.getMinutes())}`; - } - return String(val); - }, - typeText(type) { - if (type === 1 || type === '1') return '内部'; - if (type === 2 || type === '2') return '外部'; - return type || '—'; - }, - statusText(status) { - if (status === 0 || status === '0') return '草稿'; - if (status === 1 || status === '1') return '提交'; - return status ?? '—'; - }, - smsText(smsStatus) { - if (smsStatus === 0 || smsStatus === '0') return '未发'; - if (smsStatus === 1 || smsStatus === '1') return '已发'; - return smsStatus ?? '—'; - }, + }, }; @@ -353,49 +301,6 @@ export default { } } - .tag-row { - display: flex; - flex-wrap: wrap; - gap: 10rpx; - } - - .tag { - padding: 6rpx 16rpx; - border-radius: 20rpx; - font-size: 20rpx; - line-height: 1; - } - - .tag-internal { - background-color: #e6f7ff; - color: #409eff; - } - - .tag-external { - background-color: #fff7e6; - color: #fa8c16; - } - - .status-draft { - background-color: #f5f5f5; - color: #666; - } - - .status-submit { - background-color: #f6ffed; - color: #52c41a; - } - - .sms-unsent { - background-color: #f5f5f5; - color: #999; - } - - .sms-sent { - background-color: #e6fffb; - color: #13c2c2; - } - .card-body { .row { display: flex; diff --git a/app/pages/supply_chain/notice_detail/index.vue b/app/pages/supply_chain/notice_detail/index.vue index 3df4581..a774ae5 100644 --- a/app/pages/supply_chain/notice_detail/index.vue +++ b/app/pages/supply_chain/notice_detail/index.vue @@ -5,11 +5,6 @@ {{ notice.noticeTitle || '未命名通知' }} - - {{ typeText(notice.type) }} - {{ statusText(notice.status) }} - {{ smsText(notice.smsStatus) }} - @@ -17,29 +12,17 @@ 通知类型: {{ notice.noticeType }} - - 通知来源: - {{ notice.noticeSource }} - - - 拟稿单位: - {{ notice.draftDept }} + + 通知单位: + {{ notice.draftDeptName }} 通知范围: {{ notice.noticeScope }} - - 业务信息: - {{ bizText(notice.bizType, notice.bizId) }} - 通知时间: - {{ formatDate(notice.noticeTime) }} - - - 备注: - {{ notice.remark }} + {{ notice.noticeTime }} @@ -52,6 +35,36 @@ > 暂无通知内容 + + + 附件列表 + + + + + + + {{ file.name || '未命名附件' }} + + {{ (file.attType || '文件').toUpperCase() }} + · {{ formatFileSize(file.attSize) }} + + + + {{ isImageFile(file) ? '预览' : '打开' }} + + + @@ -69,13 +82,16 @@