whx há 1 ano atrás
pai
commit
e2c3173546
42 ficheiros alterados com 624 adições e 98 exclusões
  1. 1 0
      virgo.wzfrontend/console/public/reset.css
  2. 38 2
      virgo.wzfrontend/console/src/components/common/projectItemTreeSelect.vue
  3. 54 0
      virgo.wzfrontend/console/src/components/common/uploadFile.vue
  4. 24 4
      virgo.wzfrontend/console/src/components/work/contract/common/clause.vue
  5. 1 1
      virgo.wzfrontend/console/src/components/work/contract/common/documentUpload.vue
  6. 178 36
      virgo.wzfrontend/console/src/components/work/contract/common/selectTemplate.vue
  7. 157 30
      virgo.wzfrontend/console/src/components/work/contract/list/edit.vue
  8. 70 0
      virgo.wzfrontend/console/src/httpApi/contract.js
  9. 6 0
      virgo.wzfrontend/console/src/views/system/log.vue
  10. 78 9
      virgo.wzfrontend/console/src/views/work/contract/list.vue
  11. 1 1
      virgo.wzfrontend/src/main/resources/static/index.html
  12. 1 0
      virgo.wzfrontend/src/main/resources/static/reset.css
  13. 0 1
      virgo.wzfrontend/src/main/resources/static/static/css/192.968c8c10.css
  14. 1 0
      virgo.wzfrontend/src/main/resources/static/static/css/337.34ca17c0.css
  15. 1 0
      virgo.wzfrontend/src/main/resources/static/static/css/346.34ca17c0.css
  16. 0 1
      virgo.wzfrontend/src/main/resources/static/static/css/37.968c8c10.css
  17. 0 0
      virgo.wzfrontend/src/main/resources/static/static/css/609.f43f4c00.css
  18. 0 0
      virgo.wzfrontend/src/main/resources/static/static/css/636.f43f4c00.css
  19. 1 1
      virgo.wzfrontend/src/main/resources/static/static/js/153-legacy.7056c136.js
  20. 1 1
      virgo.wzfrontend/src/main/resources/static/static/js/17-legacy.b642adc7.js
  21. 0 1
      virgo.wzfrontend/src/main/resources/static/static/js/192-legacy.3c51e556.js
  22. 1 0
      virgo.wzfrontend/src/main/resources/static/static/js/337-legacy.f75ba3ba.js
  23. 1 0
      virgo.wzfrontend/src/main/resources/static/static/js/346.8ba9dd49.js
  24. 0 1
      virgo.wzfrontend/src/main/resources/static/static/js/37.c044cfb5.js
  25. 1 0
      virgo.wzfrontend/src/main/resources/static/static/js/39.6ad7ff94.js
  26. 0 1
      virgo.wzfrontend/src/main/resources/static/static/js/39.d1e82fe0.js
  27. 0 1
      virgo.wzfrontend/src/main/resources/static/static/js/529-legacy.05dc6088.js
  28. 1 0
      virgo.wzfrontend/src/main/resources/static/static/js/529-legacy.32bbec41.js
  29. 0 1
      virgo.wzfrontend/src/main/resources/static/static/js/568.0468dea8.js
  30. 1 0
      virgo.wzfrontend/src/main/resources/static/static/js/609.0ba8181f.js
  31. 0 1
      virgo.wzfrontend/src/main/resources/static/static/js/61-legacy.cefaf697.js
  32. 1 0
      virgo.wzfrontend/src/main/resources/static/static/js/61-legacy.fcfc9dbc.js
  33. 0 1
      virgo.wzfrontend/src/main/resources/static/static/js/61.bcb04045.js
  34. 1 0
      virgo.wzfrontend/src/main/resources/static/static/js/61.fcfc9dbc.js
  35. 1 0
      virgo.wzfrontend/src/main/resources/static/static/js/636-legacy.36487c56.js
  36. 1 1
      virgo.wzfrontend/src/main/resources/static/static/js/689.c1cbfd5b.js
  37. 0 0
      virgo.wzfrontend/src/main/resources/static/static/js/842.6b6de035.js
  38. 0 1
      virgo.wzfrontend/src/main/resources/static/static/js/913-legacy.60bb7049.js
  39. 1 0
      virgo.wzfrontend/src/main/resources/static/static/js/app-legacy.4901e24c.js
  40. 0 1
      virgo.wzfrontend/src/main/resources/static/static/js/app-legacy.9a379b0a.js
  41. 0 1
      virgo.wzfrontend/src/main/resources/static/static/js/app.a7c96cb4.js
  42. 1 0
      virgo.wzfrontend/src/main/resources/static/static/js/app.e01852aa.js

+ 1 - 0
virgo.wzfrontend/console/public/reset.css

@@ -7,6 +7,7 @@
 	font-family: LarkHackSafariFont, LarkEmojiFont, LarkChineseQuote, -apple-system, BlinkMacSystemFont, Helvetica Neue, Tahoma, PingFang SC, Microsoft Yahei, Arial, Hiragino Sans GB, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji;
 	font-weight: 400;
 	-webkit-font-smoothing: antialiased;
+	user-select: none;
 }
 
 html {

+ 38 - 2
virgo.wzfrontend/console/src/components/common/projectItemTreeSelect.vue

@@ -7,7 +7,8 @@
 					<span class="el-collapse-name">{{item.name}}</span>
 				</template>
 				<div>
-					<el-tree :data="item.children" :props="defaultProps" :expand-on-click-node="false" show-checkbox>
+					<el-tree :ref="'houseTree' + item.id" :data="item.children" :props="defaultProps" show-checkbox
+						default-expand-all node-key="id" :default-checked-keys="checkKeys">
 					</el-tree>
 				</div>
 			</el-collapse-item>
@@ -23,6 +24,7 @@
 		roomList
 	} from '@/uitls'
 	export default {
+		props: ['ids'],
 		data() {
 			return {
 				options: [],
@@ -30,6 +32,9 @@
 					children: 'children',
 					label: 'optionName'
 				},
+				checkKeys: [],
+				idsBox: [],
+				request: false
 			}
 		},
 		created() {
@@ -37,13 +42,44 @@
 		},
 		methods: {
 			init() {
+				if (this.request) return;
+				this.request = true;
 				getHouseTree(this.$store.getters.project.id).then(res => {
 					if (res.state) {
 						this.options = roomList(res.data.projectItemList || []);
+						if (this.ids) {
+							this.idsBox = this.ids.split(',');
+							console.log(this.idsBox);
+							this.returnChecked(this.options);
+						}
 					}
+					this.request = false;
 				})
+			},
+			returnHouseId() {
+				let data = [];
+				for (let i = 0; i < this.options.length; i++) {
+					data = data.concat(this.$refs['houseTree' + this.options[i].id][0].getCheckedNodes(true).filter(node =>
+						node.roomId).map(node => node.roomId));
+				}
+				return data;
+			},
+			returnChecked(data) {
+				for (let i = 0; i < data.length; i++) {
+					if (data[i]['roomId']) {
+						if (this.idsBox.filter(node => node == data[i]['roomId']).length > 0) {
+							this.checkKeys.push(data[i].id);
+						}
+					}
+					if (data[i].children) this.returnChecked(data[i].children);
+				}
 			}
-		}
+		},
+		watch: {
+			ids() {
+				if (this.ids && this.options.length === 0) this.init();
+			}
+		},
 	}
 </script>
 

+ 54 - 0
virgo.wzfrontend/console/src/components/common/uploadFile.vue

@@ -0,0 +1,54 @@
+<template>
+	<div class="document-upload">
+		<el-upload :action="action" name="uploadFile" ref="upload" :headers="headers" :on-success="successFile"
+			:before-upload="beforeUpload" :on-error="errorUpload" :show-file-list="false" :on-progress="progress">
+			<div class="bim-update-button">
+				<i class="el-icon-plus"></i>
+			</div>
+		</el-upload>
+	</div>
+</template>
+
+<script>
+	import config from '@/config';
+	import {
+		getToken
+	} from '@/uitls/auth';
+	export default {
+		data() {
+			return {
+				action: config.baseURL + '/file/filenode/-1',
+				headers: {}
+			};
+		},
+		created() {
+			this.headers.token = getToken();
+		},
+		methods: {
+			beforeUpload() {
+				this.$loading();
+			},
+			progress(e) {
+				let percent = e.percent >= 100 ? 99 : parseInt(e.percent)
+				this.$loading({
+					percent: (percent + '%')
+				});
+			},
+			reloadUpload() {
+				this.$refs['upload'].$children[0].$refs.input.click();
+			},
+			errorUpload() {
+				this.$loading.close();
+				this.$message.error('上传失败');
+			},
+			successFile(data) {
+				this.$emit('changeFile', data.data)
+				this.$loading.close();
+			},
+		}
+	};
+</script>
+
+<style lang="scss">
+	.document-upload {}
+</style>

+ 24 - 4
virgo.wzfrontend/console/src/components/work/contract/common/clause.vue

@@ -1,5 +1,5 @@
 <template>
-	<div class="clause-box">
+	<div class="clause-box">
 		<slot></slot>
 		<div class="clause-box-form" v-if="type === 1">
 			<el-form ref="form" :model="form" label-position="top">
@@ -141,7 +141,7 @@
 
 <script>
 	export default {
-		props: ['type'],
+		props: ['type', 'formData'],
 		data() {
 			return {
 				form: {
@@ -155,7 +155,7 @@
 					unnaturalMonthChargingWay: '1', //非自然月计费方式
 					yearDays: '', //年天数
 					payCycle: '', //付款周期
-					leaseTermWay: '', //租期划分方式
+					leaseTermWay: '1', //租期划分方式
 					earnestMoneyType: '1', //保证金类型
 					earnestMoney: '', //保证金金额
 					currencyType: '1', //币种
@@ -169,7 +169,27 @@
 					preferentialRentFreeWay: '1' //免租期划分方式
 				}
 			}
-		}
+		},
+		created() {
+			this.form['type'] = this.type;
+			if (this.formData) this.form = this.formData;
+		},
+		methods: {
+			validateForm(resolve, reject) {
+				this.$refs.form.validate((valid) => {
+					if (valid) {
+						resolve(this.form);
+					} else {
+						return false;
+					}
+				});
+			}
+		},
+		watch: {
+			formData() {
+				if (this.formData) this.form = this.formData;
+			}
+		},
 	}
 </script>
 

+ 1 - 1
virgo.wzfrontend/console/src/components/work/contract/common/documentUpload.vue

@@ -1,6 +1,6 @@
 <template>
 	<div class="document-upload">
-		<el-upload :action="action" name="uploadFile" ref="upload" :headers="headers" accept=".xlsx"
+		<el-upload :action="action" name="uploadFile" ref="upload" :headers="headers" accept=".xlsx,.docx"
 			:on-success="successFile" :before-upload="beforeUpload" :on-error="errorUpload" :show-file-list="false"
 			:on-progress="progress">
 			<div class="bim-update-button">

+ 178 - 36
virgo.wzfrontend/console/src/components/work/contract/common/selectTemplate.vue

@@ -1,48 +1,95 @@
 <template>
 	<div class="hui-flex select-template">
-		<div class="hui-content-insert">
-			<el-button type="primary" size="medium" @click="selectTemplate">
-				选择合同模板
-			</el-button>
-		</div>
-		<div class="select-template-box">
-			<el-table :data="templateData" row-key="id" border height="100%">
-				<el-table-column label="序号" width="50">
-					<template slot-scope="scope">
-						<div style="text-align: center;">{{scope.$index + 1}}</div>
+		<div class="select-template-content">
+			<div class="hui-content-insert">
+				<el-button type="primary" size="medium" @click="selectTemplate">
+					选择合同模板
+				</el-button>
+			</div>
+			<div class="select-template-box">
+				<el-table :data="templateData" row-key="id" border height="100%">
+					<el-table-column label="序号" width="50">
+						<template slot-scope="scope">
+							<div style="text-align: center;">{{scope.$index + 1}}</div>
+						</template>
+					</el-table-column>
+					<el-table-column label="合同名称" prop="name"></el-table-column>
+					<el-table-column label="操作" width="240">
+						<template slot-scope="scope">
+							<div class="hui-table-operation">
+								<span class="table-operation" @click="preview(scope.row)">
+									预览
+								</span>
+								<span class="table-operation" @click="deleteItem(scope.row)">
+									删除
+								</span>
+							</div>
+						</template>
+					</el-table-column>
+					<template slot="empty">
+						<empty description="暂无数据" width="80"></empty>
 					</template>
-				</el-table-column>
-				<el-table-column label="合同名称" prop="name"></el-table-column>
-				<el-table-column label="操作" width="240">
-					<template slot-scope="scope">
-						<div class="hui-table-operation">
-							<span class="table-operation" @click="preview(scope.row)">
-								预览
-							</span>
-							<span class="table-operation" @click="deleteItem(scope.row)">
-								删除
-							</span>
-						</div>
+				</el-table>
+			</div>
+		</div>
+		<div class="line-select-template"></div>
+		<div class="select-template-content">
+			<div class="hui-content-insert">
+				<el-button type="primary" size="medium" @click="uploadFile">
+					上传合同附件
+				</el-button>
+				<upload-file ref="upload" v-show="false" @changeFile="changeFile"></upload-file>
+			</div>
+			<div class="select-template-box">
+				<el-table :data="fileList" row-key="id" border height="100%">
+					<el-table-column label="序号" width="50">
+						<template slot-scope="scope">
+							<div style="text-align: center;">{{scope.$index + 1}}</div>
+						</template>
+					</el-table-column>
+					<el-table-column label="附件名称" prop="name"></el-table-column>
+					<el-table-column label="操作" width="240">
+						<template slot-scope="scope">
+							<div class="hui-table-operation">
+								<span class="table-operation" @click="deleteFile(scope.row)">
+									删除
+								</span>
+							</div>
+						</template>
+					</el-table-column>
+					<template slot="empty">
+						<empty description="暂无数据" width="80"></empty>
 					</template>
-				</el-table-column>
-				<template slot="empty">
-					<empty description="暂无数据"></empty>
-				</template>
-			</el-table>
+				</el-table>
+			</div>
 		</div>
 		<el-dialog title="预览" :visible.sync="detailsDialogVisible" width="80%" class="document-dialog"
 			:append-to-body="true">
 			<preview v-if="detailsDialogVisible" :templateId="templateId" @close="detailsDialogVisible = false">
 			</preview>
 		</el-dialog>
-		<el-dialog title="选择合同模板" :visible.sync="visible" width="900px" :append-to-body="true">
+		<el-dialog title="选择合同模板" custom-class="select-template-dialog" :visible.sync="visible" width="500px"
+			:append-to-body="true">
 			<div class="hui-flex hui-dialog">
 				<div class="hui-flex-box hui-dialog-content">
-
+					<el-form ref="form" :model="form" label-position="top">
+						<el-form-item label="合同模板类型">
+							<el-cascader ref="cascader" v-model="form.selectValue" :options="templateTypeList"
+								:props="props" collapse-tags clearable @change="change" placeholder="请选择合同模板类型">
+							</el-cascader>
+						</el-form-item>
+						<el-form-item label="合同模板">
+							<el-select v-model="form.templateId" placeholder="请选择合同模板">
+								<el-option :label="item.name" :value="item.id" v-for="(item,index) in templateList"
+									:key="index">
+								</el-option>
+							</el-select>
+						</el-form-item>
+					</el-form>
 				</div>
 				<div class="hui-dialog-submit">
 					<el-button size="medium" @click="visible = false">取 消</el-button>
-					<el-button size="medium" type="primary" @click="submit">保 存</el-button>
+					<el-button size="medium" type="primary" @click="submit">创 建</el-button>
 				</div>
 			</div>
 		</el-dialog>
@@ -51,23 +98,56 @@
 
 <script>
 	import preview from '@/components/document/preview'
+	import uploadFile from '@/components/common/uploadFile'
 	import {
 		getContractTemplateList,
+		getTagList
 	} from '@/httpApi/contract'
 	export default {
+		props: ['documentFileList'],
 		data() {
 			return {
 				templateData: [],
 				detailsDialogVisible: false,
 				templateId: '',
 				visible: false,
-				tableData: []
+				tableData: [],
+				form: {
+					selectValue: [],
+					templateId: ''
+				},
+				templateTypeList: [],
+				templateList: [],
+				props: {
+					label: 'name',
+					value: 'id',
+					checkStrictly: true
+				},
+				fileList: []
 			}
 		},
+		created() {
+			this.templateData = this.documentFileList.document;
+			this.fileList = this.documentFileList.attachment;
+		},
 		methods: {
 			selectTemplate() {
 				this.visible = true;
-				// getContractTemplateList()
+				getTagList(this.$store.getters.organization.id, this.$store.getters.project.id).then(res => {
+					if (res.state) {
+						this.templateTypeList = res.data;
+						this.returnPartList(this.templateTypeList);
+					}
+				})
+			},
+			returnPartList(data) {
+				for (var i = 0; i < data.length; i++) {
+					if (data[i].children.length > 0) {
+						this.returnPartList(data[i].children)
+					} else {
+						data[i].children = null;
+					}
+				}
 			},
 			deleteItem(item) {
 				this.$confirm('确定要移除该模板文件?', () => {
@@ -79,20 +159,82 @@
 				this.templateId = item.id;
 				this.detailsDialogVisible = true;
 			},
+			change() {
+				this.form.templateId = '';
+				let data = this.$refs.cascader.getCheckedNodes(true)[0].data;
+				getContractTemplateList({
+					categoryId: data.id,
+					currPage: 1,
+					pageSize: 100
+				}).then(res => {
+					if (res.state) {
+						this.templateList = res.data.dataList;
+					}
+				})
+			},
+			deleteFile(item) {
+				this.$confirm('确定要移除该文件?', () => {
+					let index = this.fileList.findIndex(node => node.id === item.id);
+					this.fileList.splice(index, 1);
+				});
+			},
+			uploadFile() {
+				this.$refs.upload.reloadUpload();
+			},
+			changeFile(data) {
+				this.fileList.push(data);
+			},
 			submit() {
-
+				if (this.templateData.filter(node => node.id == this.form.templateId).length > 0) return this.$message
+					.warning('该模板已存在');
+				let data = this.templateList.filter(node => node.id == this.form.templateId)[0];
+				if (!data) return;
+				this.templateData.push(data);
+				this.visible = false;
+				this.form = {
+					selectValue: [],
+					templateId: ''
+				}
+			},
+			returnData() {
+				return {
+					document: JSON.stringify(this.templateData),
+					attachment: JSON.stringify(this.fileList)
+				}
+			}
+		},
+		watch: {
+			documentFileList() {
+				this.templateData = this.documentFileList.document;
+				this.fileList = this.documentFileList.attachment;
 			}
 		},
 		components: {
-			preview
+			preview,
+			uploadFile
 		},
 	}
 </script>
 
 <style lang="scss">
+	.el-dialog.select-template-dialog {
+		height: 260px !important;
+		margin-top: 20vh !important;
+	}
+
 	.select-template {
-		background: $--box-background;
-		padding: 10px;
+		.select-template-content {
+			flex: 1;
+			height: 0;
+			display: flex;
+			flex-direction: column;
+			background: $--box-background;
+			padding: 10px;
+		}
+
+		.line-select-template {
+			height: 10px;
+		}
 
 		.select-template-box {
 			flex: 1;

+ 157 - 30
virgo.wzfrontend/console/src/components/work/contract/list/edit.vue

@@ -12,7 +12,7 @@
 				<div class="contract-box">
 					<div class="hui-chart-title">所属公司信息</div>
 					<div class="contract-from">
-						<el-form-item label="所属公司">
+						<el-form-item label="所属公司" prop="organizationId" :rules="[{required: true, message: '所属公司'}]">
 							<el-input v-model="organization.name" disabled></el-input>
 						</el-form-item>
 						<el-form-item label="所属部门">
@@ -21,14 +21,15 @@
 							</el-cascader>
 						</el-form-item>
 						<el-form-item label="招商跟进人">
-							<el-select v-model="form.investmentPromotion" placeholder="请选择招商跟进人">
+							<el-select v-model="form.investmentPromotion" placeholder="请选择招商跟进人"
+								@change="changeInvestmentPromotion">
 								<el-option :label="item.name" :value="item.id" v-for="(item,index) in partUserList"
 									:key="index">
 								</el-option>
 							</el-select>
 						</el-form-item>
-						<el-form-item label="运营跟进人">
-							<el-select v-model="form.operator" placeholder="请选择运营跟进人">
+						<el-form-item label="运营跟进人" prop="operator" :rules="[{required: true, message: '请选择运营跟进人'}]">
+							<el-select v-model="form.operator" placeholder="请选择运营跟进人" @change="changeOperator">
 								<el-option :label="item.name" :value="item.id" v-for="(item,index) in partUserList"
 									:key="index">
 								</el-option>
@@ -40,26 +41,28 @@
 					<div class="hui-chart-title">租客信息</div>
 					<div class="contract-from">
 						<el-form-item label="租客类型">
-							<el-select v-model="form.renterType" placeholder="请选择租客类型">
+							<el-select v-model="form.tenantType" placeholder="请选择租客类型">
 								<el-option label="企业" :value="1"></el-option>
 								<el-option label="客户" :value="2"></el-option>
 							</el-select>
 						</el-form-item>
-						<el-form-item label="企业" v-if="form.renterType === 1">
+						<el-form-item label="企业" v-if="form.tenantType === 1" prop="merchantId"
+							:rules="[{required: true, message: '请选择企业'}]">
 							<el-select v-model="form.merchantId" placeholder="请选择企业" @change="changeMerchant">
 								<el-option :label="item.name" :value="item.id" v-for="(item,index) in merchantList"
 									:key="index">
 								</el-option>
 							</el-select>
 						</el-form-item>
-						<el-form-item label="客户" v-else-if="form.renterType === 2">
-							<el-select v-model="form.clientId" placeholder="请选择客户">
+						<el-form-item label="客户" v-else-if="form.tenantType === 2" prop="clientId"
+							:rules="[{required: true, message: '请选择客户'}]">
+							<el-select v-model="form.clientId" placeholder="请选择客户" @change="changeClinet">
 								<el-option :label="item.name" :value="item.id" v-for="(item,index) in clientList"
 									:key="index">
 								</el-option>
 							</el-select>
 						</el-form-item>
-						<el-form-item label="法人" v-if="form.renterType === 1">
+						<el-form-item label="法人" v-if="form.tenantType === 1">
 							<el-input v-model="form.corporation" disabled></el-input>
 						</el-form-item>
 						<el-form-item label="行业">
@@ -110,8 +113,7 @@
 				<div class="contract-box">
 					<div class="hui-chart-title">合同标签</div>
 					<div class="contract-from" style="padding-bottom: 20px;">
-						<tag ref="tag" type="insert" :tagType="4"
-							:tagActive="form.tagIds ? form.tagIds.split(',') : []">
+						<tag ref="tag" type="insert" :tagType="4" :tagActive="tagIds">
 						</tag>
 					</div>
 				</div>
@@ -128,7 +130,8 @@
 						<svg-icon name="zhuangshi" width="16" height="20"></svg-icon>
 						<span class="hui-left-tree-sub">房源列表</span>
 					</div>
-					<project-item-tree-select></project-item-tree-select>
+					<project-item-tree-select ref="houseItem" :ids="form.projectItemTargetRoomIds">
+					</project-item-tree-select>
 				</div>
 			</div>
 		</el-form>
@@ -142,7 +145,8 @@
 					</div>
 					<div class="contract-from">
 						<clause :ref="'clause' + item.id " :type="item.type"
-							v-for="(item,index) in clauseData.filter(node => node.type === clause.id)" :key="item.id">
+							v-for="(item,index) in clauseData.filter(node => node.type === clause.id)" :key="item.id"
+							:formData="item.form">
 							<i class="el-icon-close" v-if="item.isDelete" @click="deleteClause(item.id)"></i>
 						</clause>
 					</div>
@@ -150,10 +154,10 @@
 			</div>
 		</div>
 		<div class="hui-flex-box" v-show="stepId === 3">
-			<select-template></select-template>
+			<select-template ref="selectTemplate" :documentFileList="documentFileList"></select-template>
 		</div>
 		<div class="contract-btn">
-			<el-button size="medium" @click="lastSubmit">上一步</el-button>
+			<el-button size="medium" @click="lastSubmit" v-if="stepId > 1">上一步</el-button>
 			<el-button type="primary" size="medium" @click="submit">{{stepId === 3 ? '保存' : '下一步'}}</el-button>
 		</div>
 	</div>
@@ -170,11 +174,21 @@
 	import {
 		getCustomerListByPage
 	} from '@/httpApi/crm'
+	import {
+		insertContract,
+		getContractDetailById,
+		updateContract,
+		updateContractAll
+	} from '@/httpApi/contract'
 	import tag from '@/components/common/tag'
 	import customData from '@/components/common/customData'
 	import clause from '@/components/work/contract/common/clause'
 	import selectTemplate from '@/components/work/contract/common/selectTemplate'
+	import {
+		findParentIds
+	} from '@/uitls'
 	export default {
+		props: ['detailId'],
 		data() {
 			return {
 				stepList: [{
@@ -202,13 +216,18 @@
 				customList: [],
 				form: {
 					organizationId: '',
+					organizationName: '',
 					roleId: '',
 					roleName: '',
 					investmentPromotion: '',
+					investmentPromotionName: '',
 					operator: '',
-					renterType: 1,
+					operatorName: '',
+					tenantType: 1,
 					merchantId: '',
+					merchantName: '',
 					clientId: '',
+					clientName: '',
 					tenant: '', //租客
 					industry: '',
 					corporation: '',
@@ -219,9 +238,10 @@
 					endDate: '',
 					lateFeesStartingDays: '',
 					lateFeesProportion: '',
-					tagIds: '',
-					type: ''
+					lateFeesCeiling: '',
+					projectItemTargetRoomIds: ''
 				},
+				tagIds: [],
 				clauseList: [{
 					id: 1,
 					name: '租期条款'
@@ -244,22 +264,68 @@
 					type: 2,
 					isDelete: false
 				}],
-				clauseIndex: 3
+				clauseIndex: 3,
+				clauseDataBox: [],
+				houseIds: [],
+				documentFileList: {
+					document: [],
+					attachment: []
+				},
+				formData: {}
 			}
 		},
 		created() {
 			this.organization = this.$store.getters.organization;
 			this.form['organizationId'] = this.organization.id;
-			this.partList();
+			this.form['organizationName'] = this.organization.name;
 			this.merchant();
 			this.client();
+			if (this.detailId) {
+				getContractDetailById(this.detailId).then(res => {
+					if (res.state) {
+						let data = res.data;
+						this.formData = data;
+						for (let key in this.form) {
+							this.form[key] = data[key];
+						}
+						this.tagIds = data.tagList.map(node => node.id);
+						if (data.data) this.customList = JSON.parse(data.data);
+						this.clauseData = data.clauseList.map((node, index) => {
+							let obj = {
+								id: index + 1,
+								type: node.type,
+								form: node
+							}
+							if (index < 2) {
+								node['isDelete'] = false;
+							} else {
+								node['isDelete'] = true;
+							}
+							return obj;
+						})
+						this.partList();
+						this.documentFileList = {
+							document: data.document ? JSON.parse(data.document) : [],
+							attachment: data.attachment ? JSON.parse(data.attachment) : []
+						}
+					}
+				})
+			} else {
+				this.partList();
+			}
 		},
 		methods: {
 			partList() {
 				getPartList(this.organization.id, this.$store.getters.project.id).then(res => {
 					if (res.state) {
 						this.partData = res.data;
-						this.returnPartList(this.partData);
+
+						if (this.form.roleId) {
+							this.returnPartList(this.partData, this.form.roleId);
+							this.partValue = findParentIds(this.partData, this.form.roleId);
+						} else {
+							this.returnPartList(this.partData);
+						}
 					}
 				})
 			},
@@ -276,6 +342,19 @@
 			changeMerchant() {
 				let data = this.merchantList.find(node => node.id == this.form.merchantId);
 				this.form.corporation = data.legalPerson;
+				this.form.merchantName = data.name;
+			},
+			changeClinet() {
+				let data = this.clientList.find(node => node.id == this.form.merchantId);
+				this.form.clientName = data.name;
+			},
+			changeInvestmentPromotion() {
+				let data = this.partUserList.find(node => node.id == this.form.investmentPromotion);
+				this.form.investmentPromotionName = data.name;
+			},
+			changeOperator() {
+				let data = this.partUserList.find(node => node.id == this.form.operator);
+				this.form.operatorName = data.name;
 			},
 			client() {
 				getCustomerListByPage({
@@ -289,28 +368,76 @@
 					}
 				})
 			},
-			returnPartList(data) {
+			returnPartList(data, id) {
 				for (var i = 0; i < data.length; i++) {
+					if (id === data[i].id) this.partUserList = data[i].users || [];
 					if (data[i].children.length > 0) {
-						this.returnPartList(data[i].children)
+						this.returnPartList(data[i].children, id)
 					} else {
 						data[i].children = null;
 					}
 				}
 			},
-			changePart(val) {
+			changePart() {
 				this.form.investmentPromotion = '';
 				this.form.operator = '';
-				this.partUserList = this.$refs.partCascader.getCheckedNodes(true)[0].data.users || [];
+				let data = this.$refs.partCascader.getCheckedNodes(true)[0].data;
+				this.partUserList = data.users || [];
+				this.form.roleId = data.id;
+				this.form.roleName = data.name;
 			},
 			lastSubmit() {
-				if (this.stepId > 0) return this.stepId--;
+				if (this.stepId === 1) return this.$emit('callback');
+				this.stepId--;
 			},
 			submit() {
-				if (this.stepId < 3) return this.stepId++;
-				// let post = {}
-				// postData['data'] = JSON.stringify(this.$refs.customData.listData);
-				// postData['tagIds'] = this.$refs.tag.tagIds();
+				if (this.stepId === 1) {
+					this.$refs.form.validate((valid) => {
+						if (valid) {
+							this.houseIds = this.$refs.houseItem.returnHouseId();
+							if (this.houseIds.length === 0) return this.$message.warning('请至少选择一个房源');
+							this.stepId++;
+						} else {
+							return false;
+						}
+					});
+				} else if (this.stepId === 2) {
+					let promise = [];
+					for (let i = 0; i < this.clauseData.length; i++) {
+						promise.push(new Promise((resolve, reject) => {
+							this.$refs['clause' + this.clauseData[i].id][0].validateForm(resolve)
+						}))
+					}
+					Promise.all(promise).then(res => {
+						this.clauseDataBox = res;
+						this.stepId++;
+					})
+				} else if (this.stepId === 3) {
+					let selectTemplate = this.$refs.selectTemplate.returnData();
+					let postData = JSON.parse(JSON.stringify(this.form));
+					postData['data'] = JSON.stringify(this.$refs.customData.listData);
+					if (this.$refs.tag.tagIds()) postData['tagIds'] = this.$refs.tag.tagIds();
+					postData['clauseList'] = this.clauseDataBox;
+					postData['attachment'] = selectTemplate.attachment;
+					postData['document'] = selectTemplate.document;
+					postData['projectItemTargetRoomIds'] = this.houseIds.join(',');
+					if (this.detailId) {
+						postData['id'] = this.formData.id;
+						updateContractAll(postData).then(res => {
+							if (res.state) {
+								this.$message.success('操作成功');
+								this.$emit('callback', 'init');
+							}
+						})
+					} else {
+						insertContract(postData).then(res => {
+							if (res.state) {
+								this.$message.success('操作成功');
+								this.$emit('callback', 'init');
+							}
+						})
+					}
+				}
 			},
 			insertClause(type) {
 				this.clauseData.push({

+ 70 - 0
virgo.wzfrontend/console/src/httpApi/contract.js

@@ -160,4 +160,74 @@ export function deleteField(id) {
 		url: `/file/template/data/delete/${id}`,
 		method: 'delete'
 	})
+}
+/* 
+ * 新增合同
+ * 
+ * 
+ */
+export function insertContract(data) {
+	return request({
+		url: `/api/contract`,
+		method: 'post',
+		data: data
+	})
+}
+/* 
+ * 分页获取合同
+ * 
+ * 
+ */
+export function getContractListByPage(data) {
+	return request({
+		url: `/api/contract/${data.currPage}/${data.pageSize}`,
+		method: 'post',
+		data: data
+	})
+}
+/* 
+ * 获取合同详情
+ * 
+ * 
+ */
+export function getContractDetailById(id) {
+	return request({
+		url: `/api/contract/${id}`,
+		method: 'get'
+	})
+}
+/* 
+ * 更新模板
+ * 
+ * 
+ */
+export function updateContract(data) {
+	return request({
+		url: `/api/contract/update`,
+		method: 'put',
+		data: data
+	})
+}
+/* 
+ * 更新模板
+ * 
+ * 
+ */
+export function updateContractAll(data) {
+	return request({
+		url: `/api/contract/updateAll`,
+		method: 'put',
+		data: data
+	})
+}
+/* 
+ * 删除合同
+ * 
+ * 
+ */
+export function deleteContractById(id) {
+	return request({
+		url: `/api/contract/delete/${id}`,
+		method: 'delete'
+	})
 }

+ 6 - 0
virgo.wzfrontend/console/src/views/system/log.vue

@@ -21,6 +21,12 @@
 					<div class="log-item">2、新增合同-基本信息、费用条款的数据逻辑部分以及合同文本部分逻辑。</div>
 				</div>
 			</el-timeline-item>
+			<el-timeline-item timestamp="2024-06-07" placement="top">
+				<div class="log-box">
+					<div class="log-item">1、新增获取合同列表、创建合同、编辑合同的功能。</div>
+					<div class="log-item">2、新增合同服务条款的功能。</div>
+				</div>
+			</el-timeline-item>
 		</el-timeline>
 	</div>
 </template>

+ 78 - 9
virgo.wzfrontend/console/src/views/work/contract/list.vue

@@ -15,7 +15,31 @@
 								<div style="text-align: center;">{{scope.$index + 1}}</div>
 							</template>
 						</el-table-column>
-						<el-table-column label="合同名称" prop="name"></el-table-column>
+						<el-table-column label="合同编号" prop="code"></el-table-column>
+						<el-table-column label="租客" prop="name">
+							<template slot-scope="scope">
+								{{scope.row.tenantType === 1 ? scope.row.merchantName: scope.row.clientName}}
+							</template>
+						</el-table-column>
+						<el-table-column label="房号" prop="projectItemTargetRoomIds"></el-table-column>
+						<el-table-column label="开始日" prop="startDate"></el-table-column>
+						<el-table-column label="结束日" prop="endDate"></el-table-column>
+						<el-table-column label="运营跟进人" prop="operatorName"></el-table-column>
+						<el-table-column label="操作" width="150">
+							<template slot-scope="scope">
+								<div class="hui-table-operation">
+									<span class="table-operation" @click="detailItem(scope.row)">
+										详情
+									</span>
+									<span class="table-operation" @click="updateItem(scope.row)">
+										编辑
+									</span>
+									<span class="table-operation" @click="deleteItem(scope.row)">
+										删除
+									</span>
+								</div>
+							</template>
+						</el-table-column>
 						<template slot="empty">
 							<empty description="暂无数据"></empty>
 						</template>
@@ -32,31 +56,76 @@
 			<div class="hui-nav">
 				<el-page-header @back="type = 'list'" content="新建合同"></el-page-header>
 			</div>
-			<edit class="hui-flex-box"></edit>
+			<edit class="hui-flex-box" @callback="callback" :detailId="detailId"></edit>
 		</div>
 	</div>
 </template>
 
 <script>
 	import edit from '@/components/work/contract/list/edit'
+	import {
+		getContractListByPage,
+		deleteContractById
+	} from '@/httpApi/contract'
 	export default {
 		data() {
 			return {
 				type: 'list',
-				tableData: [],
-				currPage: 1,
-				pageSize: 10,
+				tableData: [],
+				currPage: 1,
+				pageSize: 10,
 				totalCount: 0,
+				detailId: ''
 			}
 		},
+		created() {
+			this.init();
+		},
 		methods: {
+			init() {
+				getContractListByPage({
+					currPage: this.currPage,
+					pageSize: this.pageSize,
+					organizationId: this.$store.getters.organization.id
+				}).then(res => {
+					if (res.state) {
+						this.tableData = res.data.dataList;
+						this.totalCount = res.data.totalCount;
+					}
+				})
+			},
 			insert() {
+				this.detailId = '';
 				this.type = 'edit';
-			},
-			currentChange(currPage) {
-				this.currPage = currPage;
-				this.init();
 			},
+			currentChange(currPage) {
+				this.currPage = currPage;
+				this.init();
+			},
+			detailItem() {
+				this.$message.warning('功能开发中~~~')
+			},
+			updateItem(item) {
+				this.detailId = item.id;
+				this.type = 'edit';
+			},
+			deleteItem(item) {
+				this.$confirm('确定要删除该合同文件?', () => {
+					deleteContractById(item.id).then(res => {
+						if (res.state) {
+							this.$message({
+								type: 'success',
+								message: '操作成功'
+							})
+							this.init();
+						}
+					})
+				});
+			},
+			callback(type) {
+				if (type === 'init') this.init();
+				this.type = 'list';
+			}
 		},
 		components: {
 			edit

Diff do ficheiro suprimidas por serem muito extensas
+ 1 - 1
virgo.wzfrontend/src/main/resources/static/index.html


+ 1 - 0
virgo.wzfrontend/src/main/resources/static/reset.css

@@ -7,6 +7,7 @@
 	font-family: LarkHackSafariFont, LarkEmojiFont, LarkChineseQuote, -apple-system, BlinkMacSystemFont, Helvetica Neue, Tahoma, PingFang SC, Microsoft Yahei, Arial, Hiragino Sans GB, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji;
 	font-weight: 400;
 	-webkit-font-smoothing: antialiased;
+	user-select: none;
 }
 
 html {

Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 1
virgo.wzfrontend/src/main/resources/static/static/css/192.968c8c10.css


Diff do ficheiro suprimidas por serem muito extensas
+ 1 - 0
virgo.wzfrontend/src/main/resources/static/static/css/337.34ca17c0.css


Diff do ficheiro suprimidas por serem muito extensas
+ 1 - 0
virgo.wzfrontend/src/main/resources/static/static/css/346.34ca17c0.css


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 1
virgo.wzfrontend/src/main/resources/static/static/css/37.968c8c10.css


virgo.wzfrontend/src/main/resources/static/static/css/568.f43f4c00.css → virgo.wzfrontend/src/main/resources/static/static/css/609.f43f4c00.css


virgo.wzfrontend/src/main/resources/static/static/css/913.f43f4c00.css → virgo.wzfrontend/src/main/resources/static/static/css/636.f43f4c00.css


Diff do ficheiro suprimidas por serem muito extensas
+ 1 - 1
virgo.wzfrontend/src/main/resources/static/static/js/153-legacy.7056c136.js


Diff do ficheiro suprimidas por serem muito extensas
+ 1 - 1
virgo.wzfrontend/src/main/resources/static/static/js/17-legacy.b642adc7.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 1
virgo.wzfrontend/src/main/resources/static/static/js/192-legacy.3c51e556.js


Diff do ficheiro suprimidas por serem muito extensas
+ 1 - 0
virgo.wzfrontend/src/main/resources/static/static/js/337-legacy.f75ba3ba.js


Diff do ficheiro suprimidas por serem muito extensas
+ 1 - 0
virgo.wzfrontend/src/main/resources/static/static/js/346.8ba9dd49.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 1
virgo.wzfrontend/src/main/resources/static/static/js/37.c044cfb5.js


Diff do ficheiro suprimidas por serem muito extensas
+ 1 - 0
virgo.wzfrontend/src/main/resources/static/static/js/39.6ad7ff94.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 1
virgo.wzfrontend/src/main/resources/static/static/js/39.d1e82fe0.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 1
virgo.wzfrontend/src/main/resources/static/static/js/529-legacy.05dc6088.js


Diff do ficheiro suprimidas por serem muito extensas
+ 1 - 0
virgo.wzfrontend/src/main/resources/static/static/js/529-legacy.32bbec41.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 1
virgo.wzfrontend/src/main/resources/static/static/js/568.0468dea8.js


Diff do ficheiro suprimidas por serem muito extensas
+ 1 - 0
virgo.wzfrontend/src/main/resources/static/static/js/609.0ba8181f.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 1
virgo.wzfrontend/src/main/resources/static/static/js/61-legacy.cefaf697.js


Diff do ficheiro suprimidas por serem muito extensas
+ 1 - 0
virgo.wzfrontend/src/main/resources/static/static/js/61-legacy.fcfc9dbc.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 1
virgo.wzfrontend/src/main/resources/static/static/js/61.bcb04045.js


Diff do ficheiro suprimidas por serem muito extensas
+ 1 - 0
virgo.wzfrontend/src/main/resources/static/static/js/61.fcfc9dbc.js


Diff do ficheiro suprimidas por serem muito extensas
+ 1 - 0
virgo.wzfrontend/src/main/resources/static/static/js/636-legacy.36487c56.js


Diff do ficheiro suprimidas por serem muito extensas
+ 1 - 1
virgo.wzfrontend/src/main/resources/static/static/js/689.c1cbfd5b.js


virgo.wzfrontend/src/main/resources/static/static/js/842.8ded1f15.js → virgo.wzfrontend/src/main/resources/static/static/js/842.6b6de035.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 1
virgo.wzfrontend/src/main/resources/static/static/js/913-legacy.60bb7049.js


Diff do ficheiro suprimidas por serem muito extensas
+ 1 - 0
virgo.wzfrontend/src/main/resources/static/static/js/app-legacy.4901e24c.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 1
virgo.wzfrontend/src/main/resources/static/static/js/app-legacy.9a379b0a.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 1
virgo.wzfrontend/src/main/resources/static/static/js/app.a7c96cb4.js


Diff do ficheiro suprimidas por serem muito extensas
+ 1 - 0
virgo.wzfrontend/src/main/resources/static/static/js/app.e01852aa.js