whx vor 3 Monaten
Ursprung
Commit
e41d1ce61f

+ 95 - 47
virgo.wzfrontend/workark/src/components/common/pdfViewer.vue

@@ -15,47 +15,57 @@
 				</div>
 			</div>
 			<div class="operation-button" v-if="type === 'edit'">
+				<!-- <div class="button-item">
+					<el-button type="primary" size="mini">添加签字</el-button>
+				</div> -->
 				<div class="button-item">
-					<el-button type="primary" size="mini">签字</el-button>
-				</div>
-				<div class="button-item">
-					<el-button type="primary" size="mini" @click="insertSeal">盖章</el-button>
+					<el-button type="primary" size="mini" @click="insertSeal">添加印章</el-button>
 				</div>
 			</div>
 		</div>
 		<div class="hui-dialog-submit" v-if="type === 'edit'">
 			<el-button size="small" @click="$emit('callback')">取 消</el-button>
 			<el-button size="small" type="primary" @click="submit" :loading="loading">提 交</el-button>
-		</div>
-		
+		</div>
+		<el-dialog :close-on-click-modal="false" title="选择公章" :visible.sync="dialogVisibles" width="600px"
+			:append-to-body="true">
+			<select-seal @callback="callback"></select-seal>
+		</el-dialog>
 	</div>
 </template>
 
 <script>
 	import pdf from 'pdfvuer';
 	import * as fabric from 'fabric';
+	const selectSeal = () => import('@/components/common/selectSeal')
 	export default {
 		props: ['list', 'type'],
 		data() {
 			return {
+				node: {},
 				pdfDoc: null,
 				currentPage: 1,
 				totalPages: 0,
 				thumbnails: [], // 存储缩略图 Base64
 				renderTask: null,
 				fabricCanvas: null,
-				sealObj: null,
-				loading: false
+				sealObj: {},
+				loading: false,
+				dialogVisibles: false,
+				sealData: [],
+				pageData: {}
 			}
 		},
 		beforeDestroy() {
 			if (this.fabricCanvas) {
+				this.fabricCanvas.dispose();
 				document.removeEventListener('keydown', this.initDelete);
 			}
 		},
 		async mounted() {
 			if (this.list.length > 0) {
-				await this.loadPdf(this.list[0].url);
+				this.node = this.list[0];
+				await this.loadPdf(this.node.url);
 				await this.generateThumbnails();
 				await this.changePage(1);
 			}
@@ -63,6 +73,9 @@
 				document.addEventListener('keydown', this.initDelete);
 			}
 		},
+		components: {
+			selectSeal
+		},
 		methods: {
 			//加载pdf
 			async loadPdf(url) {
@@ -100,6 +113,7 @@
 			},
 			// 切换页面
 			async changePage(pageNum) {
+				if (this.fabricCanvas) this.updatePageData();
 				this.currentPage = pageNum;
 				const page = await this.pdfDoc.getPage(pageNum);
 				await this.renderMainPage(page);
@@ -129,37 +143,23 @@
 				canvas.height = Math.floor(viewport.height * outputScale);
 				canvas.style.width = Math.floor(viewport.width) + "px";
 				canvas.style.height = Math.floor(viewport.height) + "px";
-				if (this.fabricCanvas) this.fabricCanvas.dispose();
+				if (this.fabricCanvas) this.fabricCanvas.clear();
 				if (this.type === 'edit') {
-					this.$refs.fabricCanvas.style.width = Math.floor(viewport.width) + "px";
-					this.$refs.fabricCanvas.style.height = Math.floor(viewport.height) + "px";
-					this.fabricCanvas = new fabric.Canvas('fabricCanvas', {
-						width: Math.floor(viewport.width), // 设置画布宽度
-						height: Math.floor(viewport.height), // 设置画布高度
-					});
+					if (!this.fabricCanvas) {
+						this.$refs.fabricCanvas.style.width = Math.floor(viewport.width) + "px";
+						this.$refs.fabricCanvas.style.height = Math.floor(viewport.height) + "px";
+						this.fabricCanvas = new fabric.Canvas('fabricCanvas', {
+							width: Math.floor(viewport.width), // 设置画布宽度
+							height: Math.floor(viewport.height), // 设置画布高度
+						});
+					}
+					if (this.pageData[this.currentPage]) {
+						for (let i = 0; i < this.pageData[this.currentPage].length; i++) {
+							this.setImage(this.pageData[this.currentPage][i]);
+						}
+					}
 				}
 			},
-			insertSeal() {
-				if (!this.fabricCanvas) return;
-				fabric.Image.fromURL('./assets/wechat_code.jpg').then(img => {
-					let scale = 100 / img.width;
-					img.scale(scale);
-					img.set({
-						top: 0,
-						left: 0
-					})
-					this.sealObj = img;
-					// 将文字添加到画布
-					this.fabricCanvas.add(img);
-					this.fabricCanvas.renderAll();
-				});
-			},
-			sureSeal() {
-				this.fabricCanvas.discardActiveObject();
-				this.sealObj.set({
-					selectable: false
-				});
-			},
 			initDelete(event) {
 				if (!this.fabricCanvas) return;
 				if (event.key === 'Delete' || event.key === 'Backspace') {
@@ -169,17 +169,65 @@
 					}
 				}
 			},
+			insertSeal() {
+				this.dialogVisibles = true;
+
+			},
+			callback(data) {
+				this.dialogVisibles = false;
+				if (data) this.setImage({
+					pictureAddress: data.fileNode.node.url,
+					sealId: data.id,
+					type: 'add'
+				});
+			},
+			setImage(data) {
+				if (!this.fabricCanvas) return;
+				console.log(data);
+				fabric.Image.fromURL(data.pictureAddress).then(img => {
+					if (data.type === 'add') {
+						let scale = 100 / img.width;
+						img.scale(scale);
+						img.set({
+							top: 0,
+							left: 0,
+							sealId: data.sealId,
+							url: data.pictureAddress
+						})
+					} else {
+						let scale = data.pictureWidth / img.width;
+						img.scale(scale);
+						img.set({
+							top: data.top,
+							left: data.left,
+							sealId: data.sealId,
+							url: data.pictureAddress
+						})
+					}
+					// 将文字添加到画布
+					this.fabricCanvas.add(img);
+					this.fabricCanvas.renderAll();
+				});
+			},
+			updatePageData() {
+				if (!this.fabricCanvas) return;
+				this.pageData[this.currentPage] = this.fabricCanvas.getObjects().map(node => {
+					return {
+						left: node.left,
+						top: node.top,
+						pictureWidth: node.width * node.scaleX,
+						pictureHeight: node.height * node.scaleY,
+						pictureAddress: node.url,
+						pageSize: this.currentPage,
+						sealId: node.sealId,
+						pdfId: this.node.pdfId,
+						payOrganizationId: this.node.payOrganizationId,
+						organizationId: this.node.organizationId
+					}
+				});
+			},
 			submit() {
-				const allObjects = this.fabricCanvas.getObjects();
-				for (let i = 0; i < allObjects.length; i++) {
-					let item = allObjects[i];
-					console.log({
-						left: item.left,
-						top: item.top,
-						width: item.width * item.scaleX,
-						height: item.height * item.scaleY
-					});
-				}
+				this.updatePageData();
 			}
 		},
 	}

+ 50 - 0
virgo.wzfrontend/workark/src/components/common/selectSeal.vue

@@ -0,0 +1,50 @@
+<template>
+	<div class="hui-flex hui-dialog">
+		<div class="hui-flex-box">
+			<el-empty v-if="sealData.length == 0" description="暂未添加公章"></el-empty>
+			<el-radio v-else v-model="sealVal" v-for="item in sealData" :key="item.id" :label="item.id" border
+				style="margin: 10px;">
+				{{ item.name }}
+			</el-radio>
+		</div>
+		<div class="hui-dialog-submit">
+			<el-button size="small" @click="$emit('callback')">取 消</el-button>
+			<el-button size="small" type="primary" @click="submit">确 定</el-button>
+		</div>
+	</div>
+</template>
+
+<script>
+	import {
+		getSealList
+	} from '@/api/organization';
+	export default {
+		data() {
+			return {
+				sealData: [],
+				sealVal: ''
+			}
+		},
+		mounted() {
+			this.init()
+		},
+		methods: {
+			init() {
+				getSealList(this.$store.getters.organization.id).then(res => {
+					if (res.state) {
+						this.sealData = res.data;
+						if (this.sealData.length === 0) return;
+						this.sealVal = this.sealData[0].id;
+					}
+				})
+			},
+			submit() {
+				let data = this.sealData.find(node => node.id === this.sealVal);
+				this.$emit('callback', data);
+			}
+		}
+	}
+</script>
+
+<style>
+</style>

+ 36 - 11
virgo.wzfrontend/workark/src/components/work/serve/list/detail.vue

@@ -58,7 +58,7 @@
 						<div class="hui-detail-item" v-if="part.contractId">
 							<div class="hui-detail-label">合同内容</div>
 							<div class="hui-detail-value">
-								<span class="color-primary" @click="action({
+								<span class="color-primary" style="cursor: pointer;" @click="action({
 									id:7,
 									name:'查看合同'
 								})">
@@ -70,16 +70,24 @@
 							<div class="hui-detail-label">合同状态</div>
 							<div class="hui-detail-value">
 								<el-timeline>
-									<el-timeline-item :class="timelineClass(1)" :hide-timestamp="true">
+									<el-timeline-item :class="timelineClass(1)"
+										:hide-timestamp="!contractNode.createDate" :timestamp="contractNode.createDate">
 										服务商上传合同
 									</el-timeline-item>
 									<el-timeline-item :class="timelineClass(2)" :hide-timestamp="true">
-										服务商盖章
+										<div>客户确认</div>
+										<el-button v-if="timelineClass(2) === 'warning'" size="mini" type="primary"
+											@click="signSeal('client')">
+											签字盖章
+										</el-button>
 									</el-timeline-item>
 									<el-timeline-item :class="timelineClass(3)" :hide-timestamp="true">
-										客户盖章
+										服务商盖章
 									</el-timeline-item>
 									<el-timeline-item :class="timelineClass(4)" :hide-timestamp="true">
+										客户盖章
+									</el-timeline-item>
+									<el-timeline-item :class="timelineClass(5)" :hide-timestamp="true">
 										签约成功
 									</el-timeline-item>
 								</el-timeline>
@@ -114,7 +122,7 @@
 					<el-button size="small" type="primary" @click="selectContract">确定</el-button>
 				</div>
 			</div>
-			<pdf-viewer v-if="visible && actionType === 7" :list="contractList" type="preview"></pdf-viewer>
+			<pdf-viewer v-if="visible && actionType === 7" :list="contractList" :type="contractType"></pdf-viewer>
 		</el-dialog>
 		<el-dialog :close-on-click-modal="false" title="支付订单" :visible.sync="dialogVisible" width="600px"
 			:append-to-body="true">
@@ -153,7 +161,8 @@
 				actionType: '',
 				visibleTitle: '',
 				contractList: [],
-				contractNode: {}
+				contractNode: {},
+				contractType: 'preview'
 			}
 		},
 		mounted() {
@@ -217,10 +226,10 @@
 					type: 'primary',
 					name: '立即支付'
 				})
-				if (this.part.contract) this.activeList.push({
+				if (this.part.contractId) this.activeList.push({
 					id: 8,
-					type: 'warning',
-					name: '签订合同'
+					type: 'primary',
+					name: '确认合同'
 				});
 			},
 			initBindContract() {
@@ -240,7 +249,11 @@
 					case 2:
 						if (this.part.contractId && this.part.contractStatus === 0) str = 'warning';
 						break;
+					case 3:
+						break;
 					case 4:
+						break;
+					case 5:
 						str = 'last-timeline-item'
 						break;
 					default:
@@ -277,14 +290,26 @@
 					case 7:
 						this.contractList = [{
 							url: `${window.location.origin}/${config.baseURL}/file/workarkContract/pdf/show/${this.part.contractId}`
-						}]
-						console.log(this.contractList);
+						}];
+						this.contractType = 'preview';
 						this.visible = true;
 						break;
 					default:
 						break;
 				}
 			},
+			signSeal(type) {
+				this.actionType = 7;
+				this.visibleTitle = '签字盖章';
+				this.contractList = [{
+					url: `${window.location.origin}/${config.baseURL}/file/workarkContract/pdf/show/${this.part.contractId}`,
+					pdfId: this.part.contractId,
+					payOrganizationId: this.part.payOrganizationId,
+					organizationId: this.part.organizationId
+				}];
+				this.contractType = 'edit';
+				this.visible = true;
+			},
 			changePrice() {
 				let _self = this;
 				this.$prompt('请输入订单金额', 'WORKARK提示', {