| src/components/CustomImageViewer/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/project/fund/applyDetail/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/project/fund/medicalCostApply/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/project/fund/performancedetails/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/project/travelexpenseapply/travelexpensedetail/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/components/CustomImageViewer/index.vue
@@ -1,14 +1,34 @@ <template> <div v-if="visible" class="custom-image-viewer"> <div v-if="visible" class="custom-image-viewer" @wheel.prevent="handleWheel"> <!-- 遮罩层 --> <div class="el-image-viewer__mask" @click.self="handleMaskClick"></div> <!-- 图片预览主体 --> <!-- 关闭 --> <div class="el-image-viewer__btn el-image-viewer__close" @click="close"> <i class="el-icon-close"></i> </div> <!-- 上一张按钮 --> <!-- 工具栏 --> <div class="viewer-toolbar"> <div class="toolbar-btn" title="放大" @click="zoomIn"> <i class="el-icon-zoom-in"></i> </div> <div class="toolbar-btn" title="缩小" @click="zoomOut"> <i class="el-icon-zoom-out"></i> </div> <div class="toolbar-btn" title="顺时针旋转" @click="rotateRight"> <i class="el-icon-refresh-right"></i> </div> <div class="toolbar-btn" title="逆时针旋转" @click="rotateLeft"> <i class="el-icon-refresh-left"></i> </div> <div class="toolbar-btn" title="还原" @click="resetTransform"> <i class="el-icon-s-home"></i> </div> <span class="toolbar-info">{{ currentIndex + 1 }} / {{ urlList.length }}</span> </div> <!-- 上一张 --> <div class="el-image-viewer__btn el-image-viewer__prev" :class="{ 'is-disabled': isFirst }" @@ -17,7 +37,7 @@ <i class="el-icon-arrow-left"></i> </div> <!-- 下一张按钮 --> <!-- 下一张 --> <div class="el-image-viewer__btn el-image-viewer__next" :class="{ 'is-disabled': isLast }" @@ -27,17 +47,25 @@ </div> <!-- 图片展示 --> <div class="el-image-viewer__canvas"> <div class="el-image-viewer__canvas" @mousedown="handleMouseDown" @mousemove="handleMouseMove" @mouseup="handleMouseUp" @mouseleave="handleMouseUp" > <img v-if="currentUrl" :src="currentUrl" :key="currentIndex" @error="handleError" class="el-image-viewer__img" :style="imgStyle" draggable="false" /> </div> <!-- 自定义提示信息 --> <!-- 提示信息 --> <div v-if="showTip" class="custom-viewer-tip"> {{ tipMessage }} </div> @@ -48,24 +76,22 @@ export default { name: 'CustomImageViewer', props: { urlList: { type: Array, default: () => [] }, initialIndex: { type: Number, default: 0 }, visible: { type: Boolean, default: false } urlList: { type: Array, default: () => [] }, initialIndex: { type: Number, default: 0 }, visible: { type: Boolean, default: false } }, data() { return { currentIndex: this.initialIndex, showTip: false, tipMessage: '' tipMessage: '', scale: 1, rotate: 0, // 拖拽 dragging: false, dragStart: { x: 0, y: 0 }, offsetX: 0, offsetY: 0, }; }, computed: { @@ -77,174 +103,159 @@ }, isLast() { return this.currentIndex === this.urlList.length - 1; } }, imgStyle() { return { transform: `translate(${this.offsetX}px, ${this.offsetY}px) scale(${this.scale}) rotate(${this.rotate}deg)`, transition: this.dragging ? 'none' : 'transform 0.3s', cursor: this.scale > 1 ? (this.dragging ? 'grabbing' : 'grab') : 'default', }; }, }, watch: { initialIndex(newVal) { this.currentIndex = newVal; this.resetTransform(); }, visible(newVal) { if (!newVal) { this.showTip = false; this.tipMessage = ''; this.removeKeyListener(); } else { this.$nextTick(() => { this.addKeyListener(); }); this.$nextTick(() => { this.addKeyListener(); }); } } }, }, methods: { close() { this.$emit('update:visible', false); this.$emit('close'); }, handleMaskClick() { this.close(); }, handleMaskClick() { this.close(); }, // 切换图片 goPrev() { if (this.isFirst) { this.showTipMessage('这已经是第一张了'); return; } if (this.isFirst) { this.showTipMessage('已是第一张'); return; } this.currentIndex--; this.hideTip(); this.resetTransform(); }, goNext() { if (this.isLast) { this.showTipMessage('这已经是最后一张了'); return; } if (this.isLast) { this.showTipMessage('已是最后一张'); return; } this.currentIndex++; this.hideTip(); }, showTipMessage(message) { this.tipMessage = message; this.showTip = true; setTimeout(() => { this.hideTip(); }, 2000); }, hideTip() { this.showTip = false; this.tipMessage = ''; }, handleError() { console.error(`图片加载失败: ${this.currentUrl}`); this.resetTransform(); }, // 键盘事件处理 handleKeydown(event) { switch(event.key) { case 'ArrowLeft': event.preventDefault(); // 阻止默认行为 this.goPrev(); break; case 'ArrowRight': event.preventDefault(); this.goNext(); break; case 'Escape': event.preventDefault(); this.close(); break; // 缩放 zoomIn() { this.scale = Math.min(this.scale + 0.25, 5); if (this.scale <= 1) { this.offsetX = 0; this.offsetY = 0; } }, zoomOut() { this.scale = Math.max(this.scale - 0.25, 0.25); if (this.scale <= 1) { this.offsetX = 0; this.offsetY = 0; } }, handleWheel(e) { if (e.deltaY < 0) this.zoomIn(); else this.zoomOut(); }, // 旋转 rotateRight() { this.rotate = (this.rotate + 90) % 360; }, rotateLeft() { this.rotate = (this.rotate - 90) % 360; }, // 还原 resetTransform() { this.scale = 1; this.rotate = 0; this.offsetX = 0; this.offsetY = 0; }, // 拖拽(仅在放大时启用) handleMouseDown(e) { if (this.scale <= 1) return; this.dragging = true; this.dragStart = { x: e.clientX - this.offsetX, y: e.clientY - this.offsetY }; }, handleMouseMove(e) { if (!this.dragging) return; this.offsetX = e.clientX - this.dragStart.x; this.offsetY = e.clientY - this.dragStart.y; }, handleMouseUp() { this.dragging = false; }, showTipMessage(msg) { this.tipMessage = msg; this.showTip = true; setTimeout(() => { this.hideTip(); }, 2000); }, hideTip() { this.showTip = false; this.tipMessage = ''; }, handleError() { console.error('图片加载失败:', this.currentUrl); }, // 键盘 handleKeydown(e) { switch(e.key) { case 'ArrowLeft': e.preventDefault(); this.goPrev(); break; case 'ArrowRight': e.preventDefault(); this.goNext(); break; case 'Escape': e.preventDefault(); this.close(); break; case '+': case '=': e.preventDefault(); this.zoomIn(); break; case '-': e.preventDefault(); this.zoomOut(); break; case '0': e.preventDefault(); this.resetTransform(); break; } }, addKeyListener() { document.addEventListener('keydown', this.handleKeydown); }, removeKeyListener() { document.removeEventListener('keydown', this.handleKeydown); } addKeyListener() { document.addEventListener('keydown', this.handleKeydown); }, removeKeyListener() { document.removeEventListener('keydown', this.handleKeydown); }, }, mounted() { if (this.visible) { this.addKeyListener(); } }, beforeUnmount() { this.removeKeyListener(); } mounted() { if (this.visible) this.addKeyListener(); }, beforeUnmount() { this.removeKeyListener(); }, }; </script> <style scoped> .custom-image-viewer { position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 2000; /* 确保 z-index 足够高 */ position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 2000; } .el-image-viewer__mask { position: absolute; width: 100%; height: 100%; position: absolute; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); } .el-image-viewer__btn { position: absolute; z-index: 1; color: #fff; background-color: rgba(0, 0, 0, 0.3); border-radius: 50%; width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; cursor: pointer; user-select: none; position: absolute; z-index: 1; color: #fff; background-color: rgba(0, 0, 0, 0.3); border-radius: 50%; width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; cursor: pointer; user-select: none; } .el-image-viewer__btn.is-disabled { cursor: not-allowed; opacity: 0.5; } .el-image-viewer__close { top: 20px; right: 20px; } .el-image-viewer__prev { left: 20px; top: 50%; transform: translateY(-50%); } .el-image-viewer__next { right: 20px; top: 50%; transform: translateY(-50%); } .el-image-viewer__btn.is-disabled { cursor: not-allowed; opacity: 0.5; .viewer-toolbar { position: absolute; bottom: 30px; left: 50%; transform: translateX(-50%); z-index: 1; display: flex; align-items: center; gap: 8px; padding: 8px 16px; background: rgba(0, 0, 0, 0.6); border-radius: 24px; } .el-image-viewer__close { top: 20px; right: 20px; .toolbar-btn { width: 36px; height: 36px; border-radius: 50%; display: flex; align-items: center; justify-content: center; cursor: pointer; color: #fff; font-size: 18px; transition: background 0.2s; } .el-image-viewer__prev { left: 20px; top: 50%; transform: translateY(-50%); } .el-image-viewer__next { right: 20px; top: 50%; transform: translateY(-50%); } .toolbar-btn:hover { background: rgba(255, 255, 255, 0.2); } .toolbar-info { color: rgba(255, 255, 255, 0.7); font-size: 13px; margin-left: 8px; white-space: nowrap; } .el-image-viewer__canvas { display: flex; justify-content: center; align-items: center; height: 100%; display: flex; justify-content: center; align-items: center; height: 100%; overflow: hidden; } .el-image-viewer__img { max-width: 90%; max-height: 90%; object-fit: contain; max-width: 90%; max-height: 90%; object-fit: contain; user-select: none; -webkit-user-drag: none; } .custom-viewer-tip { position: absolute; bottom: 50px; left: 50%; transform: translateX(-50%); background-color: rgba(0, 0, 0, 0.7); color: #fff; padding: 10px 20px; border-radius: 4px; z-index: 2001; position: absolute; bottom: 100px; left: 50%; transform: translateX(-50%); background-color: rgba(0, 0, 0, 0.7); color: #fff; padding: 10px 20px; border-radius: 4px; z-index: 2001; } </style> src/views/project/fund/applyDetail/index.vue
@@ -69,6 +69,14 @@ <el-input :disabled="true" v-model="form.donorname" placeholder="请输入捐献者姓名" /> </el-form-item> </el-col> <el-col :span="4"> <div style="margin-left: 10px;"> <dict-tag :options="dict.type.sys_DonationStatus" :value="form.invoicecount" /> </div> </el-col> <el-col :span="10"> <el-form-item label="申请说明" prop="remark"> <el-input v-model="form.remark" placeholder="申请说明" /> @@ -800,6 +808,7 @@ //"sys_finsubject", //"sys_financeitemtype", //"sys_expensetype", 'sys_DonationStatus', "sys_recordstatus", "sys_professionaltitle" ], @@ -1268,9 +1277,12 @@ this.businessType == "2" || this.businessType == "3" ) { console.log(this.curCase,'this.curCase'); this.form.infoid = this.curCase.id; this.form.donorname = this.curCase.name; this.form.donorno = this.curCase.donorno; this.form.invoicecount = this.curCase.recordstate; } //初始化明细 src/views/project/fund/medicalCostApply/index.vue
@@ -545,7 +545,7 @@ id: 0, businessType: "3", operationType: "add", curCase: this.curCase curCase: this.curCase, } }); } else { src/views/project/fund/performancedetails/index.vue
@@ -661,16 +661,18 @@ v-if="this.previewpdf && pdfimgsrcList.length" class="pdfimgmin" > <!-- <img :src="pdfimg" /> --> <el-image style="width: 95%; height: 90%" :src="pdfimg" :preview-src-list="pdfimgsrcList" > <!-- <div slot="error" class="image-slot"> <i class="el-icon-picture-outline"></i> </div> --> </el-image> @click="handleImageClick(0)" /> <custom-image-viewer :url-list="pdfimgsrcList" :initial-index="currentIndex" :visible="viewerVisible" @update:visible="viewerVisible = $event" @close="handleViewerClose" /> </div> <div v-else class="pdfimgmins">{{ hintitle }}</div> </div> @@ -764,16 +766,18 @@ v-if="this.previewpdf && invoicepdfimgsrcList.length" class="pdfimgmin" > <!-- <img :src="pdfimg" /> --> <el-image style="width: 95%; height: 90%" :src="invoicepdfimg" :preview-src-list="invoicepdfimgsrcList" > <!-- <div slot="error" class="image-slot"> <i class="el-icon-picture-outline"></i> </div> --> </el-image> @click="invoiceHandleImageClick(0)" /> <custom-image-viewer :url-list="invoicepdfimgsrcList" :initial-index="invoiceCurrentIndex" :visible="invoiceViewerVisible" @update:visible="invoiceViewerVisible = $event" @close="invoiceHandleViewerClose" /> </div> <div v-else class="pdfimgmins">{{ hintitle }}</div> </div> @@ -872,12 +876,14 @@ import Li_area_select from "@/components/Address"; import OrgSelecter from "@/views/project/components/orgselect"; import { getToken } from "@/utils/auth"; import CustomImageViewer from "@/components/CustomImageViewer"; export default { //import引入的组件需要注入到对象中才能使用 components: { Li_area_select, OrgSelecter OrgSelecter, CustomImageViewer }, name: "fundApply", @@ -1178,6 +1184,10 @@ pdfimgsrcList: [], pdfVisible: false, previewpdf: false, viewerVisible: false, currentIndex: 0, invoiceViewerVisible: false, invoiceCurrentIndex: 0, hintitle: "请上传文件后查看", atpresent: "", Savereminder: false, //提醒保存弹框 @@ -2899,7 +2909,23 @@ destroyed() { window.removeEventListener("beforeunload", e => this.beforeunloadFn(e)); }, //生命周期 - 销毁完成 activated() {} //如果页面有keep-alive缓存功能,这个函数会触发 activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发 // 图片预览 handleImageClick(index) { this.currentIndex = index; this.viewerVisible = true; }, handleViewerClose() { this.viewerVisible = false; }, invoiceHandleImageClick(index) { this.invoiceCurrentIndex = index; this.invoiceViewerVisible = true; }, invoiceHandleViewerClose() { this.invoiceViewerVisible = false; }, }; </script> src/views/project/travelexpenseapply/travelexpensedetail/index.vue
@@ -12,10 +12,27 @@ </el-col> <el-col :span="5"> <el-form-item label="经办人" prop="username"> <<<<<<< HEAD <el-select v-model="form.username" clearable filterable allow-create ref="getReportname" default-first-option placeholder="请选择"> <el-option v-for="item in personsList" :key="item.reportNo" :label="item.reportName" :value="item.reportName"> ======= <el-select v-model="form.username" clearable filterable allow-create ref="getReportname" default-first-option placeholder="请选择" > <el-option v-for="item in personsList" :label="item.reportName" :value="item.reportName" > >>>>>>> 5b26f73b191ca95f12df24ec3e3d7930b4590be7 </el-option> </el-select> </el-form-item> @@ -40,19 +57,62 @@ </el-col> <el-col :span="5"> <el-form-item label="报销类别" prop="costtype"> <<<<<<< HEAD <el-select v-model="form.costtype" value-key="value" placeholder="请选择报销人员类别"> <el-option v-for="dict in dict.type.sys_travelexpensebelong" :key="dict.value" :label="dict.label" :value="dict.value"></el-option> ======= <el-select v-model="form.costtype" value-key="value" placeholder="请选择报销人员类别" > <el-option v-for="dict in dict.type.sys_travelexpensebelong" :label="dict.label" :value="dict.value" ></el-option> >>>>>>> 5b26f73b191ca95f12df24ec3e3d7930b4590be7 </el-select> </el-form-item> </el-col> <el-col :span="5"> <<<<<<< HEAD <el-form-item label="捐献者" prop="infoid" v-show="form.costtype == 3||form.costtype == 4"> <el-select v-model="form.infoid" @change="selectbaseinfo" clearable filterable placeholder="请选择捐献者"> <el-option v-for="item in baselist" :key="item.index" :label="item.name" :value="item.infoid"> ======= <el-form-item label="捐献者" prop="infoid" v-show="form.costtype == 4" > <el-select v-model="form.infoid" @change="selectbaseinfo" @clear="clearDonatorInfo" clearable filterable placeholder="请选择捐献者" > <el-option v-for="item in baselist" :key="item.index" :label="item.name" :value="item.infoid" > >>>>>>> 5b26f73b191ca95f12df24ec3e3d7930b4590be7 </el-option> </el-select> </el-form-item> </el-col> <el-col :span="4"> <div style="margin-left: 10px;"> <dict-tag :options="dict.type.sys_DonationStatus" :value="form.invoicecount" /> </div> </el-col> </el-row> <el-row style="margin-top: 10px"> @@ -86,7 +146,7 @@ <el-form-item label="出差人" prop="travelers"> <el-select v-model="form.travelers" clearable filterable allow-create ref="getReportname" default-first-option placeholder="请选择" @change="getAccountinfo()"> <el-option v-for="item in travelers" :key="item.reportNo" :label="item.reportName" <el-option v-for="item in travelers" :label="item.reportName" :value="item.reportName"> </el-option> </el-select> @@ -204,10 +264,28 @@ </el-table-column> <el-table-column prop="personname" slot="" label="费用人员" align="center" fixed width="110"> <template slot-scope="scope"> <<<<<<< HEAD <el-select v-model="scope.row.personname" clearable filterable allow-create default-first-option placeholder="请选择"> <el-option v-for="item in personsSel" :key="item.id" :label="item.reportNameDesc" :value="item.reportName"> ======= <el-select v-model="scope.row.personname" clearable filterable allow-create default-first-option placeholder="请选择" @focus1="getPersons(scope.row)" > <el-option v-for="(item, index) in personsSel" :key="`${item.reportNo}_${index}`" :label="item.reportName" :value="item.reportName" > >>>>>>> 5b26f73b191ca95f12df24ec3e3d7930b4590be7 </el-option> </el-select> </template> @@ -415,9 +493,28 @@ </el-table-column> <el-table-column prop="personname" slot="" label="收款人" align="center" fixed width="200"> <template slot-scope="scope"> <<<<<<< HEAD <el-select v-model="scope.row.personname" clearable filterable allow-create ref="getReportname" default-first-option placeholder="请选择" @change="getAccountinfo2(scope.row, scope.row.persontype)"> <el-option v-for="item in personsSel" :key="item.id" :label="item.reportNameDesc" :value="item.id"> ======= <el-select v-model="scope.row.personname" clearable filterable allow-create ref="getReportname" default-first-option placeholder="请选择" @change="getAccountinfo2(scope.row, scope.row.persontype)" > <el-option v-for="(item, index) in personsSel" :key="`${item.reportNo}_${index}`" :label="item.reportName" :value="item.reportName" > >>>>>>> 5b26f73b191ca95f12df24ec3e3d7930b4590be7 </el-option> </el-select> </template> @@ -602,10 +699,21 @@ <!-- <el-image style="width: 95%; height: 90%" :src="pdfimg" <<<<<<< HEAD :preview-src-list="pdfimgsrcList" --> > <el-image ref="imagePreview" style="width: 95%; height: 90%" :src="pdfimg" @click="handleImageClick(initialIndex)"> ======= :preview-src-list="pdfimgsrcList" > --> <el-image ref="imagePreview" style="width: 95%; height: 90%" :src="pdfimg" @click="handleImageClick(initialIndex)" > >>>>>>> 5b26f73b191ca95f12df24ec3e3d7930b4590be7 </el-image> <custom-image-viewer :url-list="pdfimgsrcList" :initial-index="currentIndex" :visible="viewerVisible" @update:visible="viewerVisible = $event" @close="handleViewerClose" /> @@ -741,7 +849,8 @@ "sys_recordstatus", "sys_travelexpensebelong", "sys_traffictype", "sys_area_name" "sys_area_name", "sys_DonationStatus" ], data() { return { @@ -1127,6 +1236,15 @@ name: file.name, url: URL.createObjectURL(blob) }); // console.log(file.response.url); // console.log(file); this.pdfimgsrcList.push(file.response.url); this.fileListto.push({ name: file.response.fileName, url: file.response.url }); console.log(URL.createObjectURL(blob), "ur转换"); }) .catch(error => { console.error("Error loading image", error); @@ -1678,10 +1796,22 @@ if (item.id == this.form.infoid) { this.form.donorno = item.donorno; this.form.donorname = item.name; // 新增:将捐献者的 recordstate 赋值到 invoicecount if (item.recordstate !== undefined && item.recordstate !== null) { this.form.invoicecount = item.recordstate.toString(); } else { this.form.invoicecount = ""; // 如果 recordstate 为空,清空字段 } } }); }, // 添加清除方法 clearDonatorInfo() { this.form.donorno = ""; this.form.donorname = ""; this.form.invoicecount = ""; // 清空 invoicecount }, onpick(e) { // console.log(e,this.value1) }, @@ -2095,6 +2225,7 @@ // return; // } <<<<<<< HEAD // 1. 在 reduce 累加时,直接传入字符串给 Decimal,并使用 .plus() 方法进行累加 // 初始值设为 new Decimal(0),确保全程高精度运算 const addnumber = this.rbPayees.reduce((amount, item) => { @@ -2106,6 +2237,14 @@ // 2. 使用 Decimal 的 .eq() 方法进行严格相等比较 // 这样既解决了精度问题,也解决了类型转换比较的问题 if (!addnumber.eq(this.form.amountrequested)) { ======= // 保留2位小数后进行比较 const requestedAmount = Number(this.form.amountrequested); const calculatedAmount = Number(addnumber); // 使用toFixed保留2位小数 if (requestedAmount.toFixed(2) !== calculatedAmount.toFixed(2)) { >>>>>>> 5b26f73b191ca95f12df24ec3e3d7930b4590be7 this.$message({ message: "报销请款表中合计金额不等于报销单的报销金额,请更正后再保存!!", type: "warning"