Quellcode durchsuchen

进销存管理-代码提交

huangguoce vor 5 Tagen
Ursprung
Commit
fc83c9c2ef
51 geänderte Dateien mit 18108 neuen und 76 gelöschten Zeilen
  1. 2 0
      src/api/AppPath.js
  2. 118 0
      src/api/psi/CollectService.js
  3. 40 0
      src/api/psi/ContractService.js
  4. 52 0
      src/api/psi/FoodPurchaseService.js
  5. 53 0
      src/api/psi/LossService.js
  6. 55 0
      src/api/psi/MaterialManagementService.js
  7. 47 0
      src/api/psi/MaterialTypeService.js
  8. 40 0
      src/api/psi/SupplierService.js
  9. 191 0
      src/api/psi/WareHouseService.js
  10. 64 74
      src/views/dashboard/widgets/components/MyNoticePageList.vue
  11. 17 2
      src/views/flowable/task/TaskForm.vue
  12. 1053 0
      src/views/psiManagement/collect/CollectForm.vue
  13. 680 0
      src/views/psiManagement/collect/CollectList.vue
  14. 903 0
      src/views/psiManagement/collect/CollectReturnForm.vue
  15. 851 0
      src/views/psiManagement/collect/CollectReturnHiForm.vue
  16. 149 0
      src/views/psiManagement/collect/PurchasePageForm.vue
  17. 122 0
      src/views/psiManagement/collect/PurchasePageFormByOption.vue
  18. 621 0
      src/views/psiManagement/collect/UpdateCollectInfoForm.vue
  19. 138 0
      src/views/psiManagement/contract/ContractChooseForm.vue
  20. 632 0
      src/views/psiManagement/contract/ContractForm.vue
  21. 369 0
      src/views/psiManagement/contract/ContractList.vue
  22. 515 0
      src/views/psiManagement/contract/UpdateContractInfoForm.vue
  23. 91 0
      src/views/psiManagement/file/MaterialManagementDialog.vue
  24. 674 0
      src/views/psiManagement/file/MaterialManagementV2.vue
  25. 758 0
      src/views/psiManagement/foodPurchase/FoodPurchaseForm.vue
  26. 657 0
      src/views/psiManagement/foodPurchase/FoodPurchaseList.vue
  27. 76 0
      src/views/psiManagement/foodPurchase/UpdateFoodPurchaseForm.vue
  28. 119 0
      src/views/psiManagement/info/MaterialTypePullForm.vue
  29. 88 0
      src/views/psiManagement/info/MaterialTypePullFormByOption.vue
  30. 724 0
      src/views/psiManagement/info/UpdateInfoForm.vue
  31. 651 0
      src/views/psiManagement/loss/LossForm.vue
  32. 436 0
      src/views/psiManagement/loss/LossList.vue
  33. 151 0
      src/views/psiManagement/loss/PurchasePageForm.vue
  34. 67 0
      src/views/psiManagement/loss/UpdateLossInfoForm.vue
  35. 157 0
      src/views/psiManagement/materialType/TypeForm.vue
  36. 145 0
      src/views/psiManagement/materialType/TypeList.vue
  37. 967 0
      src/views/psiManagement/purchase/PurchaseForm.vue
  38. 507 0
      src/views/psiManagement/purchase/PurchaseList.vue
  39. 127 0
      src/views/psiManagement/purchase/SeeWareHouseList.vue
  40. 132 0
      src/views/psiManagement/supplier/SupplierChooseForm.vue
  41. 470 0
      src/views/psiManagement/supplier/SupplierForm.vue
  42. 190 0
      src/views/psiManagement/supplier/SupplierList.vue
  43. 135 0
      src/views/psiManagement/wareHouse/PurchaseChooseForm.vue
  44. 1044 0
      src/views/psiManagement/wareHouse/WareHouseAddForm.vue
  45. 473 0
      src/views/psiManagement/wareHouse/WareHouseHi.vue
  46. 510 0
      src/views/psiManagement/wareHouse/WareHouseList.vue
  47. 1180 0
      src/views/psiManagement/wareHouse/WareHouseUpdateForm.vue
  48. 100 0
      src/views/psiManagement/wareHouseSummary/EditTradeNameForm.vue
  49. 294 0
      src/views/psiManagement/wareHouseSummary/WareHouseHistory.vue
  50. 160 0
      src/views/psiManagement/wareHouseSummary/WareHouseHistoryPopup.vue
  51. 313 0
      src/views/psiManagement/wareHouseSummary/WareHouseSummaryList.vue

+ 2 - 0
src/api/AppPath.js

@@ -17,3 +17,5 @@ export const REGISTER_PATH = "/human-server";
 export const CCPM_PATH = "/ccpm-server";
 //咨询公司
 export const CONSULTANCY_PATH = "/consultancy-server";
+//进销存系统
+export const PSI_MANAGEMANT = "/psi-management-server";

+ 118 - 0
src/api/psi/CollectService.js

@@ -0,0 +1,118 @@
+import request from "@/utils/httpRequest";
+import { PSI_MANAGEMANT as prefix } from "../AppPath";
+
+export default class CollectService {
+	updateStatusById(param) {
+		return request({
+			url: prefix + "/psi/collect/updateStatusById",
+			method: "post",
+			data: param,
+		});
+	}
+	remove(id) {
+		return request({
+			url: prefix + "/psi/collect/remove",
+			method: "get",
+			params: { id: id },
+		});
+	}
+	save(param) {
+		return request({
+			url: prefix + "/psi/collect/save",
+			method: "post",
+			data: param,
+		});
+	}
+	findById(id) {
+		return request({
+			url: prefix + "/psi/collect/findById",
+			method: "get",
+			params: { id: id },
+		});
+	}
+	list(param) {
+		return request({
+			url: prefix + "/psi/collect/list",
+			method: "get",
+			params: param,
+		});
+	}
+	exportFile(params) {
+		return request({
+			url: prefix + "/psi/collect/exportFile",
+			method: "get",
+			params: params,
+			responseType: "blob",
+		});
+	}
+	wareHouseList(params) {
+		return request({
+			url: prefix + "/psi/collect/wareHouseList",
+			method: "get",
+			params: params,
+		});
+	}
+	createReturnData(param) {
+		return request({
+			url: prefix + "/psi/collect/createReturnData",
+			method: "post",
+			data: param,
+		});
+	}
+	saveReturn(param) {
+		return request({
+			url: prefix + "/psi/collect/saveReturn",
+			method: "post",
+			data: param,
+		});
+	}
+	saveReturnAgree(param) {
+		return request({
+			url: prefix + "/psi/collect/saveReturnAgree",
+			method: "post",
+			data: param,
+		});
+	}
+	updateStatusByIdReturn(param) {
+		return request({
+			url: prefix + "/psi/collect/updateStatusByIdReturn",
+			method: "post",
+			data: param,
+		});
+	}
+	findByReturnId(id) {
+		return request({
+			url: prefix + "/psi/collect/findByReturnId",
+			method: "get",
+			params: { returnId: id },
+		});
+	}
+	returnRequest(param) {
+		return request({
+			url: prefix + "/psi/collect/returnRequest",
+			method: "post",
+			data: param,
+		});
+	}
+	findHiById(id) {
+		return request({
+			url: prefix + "/psi/collect/findHiById",
+			method: "get",
+			params: { collectId: id },
+		});
+	}
+	findHiByHiId(id) {
+		return request({
+			url: prefix + "/psi/collect/findHiByHiId",
+			method: "get",
+			params: { id: id },
+		});
+	}
+	findLastHiByid(id) {
+		return request({
+			url: prefix + "/psi/collect/findLastHiByid",
+			method: "get",
+			params: { collectId: id },
+		});
+	}
+}

+ 40 - 0
src/api/psi/ContractService.js

@@ -0,0 +1,40 @@
+import request from "@/utils/httpRequest";
+import { PSI_MANAGEMANT as prefix } from "../AppPath";
+
+export default class ContractService {
+	save(param) {
+		return request({
+			url: prefix + "/psi/contract/save",
+			method: "post",
+			data: param,
+		});
+	}
+	list(param) {
+		return request({
+			url: prefix + "/psi/contract/list",
+			method: "get",
+			params: param,
+		});
+	}
+	findById(id) {
+		return request({
+			url: prefix + "/psi/contract/findById",
+			method: "get",
+			params: { id: id },
+		});
+	}
+	updateStatusById(param) {
+		return request({
+			url: prefix + "/psi/contract/updateStatusById",
+			method: "post",
+			data: param,
+		});
+	}
+	remove(id) {
+		return request({
+			url: prefix + "/psi/contract/remove",
+			method: "get",
+			params: { id: id },
+		});
+	}
+}

+ 52 - 0
src/api/psi/FoodPurchaseService.js

@@ -0,0 +1,52 @@
+import request from "@/utils/httpRequest";
+import { PSI_MANAGEMANT as prefix } from "../AppPath";
+
+export default class FoodPurchaseService {
+	list(params) {
+		return request({
+			url: prefix + "/psi/foodPurchase/list",
+			method: "get",
+			params,
+		});
+	}
+
+	save(data) {
+		return request({
+			url: prefix + "/psi/foodPurchase/save",
+			method: "post",
+			data,
+		});
+	}
+
+	findById(id) {
+		return request({
+			url: prefix + "/psi/foodPurchase/findById",
+			method: "get",
+			params: { id },
+		});
+	}
+
+	remove(id) {
+		return request({
+			url: prefix + "/psi/foodPurchase/remove",
+			method: "get",
+			params: { id },
+		});
+	}
+
+	updateStatusById(data) {
+		return request({
+			url: prefix + "/psi/foodPurchase/updateStatusById",
+			method: "post",
+			data,
+		});
+	}
+
+	statistics(params) {
+		return request({
+			url: prefix + "/psi/foodPurchase/statistics",
+			method: "get",
+			params,
+		});
+	}
+}

+ 53 - 0
src/api/psi/LossService.js

@@ -0,0 +1,53 @@
+import request from "@/utils/httpRequest";
+import { PSI_MANAGEMANT as prefix } from "../AppPath";
+
+export default class LossService {
+	updateStatusById(data) {
+		return request({
+			url: prefix + "/psi/loss/updateStatusById",
+			method: "post",
+			data,
+		});
+	}
+
+	remove(id) {
+		return request({
+			url: prefix + "/psi/loss/remove",
+			method: "get",
+			params: { id },
+		});
+	}
+
+	save(data) {
+		return request({
+			url: prefix + "/psi/loss/save",
+			method: "post",
+			data,
+		});
+	}
+
+	findById(id) {
+		return request({
+			url: prefix + "/psi/loss/findById",
+			method: "get",
+			params: { id },
+		});
+	}
+
+	list(params) {
+		return request({
+			url: prefix + "/psi/loss/list",
+			method: "get",
+			params,
+		});
+	}
+
+	exportFile(params) {
+		return request({
+			url: prefix + "/psi/loss/exportFile",
+			method: "get",
+			params: params,
+			responseType: "blob",
+		});
+	}
+}

+ 55 - 0
src/api/psi/MaterialManagementService.js

@@ -0,0 +1,55 @@
+import request from "@/utils/httpRequest";
+import { PSI_MANAGEMANT as prefix } from "../AppPath";
+
+export default class MaterialManagementService {
+	list(param) {
+		return request({
+			url: prefix + "/psi/management/list",
+			method: "get",
+			params: param,
+		});
+	}
+	save(param) {
+		return request({
+			url: prefix + "/psi/management/save",
+			method: "post",
+			data: param,
+		});
+	}
+	findById(id) {
+		return request({
+			url: prefix + "/psi/management/findById",
+			method: "get",
+			params: { id: id },
+		});
+	}
+	remove(id) {
+		return request({
+			url: prefix + "/psi/management/remove",
+			method: "get",
+			params: { id: id },
+		});
+	}
+	updateStatusById(param) {
+		return request({
+			url: prefix + "/psi/management/updateStatusById",
+			method: "post",
+			data: param,
+		});
+	}
+	exportFile(params) {
+		return request({
+			url: prefix + "/psi/management/exportFile",
+			method: "get",
+			params: params,
+			responseType: "blob",
+		});
+	}
+	findTradeByTypeId(typeId) {
+		return request({
+			url: prefix + "/psi/management/findTradeByTypeId",
+			method: "get",
+			params: { typeId: typeId },
+		});
+	}
+}

+ 47 - 0
src/api/psi/MaterialTypeService.js

@@ -0,0 +1,47 @@
+import request from "@/utils/httpRequest";
+import { PSI_MANAGEMANT as prefix } from "../AppPath";
+
+export default class MaterialTypeService {
+	list(param) {
+		return request({
+			url: prefix + "/psi/materialType/list",
+			method: "get",
+			params: param,
+		});
+	}
+	bxList(param) {
+		return request({
+			url: prefix + "/psi/materialType/bxList",
+			method: "get",
+			params: param,
+		});
+	}
+	cgList(param) {
+		return request({
+			url: prefix + "/psi/materialType/cgList",
+			method: "get",
+			params: param,
+		});
+	}
+	save(param) {
+		return request({
+			url: prefix + "/psi/materialType/save",
+			method: "post",
+			data: param,
+		});
+	}
+	findById(id) {
+		return request({
+			url: prefix + "/psi/materialType/findById",
+			method: "get",
+			params: { id: id },
+		});
+	}
+	remove(id) {
+		return request({
+			url: prefix + "/psi/materialType/deleteById",
+			method: "get",
+			params: { id: id },
+		});
+	}
+}

+ 40 - 0
src/api/psi/SupplierService.js

@@ -0,0 +1,40 @@
+import request from "@/utils/httpRequest";
+import { PSI_MANAGEMANT as prefix } from "../AppPath";
+
+export default class SupplierService {
+	save(param) {
+		return request({
+			url: prefix + "/psi/supplier/save",
+			method: "post",
+			data: param,
+		});
+	}
+	queryById(id) {
+		return request({
+			url: prefix + "/psi/supplier/queryById",
+			method: "get",
+			params: { id: id },
+		});
+	}
+	list(param) {
+		return request({
+			url: prefix + "/psi/supplier/list",
+			method: "get",
+			params: param,
+		});
+	}
+	delete(ids) {
+		return request({
+			url: prefix + "/psi/supplier/delete",
+			method: "delete",
+			params: { ids: ids },
+		});
+	}
+	findByName(name) {
+		return request({
+			url: prefix + "/psi/supplier/findByName",
+			method: "get",
+			params: { name: name },
+		});
+	}
+}

+ 191 - 0
src/api/psi/WareHouseService.js

@@ -0,0 +1,191 @@
+import request from "@/utils/httpRequest";
+import { PSI_MANAGEMANT as prefix } from "../AppPath";
+
+export default class WareHouseService {
+	list(params) {
+		return request({
+			url: prefix + "/psi/management/wareHouse/list",
+			method: "get",
+			params: params,
+		});
+	}
+	reimbursementList(params) {
+		return request({
+			url: prefix + "/psi/management/wareHouse/reimbursementList",
+			method: "get",
+			params: params,
+		});
+	}
+	wareHouseList(param) {
+		return request({
+			url: prefix + "/psi/management/wareHouse/wareHouseList",
+			method: "get",
+			params: param,
+		});
+	}
+	exportFile(params) {
+		return request({
+			url: prefix + "/psi/management/wareHouse/exportFile",
+			method: "get",
+			params: params,
+			responseType: "blob",
+		});
+	}
+	exportSummaryFile(params) {
+		return request({
+			url: prefix + "/psi/management/wareHouse/exportSummaryFile",
+			method: "get",
+			params: params,
+			responseType: "blob",
+		});
+	}
+
+	wareHouseHistoryList(param) {
+		return request({
+			url: prefix + "/psi/management/wareHouse/wareHouseHistoryList",
+			method: "get",
+			params: param,
+		});
+	}
+	collectHistoryList(param) {
+		return request({
+			url: prefix + "/psi/management/wareHouse/collectHistoryList",
+			method: "get",
+			params: param,
+		});
+	}
+	wareHouseSummaryList(param) {
+		return request({
+			url: prefix + "/psi/management/wareHouse/wareHouseSummaryList",
+			method: "get",
+			params: param,
+		});
+	}
+	wareHouseSummaryList2(param) {
+		return request({
+			url: prefix + "/psi/management/wareHouse/wareHouseSummaryList2",
+			method: "get",
+			params: param,
+		});
+	}
+	getByProduceDateAndNameGroup(param) {
+		return request({
+			url:
+				prefix +
+				"/psi/management/wareHouse/getByProduceDateAndNameGroup",
+			method: "get",
+			params: param,
+		});
+	}
+	getByProduceDateNotMerge(param) {
+		return request({
+			url: prefix + "/psi/management/wareHouse/getByProduceDateNotMerge",
+			method: "get",
+			params: param,
+		});
+	}
+
+	save(param) {
+		return request({
+			url: prefix + "/psi/management/wareHouse/save",
+			method: "post",
+			data: param,
+		});
+	}
+	findById(id, status) {
+		return request({
+			url: prefix + "/psi/management/wareHouse/findById",
+			method: "get",
+			params: { id: id, status: status },
+		});
+	}
+	remove(id) {
+		return request({
+			url: prefix + "/psi/management/wareHouse/remove",
+			method: "get",
+			params: { id: id },
+		});
+	}
+	findRequestId(purchaseNo) {
+		return request({
+			url: prefix + "/psi/management/wareHouse/findRequestId",
+			method: "get",
+			params: { purchaseNo: purchaseNo },
+		});
+	}
+	updateStatusById(data) {
+		return request({
+			url: prefix + "/psi/management/wareHouse/updateStatusById",
+			method: "post",
+			data: data,
+		});
+	}
+	backSourceData(id) {
+		return request({
+			url: prefix + "/psi/management/wareHouse/backSourceData",
+			method: "get",
+			params: { id: id },
+		});
+	}
+	findHiById(id) {
+		return request({
+			url: prefix + "/psi/management/wareHouse/findHiById",
+			method: "get",
+			params: { id: id },
+		});
+	}
+	findHiByHiId(id) {
+		return request({
+			url: prefix + "/psi/management/wareHouse/findHiByHiId",
+			method: "get",
+			params: { id: id },
+		});
+	}
+	findLastHiByid(id) {
+		return request({
+			url: prefix + "/psi/management/wareHouse/findLastHiByid",
+			method: "get",
+			params: { id: id },
+		});
+	}
+	updateWarnFlagByTradeNameAndType(tradeName, wareHouseType) {
+		return request({
+			url:
+				prefix +
+				`/psi/management/wareHouse/updateWarnFlagByTradeNameAndType`,
+			method: "post",
+			data: { tradeName: tradeName, wareHouseType: wareHouseType },
+		});
+	}
+	updateWarnNumByTradeNameAndType(tradeName, wareHouseType, warnNum) {
+		return request({
+			url:
+				prefix +
+				`/psi/management/wareHouse/updateWarnNumByTradeNameAndType`,
+			method: "post",
+			data: {
+				tradeName: tradeName,
+				wareHouseType: wareHouseType,
+				warnNum: warnNum,
+			},
+		});
+	}
+	saveTradeName(oldTradeName, tradeName, type) {
+		return request({
+			url: prefix + `/psi/management/wareHouse/saveTradeName`,
+			method: "post",
+			data: {
+				oldTradeName: oldTradeName,
+				tradeName: tradeName,
+				wareHouseType: type,
+			},
+		});
+	}
+	findTradeByTypeId(typeId) {
+		return request({
+			url: prefix + "/psi/management/wareHouse/findTradeByTypeId",
+			method: "get",
+			params: { typeId: typeId },
+		});
+	}
+}

+ 64 - 74
src/views/dashboard/widgets/components/MyNoticePageList.vue

@@ -3,8 +3,9 @@
 		<template #header>
 			<div class="card-header">
 				<span>
-				我的通知
-				<el-badge class="mark" v-if="tablePage.total !== 0" :value="tablePage.total" :max="99" style="line-height: 0;margin-top: 8px"/>
+					我的通知
+					<el-badge class="mark" v-if="tablePage.total !== 0" :value="tablePage.total" :max="99"
+						style="line-height: 0;margin-top: 8px" />
 				</span>
 				<div style="float:right;">
 					<el-button type="text" @click="refreshList()">刷新</el-button>
@@ -16,8 +17,9 @@
 			<el-table-column label="实例标题" prop="title" min-width="400px">
 				<template #default="scope">
 					<el-link type="primary" :underline="false" @click="todo(scope.row)">
-						<span v-if="scope.row.repetitionCount > 0" >
-							<span style="color: red; font-weight: bold;">【{{ scope.row.repetitionCount }}】</span>{{ scope.row.title }}
+						<span v-if="scope.row.repetitionCount > 0">
+							<span style="color: red; font-weight: bold;">【{{ scope.row.repetitionCount }}】</span>{{
+								scope.row.title }}
 						</span>
 						<span v-else>
 							{{ scope.row.title }}
@@ -27,75 +29,54 @@
 			</el-table-column>
 
 
-			<el-table-column
-				min-width="90px"
-				show-overflow-tooltip
-				label="流程名称"
-				prop="taskName"
-			></el-table-column>
-			<el-table-column
-				min-width="100px"
-				show-overflow-tooltip
-				label="发起人"
-				prop="createUser"
-			></el-table-column>
-			<el-table-column
-				fixed="right"
-				min-width="100px"
-				show-overflow-tooltip
-				label="创建时间"
-				prop="createTime"
-			></el-table-column>
+			<el-table-column min-width="90px" show-overflow-tooltip label="流程名称" prop="taskName"></el-table-column>
+			<el-table-column min-width="100px" show-overflow-tooltip label="发起人" prop="createUser"></el-table-column>
+			<el-table-column fixed="right" min-width="100px" show-overflow-tooltip label="创建时间"
+				prop="createTime"></el-table-column>
 		</el-table>
-		<vxe-pager
-			background
-			size="small"
-			:current-page="tablePage.currentPage"
-			:page-size="tablePage.pageSize"
-			:total="tablePage.total"
-			:page-sizes="[
+		<vxe-pager background size="small" :current-page="tablePage.currentPage" :page-size="tablePage.pageSize"
+			:total="tablePage.total" :page-sizes="[
 				10,
 				20,
 				100,
 				1000,
 				{ label: '全量数据', value: 1000000 },
-			]"
-			:layouts="[
+			]" :layouts="[
 				'PrevPage',
 				'JumpNumber',
 				'NextPage',
 				'FullJump',
 				'Sizes',
 				'Total',
-			]"
-			@page-change="currentChangeHandle"
-		>
+			]" @page-change="currentChangeHandle">
 		</vxe-pager>
 	</el-card>
 	<WareHouseHistoryPopup ref="wareHouseHistoryPopup"></WareHouseHistoryPopup>
+	<PsiWareHouseHistoryPopup ref="wareHouseHistoryPopup2"></PsiWareHouseHistoryPopup>
 	<RegisterPopup ref="registerPopup"></RegisterPopup>
 	<KeyCardPopup ref="keyCardPopup"></KeyCardPopup>
 	<DepartPopup ref="departPopup"></DepartPopup>
 	<DepartProvePopup ref="departProvePopup"></DepartProvePopup>
 	<ProjectRecordsForm ref="projectRecordsForm"></ProjectRecordsForm>
-	<CwInvoiceForm  ref="cwInvoiceForm"></CwInvoiceForm>
-	<InvoiceForm  ref="invoiceForm"></InvoiceForm>
+	<CwInvoiceForm ref="cwInvoiceForm"></CwInvoiceForm>
+	<InvoiceForm ref="invoiceForm"></InvoiceForm>
 
 </template>
 
 <script>
-	import WareHouseHistoryPopup from '@/views/materialManagement/wareHouseSummary/WareHouseHistoryPopup'
-	import RegisterPopup from '@/views/human/practice/register/RegisterPopup'
-	import KeyCardPopup from '@/views/human/enrollment/registration/KeyCardPopup'
-	import DepartPopup from '@/views/human/depart/handover/DepartPopup'
-	import DepartProvePopup from '@/views/human/depart/handover/DepartProvePopup'
-	import ProjectRecordsForm from "@/views/cw/projectRecords/ProjectRecordsForm";
-	import CwInvoiceForm from '@/views/cw/invoice/InvoiceForm'
-	import InvoiceForm from '@/views/finance/invoice/InvoiceForm'
-	// import notifyService from "@/api/notify/notifyService";
+import WareHouseHistoryPopup from '@/views/materialManagement/wareHouseSummary/WareHouseHistoryPopup'
+import PsiWareHouseHistoryPopup from '@/views/psiManagement/wareHouseSummary/WareHouseHistoryPopup.vue'
+import RegisterPopup from '@/views/human/practice/register/RegisterPopup'
+import KeyCardPopup from '@/views/human/enrollment/registration/KeyCardPopup'
+import DepartPopup from '@/views/human/depart/handover/DepartPopup'
+import DepartProvePopup from '@/views/human/depart/handover/DepartProvePopup'
+import ProjectRecordsForm from "@/views/cw/projectRecords/ProjectRecordsForm";
+import CwInvoiceForm from '@/views/cw/invoice/InvoiceForm'
+import InvoiceForm from '@/views/finance/invoice/InvoiceForm'
+// import notifyService from "@/api/notify/notifyService";
 import noticeService from '@/api/flowable/NoticeService'
 import taskService from "@/api/flowable/taskService";
-	import pick from "lodash.pick";
+import pick from "lodash.pick";
 export default {
 	title: "我的通知",
 	icon: "tongzhi",
@@ -106,6 +87,7 @@ export default {
 	},
 	components: {
 		WareHouseHistoryPopup,
+		PsiWareHouseHistoryPopup,
 		RegisterPopup,
 		KeyCardPopup,
 		DepartPopup,
@@ -142,25 +124,25 @@ export default {
 		this.refreshList();
 	},
 	methods: {
-		todo (row) {
+		todo(row) {
 			// console.log('row', row)
 			if (row.taskName === '评估发票超期收款') {
 				// console.log('测试进来了')
-				this.$refs.invoiceForm.init(false,row.defId)
+				this.$refs.invoiceForm.init(false, row.defId)
 				this.inputForm = {
 					id: row.id
 				}
 				noticeService.stockUpdate(this.inputForm)
 				this.resetSearch()
-			}else if (row.taskName === '超期收款发票') {
+			} else if (row.taskName === '超期收款发票') {
 				// console.log('测试进来了')
-				this.$refs.cwInvoiceForm.init(false,row.defId)
+				this.$refs.cwInvoiceForm.init(false, row.defId)
 				this.inputForm = {
 					id: row.id
 				}
 				noticeService.stockUpdate(this.inputForm)
 				this.resetSearch()
-			}else if (row.taskName === '库存提醒') {
+			} else if (row.taskName === '库存提醒') {
 				// console.log('测试进来了')
 				this.$refs.wareHouseHistoryPopup.init(row.defId)
 				this.inputForm = {
@@ -168,42 +150,50 @@ export default {
 				}
 				noticeService.stockUpdate(this.inputForm)
 				this.resetSearch()
-			}else if (row.taskName === '实习日志超时提醒') {
+			} else if (row.taskName === '进销存库存提醒') {
+				// console.log('测试进来了')
+				this.$refs.wareHouseHistoryPopup2.init(row.defId)
+				this.inputForm = {
+					id: row.id
+				}
+				noticeService.stockUpdate(this.inputForm)
+				this.resetSearch()
+			} else if (row.taskName === '实习日志超时提醒') {
 				this.$refs.registerPopup.init(row.defId)
 				this.inputForm = {
 					id: row.id
 				}
 				noticeService.stockUpdate(this.inputForm)
 				this.resetSearch()
-			}else if (row.taskName === '门卡领取提醒') {
+			} else if (row.taskName === '门卡领取提醒') {
 				this.$refs.keyCardPopup.init()
 				this.inputForm = {
 					id: row.id
 				}
 				noticeService.stockUpdate(this.inputForm)
 				this.resetSearch()
-			}else if (row.taskName.includes('离职提醒')) {
+			} else if (row.taskName.includes('离职提醒')) {
 				this.$refs.departPopup.init(row.taskName)
 				this.inputForm = {
 					id: row.id
 				}
 				noticeService.stockUpdate(this.inputForm)
 				this.resetSearch()
-			}else if (row.taskName.includes('请点击下载离职证明')) {
-				this.$refs.departProvePopup.init(row.taskName,row.defId)
+			} else if (row.taskName.includes('请点击下载离职证明')) {
+				this.$refs.departProvePopup.init(row.taskName, row.defId)
 				this.inputForm = {
 					id: row.id
 				}
 				noticeService.stockUpdate(this.inputForm)
 				this.resetSearch()
-			}else if (row.taskName === '预开票项目未关联') {
-				this.$refs.projectRecordsForm.init('view',row.defId)
+			} else if (row.taskName === '预开票项目未关联') {
+				this.$refs.projectRecordsForm.init('view', row.defId)
 				this.inputForm = {
 					id: row.id
 				}
 				noticeService.stockUpdate(this.inputForm)
 				this.resetSearch()
-			}else {
+			} else {
 				this.inputForm = {
 					taskId: '',
 					noticeId: '',
@@ -230,16 +220,16 @@ export default {
 					// 	}
 					// })
 					this.$router.push({
-					  path: '/flowable/task/TaskFormDetail',
-					  query: {
-						  ...pick(data, 'formType', 'formUrl', 'procDefKey', 'taskDefKey', 'procInsId', 'procDefId', 'taskId', 'status', 'title'),
-						  isShow: 'false',
-						  readOnly: true,
-						title: `审批【${row.taskName || ''}】`,
-						formTitle: `${row.title}`,
-						businessId: data.businessId,
-						  status: 'reback'
-					  }
+						path: '/flowable/task/TaskFormDetail',
+						query: {
+							...pick(data, 'formType', 'formUrl', 'procDefKey', 'taskDefKey', 'procInsId', 'procDefId', 'taskId', 'status', 'title'),
+							isShow: 'false',
+							readOnly: true,
+							title: `审批【${row.taskName || ''}】`,
+							formTitle: `${row.title}`,
+							businessId: data.businessId,
+							status: 'reback'
+						}
 					})
 				})
 			}
@@ -269,7 +259,7 @@ export default {
 			// this.$refs.searchForm.resetFields();
 			this.refreshList();
 		},
-		toPendingList () {
+		toPendingList() {
 			// this.$router.push('./PendingList')
 			this.$router.push('/flowable/task/NoticePageList')
 		},
@@ -277,7 +267,7 @@ export default {
 };
 </script>
 <style scoped>
-	.box-card {
-		height: 100%;
-	}
+.box-card {
+	height: 100%;
+}
 </style>

+ 17 - 2
src/views/flowable/task/TaskForm.vue

@@ -739,6 +739,11 @@ export default {
 		// Process_1722412442950 项目-报销文件补充
 		// Process_1722416114655 咨询-报销文件补充
 		// Process_1723517404891 会议室预约
+		// Process_1774937846626 进销存-采购申请
+		// Process_1775006048278 进销存-入库修改
+		// Process_1775013293806 进销存-领用申请
+		// Process_1775013611447 进销存-领用退回申请
+		// Process_1775549295075 进销存-报损申请
 		// 驳回
 		reject(vars) {
 			if (this.procDefId.includes('Process_1667978088459') ||
@@ -836,7 +841,12 @@ export default {
 				this.procDefId.includes('Process_1722412442950') ||
 				this.procDefId.includes('Process_1722416114655') ||
 				this.procDefId.includes('Process_1723517404891') ||
-				this.procDefId.includes('Process_1751269402209')
+				this.procDefId.includes('Process_1751269402209') ||
+				this.procDefId.includes('Process_1774937846626') ||
+				this.procDefId.includes('Process_1775006048278') ||
+				this.procDefId.includes('Process_1775013293806') ||
+				this.procDefId.includes('Process_1775013611447') ||
+				this.procDefId.includes('Process_1775549295075')
 			) {
 				console.log('进入新版驳回')
 				this.$confirm(`确定驳回流程吗?`, '提示', {
@@ -990,7 +1000,12 @@ export default {
 				this.procDefId.includes('Process_1699321267272') ||
 				this.procDefId.includes('Process_1699926014064') ||
 				this.procDefId.includes('Process_1698129477831') ||
-				this.procDefId.includes('Process_1702534302878')
+				this.procDefId.includes('Process_1702534302878') ||
+				this.procDefId.includes('Process_1774937846626') ||
+				this.procDefId.includes('Process_1775006048278') ||
+				this.procDefId.includes('Process_1775013293806') ||
+				this.procDefId.includes('Process_1775013611447') ||
+				this.procDefId.includes('Process_1775549295075')
 			) {
 				if (this.formType === '2') {
 					vars = { ...vars, agree: false }

Datei-Diff unterdrückt, da er zu groß ist
+ 1053 - 0
src/views/psiManagement/collect/CollectForm.vue


+ 680 - 0
src/views/psiManagement/collect/CollectList.vue

@@ -0,0 +1,680 @@
+<template>
+	<div class="page">
+		<el-form :inline="true" v-if="searchVisible" class="query-form m-b-10" ref="searchForm" :model="searchForm"
+			@keyup.enter.native="refreshList()" @submit.native.prevent>
+			<!-- 搜索框-->
+			<el-form-item label="领用编号" prop="collectNo">
+				<el-input v-model="searchForm.collectNo" placeholder="请输入领用编号" clearable></el-input>
+			</el-form-item>
+			<el-form-item label="领用物品名称" prop="goodsName">
+				<el-input v-model="searchForm.goodsName" placeholder="请输入领用物品名称" clearable></el-input>
+			</el-form-item>
+			<el-form-item v-if="showHideItem" label="经办人" prop="handledBy">
+				<UserSelect :limit='1' :modelValue="searchForm.handledBy"
+					@update:modelValue='(value, label) => { searchForm.handledBy = value }'></UserSelect>
+			</el-form-item>
+			<el-form-item v-if="showHideItem" prop="handledByOffice" label="经办人部门">
+				<SelectTree ref="officeTree" :props="{
+					value: 'id',             // ID字段名
+					label: 'name',         // 显示名称
+					children: 'children'    // 子级字段名
+				}" :url="`/system-server/sys/office/treeData?type=2`" :value="searchForm.handledByOffice" size="default"
+					:accordion="true" @getValue="(value) => { searchForm.handledByOffice = value }" />
+			</el-form-item>
+			<el-form-item v-if="showHideItem" label="领用时间" prop="collectDates">
+				<el-date-picker placement="bottom-start" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
+					v-model="searchForm.collectDates" type="datetimerange" range-separator="至" start-placeholder="开始日期"
+					end-placeholder="结束日期">
+				</el-date-picker>
+			</el-form-item>
+			<el-form-item v-if="showHideItem" label="退回状态" prop="statusReturn">
+				<el-select v-model="searchForm.statusReturn" placeholder="请选择" style="width:100%;" clearable>
+					<el-option v-for="item in $dictUtils.getDictList('cw_status')" :key="item.value" :label="item.label"
+						:value="item.value">
+					</el-option>
+				</el-select>
+			</el-form-item>
+			<el-form-item>
+				<el-button type="default" @click="showHide" :icon="showHideIcon">{{ showHideName }}</el-button>
+				<el-button type="primary" @click="refreshList()" icon="el-icon-search">查询</el-button>
+				<el-button @click="resetSearch()" icon="el-icon-refresh-right">重置</el-button>
+			</el-form-item>
+		</el-form>
+		<div class="jp-table top" style="">
+			<vxe-toolbar :refresh="{ query: refreshList }" custom>
+				<template #buttons>
+					<el-button v-if="hasPermission('psi:add')" type="primary" icon="el-icon-plus"
+						@click="start()">新建</el-button>
+					<el-button v-if="hasPermission('psi:edit')" type="warning" icon="el-icon-plus"
+						@click="exportFile()">导出</el-button>
+				</template>
+				<template #tools>
+					<vxe-button text type="primary" :title="searchVisible ? '收起检索' : '展开检索'" icon="vxe-icon-search"
+						class="tool-btn" @click="searchVisible = !searchVisible"></vxe-button>
+				</template>
+			</vxe-toolbar>
+			<div style="height: calc(100% - 90px)">
+				<vxe-table :key="tableKey" border="inner" auto-resize resizable height="auto" :loading="loading"
+					ref="clientTable" show-header-overflow show-overflow highlight-hover-row :menu-config="{}"
+					@sort-change="sortChangeHandle" :sort-config="{ remote: true }" :data="dataList"
+					:checkbox-config="{}">
+					<vxe-column type="seq" width="60" title="序号"></vxe-column>
+					<vxe-column min-width="160" align="center" title="领用编号" field="collectNo">
+						<template #default="scope">
+							<el-link type="primary" :underline="false" v-if="hasPermission('psi:list')"
+								@click="view(scope.row.id)">{{ scope.row.collectNo }}</el-link>
+							<el-link type="primary" :underline="false" v-else-if="hasPermission('psi:list')"
+								@click="view(scope.row.id,)">{{ scope.row.collectNo }}</el-link>
+							<span v-else>{{ scope.row.collectNo }}</span>
+						</template>
+					</vxe-column>
+					<vxe-column min-width="160" align="center" title="领用物品名称" field="goodsName">
+						<template #default="scope">
+							<span v-if="commonJS.isEmpty(scope.row.detailId)" style="color: #F56C6C">领用物品已全部退回</span>
+							<span v-else>{{ scope.row.goodsName }}</span>
+						</template>
+					</vxe-column>
+					<vxe-column min-width="160" align="center" title="经办人" field="handledByName"></vxe-column>
+					<vxe-column min-width="160" align="center" title="经办人部门" field="handledByOfficeName"></vxe-column>
+					<vxe-column min-width="160" align="center" title="领用时间" field="collectDate"></vxe-column>
+					<vxe-column min-width="100px" align="center" fixed="right" title="状态" field="status">
+						<template #default="scope">
+							<el-button @click="detail(scope.row)" effect="dark"
+								:type="$dictUtils.getDictLabel('cw_status_flag', scope.row.status, '')">
+								{{ $dictUtils.getDictLabel("cw_status", scope.row.status, '') }}
+							</el-button>
+						</template>
+					</vxe-column>
+					<vxe-column min-width="100px" align="center" fixed="right" title="退回状态" field="statusReturn">
+						<template #default="scope">
+							<el-button @click="detailReturn(scope.row)" effect="dark"
+								:type="$dictUtils.getDictLabel('cw_status_flag', scope.row.statusReturn, '')">
+								{{ $dictUtils.getDictLabel("cw_status", scope.row.statusReturn, '未发起') }}
+							</el-button>
+						</template>
+					</vxe-column>
+
+					<vxe-column title="操作" width="220px" fixed="right" align="center">
+						<template #default="scope">
+							<el-button
+								v-if="hasPermission('psi:edit') && scope.row.createBy === $store.state.user.id && (scope.row.status === '1' || scope.row.status === '3')"
+								text type="primary" size="small" @click="push(scope.row)">修改</el-button>
+							<el-button
+								v-else-if="hasPermission('psi:edit') && isAdmin && (scope.row.status === '1' || scope.row.status === '3' || scope.row.status === '4' || scope.row.status === '5')"
+								text type="primary" size="small" @click="edit(scope.row.id)">修改</el-button>
+							<el-button
+								v-if="hasPermission('psi:edit') && scope.row.createBy === $store.state.user.id && scope.row.status === '2'"
+								text type="primary" size="small" @click="reback(scope.row)">撤回</el-button>
+							<el-button
+								v-if="hasPermission('psi:del') && scope.row.createBy === $store.state.user.id && (scope.row.status === '1' || scope.row.status === '3')"
+								text type="primary" size="small" @click="del(scope.row.id)">删除</el-button>
+							<el-button
+								v-else-if="hasPermission('psi:del') && isAdmin && (scope.row.status === '1' || scope.row.status === '3' || scope.row.status === '4' || scope.row.status === '5')"
+								text type="primary" size="small" @click="del(scope.row.id)">删除</el-button>
+							<el-button v-if="scope.row.status === '2' && checkIsAudit(scope.row)" text type="primary"
+								size="small" @click="examine(scope.row)">审核</el-button>
+							<el-button
+								v-if="hasPermission('psi:edit') && scope.row.status === '4' && scope.row.createBy === $store.state.user.id"
+								text type="primary" size="small" @click="adjust(scope.row)">驳回调整</el-button>
+
+							<el-button
+								v-if="hasPermission('psi:edit') && scope.row.status === '5' && scope.row.createBy === $store.state.user.id && commonJS.isNotEmpty(scope.row.detailId) &&
+									(commonJS.isEmpty(scope.row.statusReturn) || scope.row.statusReturn === '0' || scope.row.statusReturn === '1' || scope.row.statusReturn === '3' || scope.row.statusReturn === '5')"
+								text type="primary" size="small" @click="returnPush(scope.row)">退回</el-button>
+							<el-button
+								v-if="hasPermission('psi:edit') && scope.row.statusReturn === '2' && scope.row.createBy === $store.state.user.id"
+								text type="primary" size="small" @click="rebackReturn(scope.row)">撤回</el-button>
+							<el-button
+								v-if="hasPermission('psi:edit') && scope.row.statusReturn === '3' && scope.row.createBy === $store.state.user.id"
+								text type="primary" size="small" @click="returnRequest(scope.row)">取消申请</el-button>
+							<el-button v-if="scope.row.statusReturn === '2' && checkIsAuditReturn(scope.row)" text
+								type="primary" size="small" @click="examineReturn(scope.row)">退回审核</el-button>
+							<el-button
+								v-if="hasPermission('psi:edit') && scope.row.statusReturn === '4' && scope.row.createBy === $store.state.user.id"
+								text type="primary" size="small" @click="adjustReturn(scope.row)">驳回调整</el-button>
+						</template>
+					</vxe-column>
+				</vxe-table>
+				<vxe-pager background :current-page="tablePage.currentPage" :page-size="tablePage.pageSize"
+					:total="tablePage.total" :page-sizes="[10, 20, 100, 1000, { label: '全量数据', value: 1000000 }]"
+					:layouts="['PrevPage', 'JumpNumber', 'NextPage', 'FullJump', 'Sizes', 'Total']"
+					@page-change="currentChangeHandle">
+				</vxe-pager>
+				<UpdateCollectInfoForm ref="updateCollectInfoForm" @refreshList="refreshList"></UpdateCollectInfoForm>
+			</div>
+		</div>
+	</div>
+</template>
+
+<script>
+import UserSelect from '@/components/userSelect'
+import CollectService from '@/api/psi/CollectService'
+import UpdateCollectInfoForm from './UpdateCollectInfoForm'
+import SelectTree from '@/components/treeSelect/treeSelect.vue'
+import taskService from '@/api/flowable/taskService'
+import processService from '@/api/flowable/processService'
+import pick from 'lodash.pick'
+import userService from '@/api/sys/userService'
+export default {
+	data() {
+		return {
+			searchVisible: true,
+			showHideItem: false,
+			showHideIcon: 'el-icon-arrow-down',
+			showHideName: '展示',
+			num: 0,
+			searchForm: {
+				handledBy: '',
+				handledByOffice: '',
+				collectNo: '',
+				goodsName: '',
+				collectDates: [],
+				statusReturn: ''
+			},
+			dataList: [],
+			tablePage: {
+				total: 0,
+				currentPage: 1,
+				pageSize: 10,
+				orders: []
+			},
+			tableKey: '',
+			loading: false,
+			processDefinitionAuditId: '',
+			procDefAuditKey: '',
+			isAdmin: false,
+			create: '',
+			processDefinitionAuditIdReturn: '',
+			procDefAuditKeyReturn: ''
+		}
+	},
+	collectService: null,
+	created() {
+		this.collectService = new CollectService()
+	},
+	components: {
+		UserSelect,
+		SelectTree,
+		UpdateCollectInfoForm
+	},
+	computed: {
+		userName() {
+			return this.$store.state.user.name
+		},
+		user() {
+			this.createName = this.$store.state.user.name
+			return this.$store.state.user
+		}
+	},
+	mounted() {
+		this.refreshList()
+	},
+	activated() {
+		this.refreshList()
+	},
+	methods: {
+		showHide() {
+			if (this.showHideItem === false) {
+				this.showHideItem = true
+				this.showHideIcon = 'el-icon-arrow-up'
+				this.showHideName = '隐藏'
+			} else {
+				this.showHideItem = false
+				this.showHideIcon = 'el-icon-arrow-down'
+				this.showHideName = '展示'
+			}
+		},
+		// 新增
+		add() {
+			// this.$refs.reportManagementForm.init('add', '')
+		},
+		// 修改
+		edit(id) {
+			id = id || this.$refs.clientTable.getCheckboxRecords().map(item => {
+				return item.id
+			})[0]
+			this.$refs.updateCollectInfoForm.init('edit', id)
+		},
+		// 查看
+		view(id) {
+			this.$refs.updateCollectInfoForm.init('view', id)
+		},
+		// 查询当前用户是否是管理员用户
+		checkIsAdmin() {
+			userService.is().then((data) => {
+				this.isAdmin = data
+			})
+		},
+		// 获取数据列表
+		refreshList() {
+			this.loading = true
+			this.collectService.list({
+				'current': this.tablePage.currentPage,
+				'size': this.tablePage.pageSize,
+				'orders': this.tablePage.orders,
+				...this.searchForm
+			}).then((data) => {
+				this.dataList = data.records
+				this.tablePage.total = data.total
+				this.tableKey = Math.random()
+				this.loading = false
+			})
+			this.checkIsAdmin()
+			processService.getByName('进销存-领用申请').then((data) => {
+				if (!this.commonJS.isEmpty(data.id)) {
+					this.processDefinitionAuditId = data.id
+					this.procDefAuditKey = data.key
+				}
+			})
+			processService.getByName('进销存-领用退回申请').then((data) => {
+				if (!this.commonJS.isEmpty(data.id)) {
+					this.processDefinitionAuditIdReturn = data.id
+					this.procDefAuditKeyReturn = data.key
+				}
+			})
+		},
+		// 当前页
+		currentChangeHandle({ currentPage, pageSize }) {
+			this.tablePage.currentPage = currentPage
+			this.tablePage.pageSize = pageSize
+			this.refreshList()
+		},
+		// 排序
+		sortChangeHandle(column) {
+			this.tablePage.orders = []
+			if (column.order != null) {
+				this.tablePage.orders.push({ column: this.$utils.toLine(column.property), asc: column.order === 'asc' })
+			}
+			this.refreshList()
+		},
+		// 删除
+		del(id) {
+			let ids = id || this.$refs.clientTable.getCheckboxRecords().map(item => {
+				return item.id
+			}).join(',')
+			this.$confirm(`确定删除所选项吗?`, '提示', {
+				confirmButtonText: '确定',
+				cancelButtonText: '取消',
+				type: 'warning'
+			}).then(() => {
+				this.loading = true
+				this.collectService.remove(ids).then((data) => {
+					this.$message.success(data)
+					this.refreshList()
+					this.loading = false
+				})
+			})
+		},
+		resetSearch() {
+			this.$refs.searchForm.resetFields()
+			this.refreshList()
+		},
+		start() {
+			// 读取流程表单
+			let tabTitle = `发起流程【领用申请】`
+			let processTitle = `${this.userName} 在 ${this.moment(new Date()).format('YYYY-MM-DD HH:mm')} 发起了 [领用申请]`
+			taskService.getTaskDef({
+				procDefId: this.processDefinitionAuditId,
+				status: 'startAndHold'
+			}).then((data) => {
+				this.$router.push({
+					path: '/flowable/task/TaskForm',
+					query: {
+						...pick(data, 'formType', 'formUrl', 'procDefKey', 'taskDefKey', 'procInsId', 'procDefId', 'taskId', 'status', 'title'),
+						procDefId: this.processDefinitionAuditId,
+						procDefKey: this.procDefAuditKey,
+						status: 'startAndHold',
+						title: tabTitle,
+						formType: data.formType,
+						formUrl: data.formUrl,
+						formTitle: processTitle,
+						businessId: 'false',
+						isShow: false,
+						routePath: '/psiManagement/collect/CollectList'
+					}
+				})
+			})
+		},
+		// 发起领用申请
+		push(row) {
+			// 读取流程表单
+			let title = `发起流程【领用申请】`
+			let processTitle = `${this.userName} 在 ${this.moment(new Date()).format('YYYY-MM-DD HH:mm')} 发起了[领用申请]`
+			let status = 'startAndHold'
+			if (row.status === '3') {
+				status = 'startAndClose'
+			} else if (row.status === '4') {
+				status = 'reapplyFlag'
+			}
+			taskService.getTaskDef({
+				procDefId: this.processDefinitionAuditId,
+				businessId: row.id,
+				businessTable: 'material_management_collect_basics'
+			}).then((data) => {
+				this.$router.push({
+					path: '/flowable/task/TaskForm',
+					query: {
+						...pick(data, 'formType', 'formUrl', 'procDefKey', 'taskDefKey', 'procInsId', 'procDefId', 'taskId', 'status', 'title'),
+						procDefId: this.processDefinitionAuditId,
+						procDefKey: this.procDefAuditKey,
+						title: title,
+						formType: data.formType,
+						formUrl: data.formUrl,
+						formTitle: processTitle,
+						businessTable: 'psi_management_collect_basics',
+						businessId: row.id,
+						isShow: 'false',
+						status: status,
+						routePath: '/psiManagement/collect/CollectList'
+					}
+				})
+			})
+		},
+		// 查看客户登记流程结果
+		detail(row) {
+			if (row.status !== '0' && row.status !== '1') {
+				// eslint-disable-next-line eqeqeq
+				taskService.getTaskDef({
+					procInsId: row.procInsId,
+					procDefId: this.processDefinitionAuditId
+				}).then((data) => {
+					this.$router.push({
+						path: '/flowable/task/TaskFormDetail',
+						query: {
+							...pick(data, 'formType', 'formUrl', 'procDefKey', 'taskDefKey', 'procInsId', 'procDefId', 'taskId', 'status', 'title'),
+							isShow: 'false',
+							readOnly: true,
+							title: '领用申请' + '流程详情',
+							formTitle: '领用申请' + '流程详情',
+							businessId: row.id,
+							status: 'reback'
+						}
+					})
+				})
+			}
+		},
+		// 撤回报告流程
+		reback(row) {
+			this.$confirm(`确定要撤回该申请吗?`, '提示', {
+				confirmButtonText: '确定',
+				cancelButtonText: '取消',
+				type: 'warning'
+			}).then(async () => {
+				await this.collectService.findById(row.id).then((data) => {
+					if (data.status !== '2') { // status的值不等于“审核中”,就弹出提示
+						this.$message.error('数据已发生改变或不存在,请刷新数据')
+						this.refreshList()
+					} else {
+						processService.revokeProcIns(row.procInsId).then((data) => {
+							let form = { status: '3', id: row.id }
+							this.collectService.updateStatusById(form)
+							this.$message.success(data)
+							this.refreshList()
+						})
+					}
+				})
+				// await this.reportCancellApplyService.queryById(row.id).then((data) => {
+				//   if (data.status !== '2') { // status的值不等于“审核中”,就弹出提示
+				//     this.$message.error('数据已发生改变或不存在,请刷新数据')
+				//     this.refreshList()
+				//   } else {
+				//     processService.revokeProcIns(row.procInsId).then((data) => {
+				//       let form = {status: '3', id: row.id}
+				//       this.reportCancellApplyService.updateStatusById(form)
+				//       this.$message.success(data)
+				//       this.refreshList()
+				//     })
+				//   }
+				// })
+			})
+		},
+		// 驳回后调整
+		adjust(row) {
+			this.collectService.findById(row.id).then((data) => {
+				if (data.status !== '4') { // status的值不等于“驳回”,就弹出提示
+					this.$message.error('数据已发生改变或不存在,请刷新数据')
+					this.refreshList()
+				} else {
+					this.todo(row)
+				}
+			})
+		},
+		// 审核
+		examine(row) {
+			this.collectService.findById(row.id).then((data) => {
+				if (data.status !== '2') { // status的值不等于“审核中”,就弹出提示
+					this.$message.error('数据已发生改变或不存在,请刷新数据')
+					this.refreshList()
+				} else {
+					this.todo(row)
+				}
+			})
+		},
+		// 审核或重新调整跳转
+		todo(row) {
+			let cUser = false
+			taskService.getTaskDefInfo({
+				taskId: row.taskId
+			}).then((data) => {
+				this.$router.push({
+					path: '/flowable/task/TaskForm',
+					query: {
+						...pick(data, 'formType', 'formUrl', 'procDefKey', 'taskDefKey', 'procInsId', 'procDefId', 'taskId', 'status', 'title', 'businessId'),
+						isShow: false,
+						formReadOnly: true,
+						formTitle: `${data.taskName}`,
+						cUser: cUser,
+						title: `审批【${data.taskName || ''}】`,
+						routePath: '/psiManagement/collect/CollectList'   // 数据处理后需要跳转的页面路径
+					}
+				})
+			})
+		},
+		// 查询当前登录人是否是数据的审核人
+		checkIsAudit(row) {
+			let loginUserId = this.$store.state.user.id  // 获取当前登录用户id
+			if (this.commonJS.isNotEmpty(row.auditUserIds)) {
+				for (const userId of row.auditUserIds) {
+					if (userId === loginUserId) {  // 当数据的审核人中包含当前登录人id时,返回true
+						return true
+					}
+				}
+			}
+			return false
+		},
+		// 发起领用-退回申请
+		async returnPush(row) {
+
+			if (this.commonJS.isEmpty(row.returnId)) {
+				this.loading = true
+				// 由于退回数据表中没有数据,需要生成一条默认数据
+				let resp = await this.collectService.createReturnData({ id: row.id })
+				if (resp) {
+					this.loading = false
+					row.returnId = resp.returnId
+					this.returnPushTrue(row)
+				} else {
+					this.loading = false
+					this.$message.error('无法退回数据,联系管理员解决')
+				}
+			} else {
+				this.returnPushTrue(row)
+			}
+		},
+		returnPushTrue(row) {
+			// 读取流程表单
+			let title = `发起流程【领用-退回申请】`
+			let processTitle = `${this.userName} 在 ${this.moment(new Date()).format('YYYY-MM-DD HH:mm')} 发起了[领用-退回申请]`
+			let status = 'startAndHold'
+			if (row.statusReturn === '3') {
+				status = 'startAndClose'
+			} else if (row.statusReturn === '4') {
+				status = 'reapplyFlag'
+			}
+			taskService.getTaskDef({
+				procDefId: this.processDefinitionAuditIdReturn,
+				businessId: row.returnId,
+				businessTable: 'psi_management_collect_basics_return'
+			}).then((data) => {
+				this.$router.push({
+					path: '/flowable/task/TaskForm',
+					query: {
+						...pick(data, 'formType', 'formUrl', 'procDefKey', 'taskDefKey', 'procInsId', 'procDefId', 'taskId', 'status', 'title'),
+						procDefId: this.processDefinitionAuditIdReturn,
+						procDefKey: this.procDefAuditKeyReturn,
+						title: title,
+						formType: data.formType,
+						formUrl: data.formUrl,
+						formTitle: processTitle,
+						businessTable: 'psi_management_collect_basics_return',
+						businessId: row.returnId,
+						isShow: 'false',
+						status: status,
+						routePath: '/psiManagement/collect/CollectList',
+						returnId: row.returnId
+					}
+				})
+			})
+		},
+		detailReturn(row) {
+			if (this.commonJS.isNotEmpty(row.statusReturn) && row.statusReturn !== '0' && row.statusReturn !== '1') {
+				// eslint-disable-next-line eqeqeq
+				taskService.getTaskDef({
+					procInsId: row.procInsIdReturn,
+					procDefId: this.processDefinitionAuditIdReturn
+				}).then((data) => {
+					this.$router.push({
+						path: '/flowable/task/TaskFormDetail',
+						query: {
+							...pick(data, 'formType', 'formUrl', 'procDefKey', 'taskDefKey', 'procInsId', 'procDefId', 'taskId', 'status', 'title'),
+							isShow: 'false',
+							readOnly: true,
+							title: '领用-退回申请' + '流程详情',
+							formTitle: '领用-退回申请' + '流程详情',
+							businessId: row.returnId,
+							status: 'reback',
+							returnId: row.returnId
+						}
+					})
+				})
+			}
+		},
+		// 撤回退回流程
+		rebackReturn(row) {
+			this.$confirm(`确定要撤回该申请吗?`, '提示', {
+				confirmButtonText: '确定',
+				cancelButtonText: '取消',
+				type: 'warning'
+			}).then(() => {
+				this.collectService.findById(row.id).then((data) => {
+					if (data.statusReturn !== '2') { // status的值不等于“审核中”,就弹出提示
+						this.$message.error('数据已发生改变或不存在,请刷新数据')
+						this.refreshList()
+					} else {
+						processService.revokeProcIns(row.procInsIdReturn).then((data) => {
+							let form = { status: '3', id: row.id }
+							this.collectService.updateStatusByIdReturn(form)
+							this.$message.success(data)
+							this.refreshList()
+						})
+					}
+				})
+			})
+		},
+		returnRequest(row) {
+			this.$confirm(`确定要取消该申请吗?`, '提示', {
+				confirmButtonText: '确定',
+				cancelButtonText: '取消',
+				type: 'warning'
+			}).then(() => {
+				this.collectService.findById(row.id).then((data) => {
+					if (data.statusReturn !== '3') { // status的值不等于“已撤回”,就弹出提示
+						this.$message.error('数据已发生改变或不存在,请刷新数据')
+						this.refreshList()
+					} else {
+						this.collectService.returnRequest({ id: row.id }).then((data) => {
+							this.$message.success(data)
+							this.refreshList()
+						})
+					}
+				})
+			})
+		},
+		// 驳回后调整
+		adjustReturn(row) {
+			this.collectService.findById(row.id).then((data) => {
+				if (data.statusReturn !== '4') { // status的值不等于“驳回”,就弹出提示
+					this.$message.error('数据已发生改变或不存在,请刷新数据')
+					this.refreshList()
+				} else {
+					this.todoReturn(row)
+				}
+			})
+		},
+		// 审核
+		examineReturn(row) {
+			this.collectService.findById(row.id).then((data) => {
+				if (data.statusReturn !== '2') { // status的值不等于“审核中”,就弹出提示
+					this.$message.error('数据已发生改变或不存在,请刷新数据')
+					this.refreshList()
+				} else {
+					this.todoReturn(row)
+				}
+			})
+		},
+		// 审核或重新调整跳转
+		todoReturn(row) {
+			let cUser = false
+			taskService.getTaskDefInfo({
+				taskId: row.taskIdReturn
+			}).then((data) => {
+				this.$router.push({
+					path: '/flowable/task/TaskForm',
+					query: {
+						...pick(data, 'formType', 'formUrl', 'procDefKey', 'taskDefKey', 'procInsId', 'procDefId', 'taskId', 'status', 'title', 'businessId'),
+						isShow: false,
+						formReadOnly: true,
+						formTitle: `${data.taskName}`,
+						cUser: cUser,
+						title: `审批【${data.taskName || ''}】`,
+						routePath: '/psiManagement/collect/CollectList'   // 数据处理后需要跳转的页面路径
+					}
+				})
+			})
+		},
+		// 查询当前登录人是否是数据的审核人
+		checkIsAuditReturn(row) {
+			let loginUserId = this.$store.state.user.id  // 获取当前登录用户id
+			if (this.commonJS.isNotEmpty(row.auditUserIdsReturn)) {
+				for (const userId of row.auditUserIdsReturn) {
+					if (userId === loginUserId) {  // 当数据的审核人中包含当前登录人id时,返回true
+						return true
+					}
+				}
+			}
+			return false
+		},
+		// 导出
+		exportFile() {
+			const options = {
+				filename: `${this.moment(new Date()).format('YYYY-MM-DD')}采购数据导出`,
+				sheetName: '采购数据导出',
+				mode: 'all'
+			}
+			this.loading = true
+			this.collectService.exportFile({
+				current: this.tablePage.currentPage,
+				size: this.tablePage.pageSize,
+				orders: this.tablePage.orders,
+				...options,
+				...this.searchForm
+			}).then((res) => {
+				this.$utils.downloadExcel(res, options.filename)
+				this.loading = false
+			}).catch(() => {
+				this.loading = false
+			})
+		}
+	}
+}
+</script>

+ 903 - 0
src/views/psiManagement/collect/CollectReturnForm.vue

@@ -0,0 +1,903 @@
+<template>
+	<div>
+		<el-form :model="inputForm" ref="inputForm" v-loading="loading" :class="method === 'view' ? 'readonly' : ''"
+			:disabled="status === 'audit' || status === 'taskFormDetail'" label-width="100px" @submit.native.prevent>
+
+			<el-divider content-position="left"><i class="el-icon-document"></i> 基础信息</el-divider>
+			<el-row :gutter="26">
+				<el-col :span="12">
+					<el-form-item label="领用编号" prop="collectNo">
+						<el-input placeholder="自动生成" v-model="inputForm.collectNo" :disabled="true"></el-input>
+					</el-form-item>
+				</el-col>
+				<el-col :span="12">
+					<el-form-item label="经办人" prop="handledBy">
+						<el-input v-model="inputForm.handledBy" :disabled="true"></el-input>
+					</el-form-item>
+				</el-col>
+				<el-col :span="12">
+					<el-form-item label="经办人部门" prop="handledByOffice">
+						<SelectTree :disabled="true" ref="officeTree" :props="{
+							value: 'id',             // ID字段名
+							label: 'name',         // 显示名称
+							children: 'children'    // 子级字段名
+						}" :url="`/system-server/sys/office/treeData?type=2`" :value="inputForm.handledByOffice" :accordion="true"
+							size="default" @getValue="(value) => { inputForm.handledByOffice = value }" />
+						<!--            <el-input v-model="inputForm.handledByOffice" :disabled="true"></el-input>-->
+					</el-form-item>
+				</el-col>
+				<el-col :span="12">
+					<el-form-item label="领用时间" prop="collectDate"
+						:rules="[{ required: true, message: '请选择领用时间', trigger: 'blur' }]">
+						<el-date-picker :disabled="true" v-model="inputForm.collectDate" type="date"
+							placement="bottom-start" value-format="YYYY-MM-DD" style="width: 100%" placeholder="选择日期">
+						</el-date-picker>
+					</el-form-item>
+				</el-col>
+				<el-col :span="24">
+					<el-form-item label="备注" prop="remarks">
+						<el-input v-model="inputForm.remarks" type="textarea" :rows="5" maxlength="500"
+							placeholder="请填写备注信息" :disabled="true" show-word-limit>
+						</el-input>
+					</el-form-item>
+				</el-col>
+			</el-row>
+
+			<el-divider content-position="left"><i class="el-icon-document"></i>
+				领用详情
+			</el-divider>
+			<el-row :gutter="15">
+				<el-col :span="24">
+					<vxe-table border show-footer show-overflow ref="detailTable" class="vxe-table-element"
+						:edit-config="{ trigger: 'click', mode: 'row', showStatus: false, autoClear: !produceDateSelectVisible, icon: '-' }"
+						:edit-rules="validRules" :data="inputForm.recordList" style="margin-left: 5em"
+						:row-class-name="rowClassName">
+						<vxe-table-column field="recipientAgent" title="领用人" align="center" min-width="160">
+							<template #default="scope">
+								<span>{{ scope.row.recipientAgent }}</span>
+								<span v-if="scope.row.isReturn === '1'">(已退回)</span>
+								<span v-else-if="scope.row.isReturn === '2'">(部分退回)</span>
+							</template>
+						</vxe-table-column>
+						<vxe-table-column field="recipientOffice" title="领用人部门" align="center"></vxe-table-column>
+						<vxe-table-column field="collectType" title="领用类型" align="center"></vxe-table-column>
+						<vxe-table-column field="goodsName" title="物品名称" align="center"></vxe-table-column>
+						<vxe-table-column field="produceDate" title="生产日期" align="center"></vxe-table-column>
+						<vxe-table-column field="collectNumber" title="领用数量" align="center">
+							<template #default="scope">
+								<span>{{ scope.row.collectNumber }}</span>
+							</template>
+							<!-- <template v-slot:edit="scope">
+								<el-input v-model="scope.row.collectNumber"
+									@blur="scope.row.collectNumber = twoDecimalPlaces2(scope.row.collectNumber)"
+									maxlength="10"></el-input>
+							</template> -->
+						</vxe-table-column>
+						<vxe-table-column field="surplusStock" title="本次退回数量" align="center" :edit-render="{}">
+							<template v-slot:edit="scope">
+								<el-input :disabled="scope.row.returnedNum == scope.row.collectNumber"
+									v-model="scope.row.surplusStock" @input="handleSurplusStockChange(scope.row)"
+									@blur="scope.row.surplusStock = twoDecimalPlaces2(scope.row.surplusStock)"
+									maxlength="10"></el-input>
+							</template>
+						</vxe-table-column>
+						<vxe-table-column field="returnedNum" title="已退回数量" align="center">
+							<template #default="scope">
+								<span>{{ scope.row.returnedNum }}</span>
+							</template>
+						</vxe-table-column>
+						<vxe-table-column field="notSurplusStock" title="未退回数量" align="center">
+							<template #default="scope">
+								<span>{{ scope.row.notSurplusStock }}</span>
+							</template>
+						</vxe-table-column>
+						<vxe-table-column v-if="status === 'audit'" field="surplusNumber" title="库存数量"
+							align="center"></vxe-table-column>
+						<vxe-table-column field="company" title="单位" align="center"></vxe-table-column>
+						<vxe-table-column field="remarks" title="备注" align="center"></vxe-table-column>
+						<vxe-table-column title="操作" width="170" align="center">
+							<template v-slot="scope">
+								<el-button size="small" type="primary" :disabled="false"
+									@click="seeFileInfo(scope.$rowIndex)">附件</el-button>
+								<!-- <el-button size="small" type="primary"
+									v-if="scope.row.isReturn === '0' && status !== 'audit' && status !== 'taskFormDetail'"
+									@click="returnCollect(scope.$rowIndex)">退回</el-button>
+								<el-button size="small" type="primary"
+									v-if="scope.row.isReturn === '1' && status !== 'audit' && status !== 'taskFormDetail'"
+									@click="cancelReturn(scope.$rowIndex)">取消退回</el-button> -->
+							</template>
+						</vxe-table-column>
+					</vxe-table>
+				</el-col>
+			</el-row>
+			<el-row>
+				<el-col :span="24" style="margin-top: 20px">
+					<el-form-item label="退回原因" prop="returnCause"
+						:rules="[{ required: true, message: '退回原因不能为空', trigger: 'blur' }]">
+						<el-input v-model="inputForm.returnCause" type="textarea" :rows="5" maxlength="500"
+							placeholder="请填写退回原因" show-word-limit>
+						</el-input>
+					</el-form-item>
+				</el-col>
+			</el-row>
+
+		</el-form>
+		<PurchasePageForm ref="purchasePageForm" @getProject="getContract"></PurchasePageForm>
+		<!-- 附件 -->
+		<MaterialManagementDialog ref="materialManagementDialog" @getUpload="getUpload"></MaterialManagementDialog>
+		<UpLoadComponent ref="uploadComponent"></UpLoadComponent>
+		<CwProgramPageForm ref="cwProgramPageForm" @getProgram="getProgram"></CwProgramPageForm>
+		<MaterialTypePullForm ref="materialTypePullForm" @getProgramForType="getProgramForType"></MaterialTypePullForm>
+		<UserPullForm ref="userPullForm" @getProgramForUser="getProgramForUser"></UserPullForm>
+	</div>
+</template>
+
+<script>
+import MaterialManagementDialog from '../file/MaterialManagementDialog'
+import CollectService from '@/api/psi/CollectService'
+import UpLoadComponent from '@/views/common/UpLoadComponent'
+import SelectTree from '@/components/treeSelect/treeSelect.vue'
+import CwProgramPageForm from '@/views/cw/reimbursementApproval/info/CwProgramPageForm'
+import MaterialTypePullForm from '../info/MaterialTypePullForm'
+import UserPullForm from '@/views/finance/invoice/UserPullForm'
+import PurchasePageForm from './PurchasePageForm'
+import CommonApi from '@/api/cw/common/CommonApi'
+export default {
+	data() {
+		return {
+			validRules: {
+				recipientAgent: [
+					{ required: true, message: '领用人不能为空' }
+				],
+				recipientOffice: [
+					{ required: true, message: '领用人部门不能为空' }
+				],
+				collectType: [
+					{ required: true, message: '领用类型不能为空' }
+				],
+				goodsName: [
+					{ required: true, message: '物品名称不能为空' }
+				],
+				collectNumber: [
+					{ required: true, message: '领用数量不能为空' }
+				]
+			},
+			title: '',
+			method: '',
+			visible: false,
+			loading: false,
+			indexRow: '',
+			inputForm: {
+				fileInfoLost: [],
+				handledByOffice: '',
+				handledBy: '',
+				handledById: '',
+				collectNo: '', // 领用编号
+				userId: '',
+				collectDate: '',
+				remarks: '',
+				detailInfos: [],
+				recordList: [],
+				// amountInfos: [],
+				files: [], // 附件信息
+				procInsId: '',
+				statusReturn: '',
+				procInsIdReturn: '',
+				processDefinitionIdReturn: '',
+				returnId: '',
+				returnCause: '',
+				returnFiles: []
+			},
+			keyWatch: ''
+		}
+	},
+	collectService: null,
+	commonApi: null,
+	created() {
+		this.collectService = new CollectService()
+		this.commonApi = new CommonApi()
+	},
+	props: {
+		businessId: {
+			type: String,
+			default: ''
+		},
+		formReadOnly: {
+			type: Boolean,
+			default: false
+		},
+		status: {
+			type: String,
+			default: ''
+		}
+	},
+	components: {
+		MaterialManagementDialog,
+		UpLoadComponent,
+		SelectTree,
+		CwProgramPageForm,
+		MaterialTypePullForm,
+		UserPullForm,
+		PurchasePageForm
+	},
+	computed: {
+		bus: {
+			get() {
+				return this.businessId
+			},
+			set(val) {
+				this.businessId = val
+			}
+		},
+		name() {
+			return this.$store.state.user.name
+		},
+		officeName() {
+			return this.$store.state.user.office.name
+		},
+		userId() {
+			return this.$store.state.user.id
+		},
+		recipientAgentId() {
+			return this.$store.state.user.id
+		},
+		collectTypeId() {
+			return ''
+		}
+	},
+	watch: {
+		'keyWatch': {
+			handler(newVal) {
+				if (this.commonJS.isNotEmpty(this.bus)) {
+					this.init('', this.bus)
+				} else {
+					this.$nextTick(() => {
+						this.$refs.inputForm.resetFields()
+					})
+				}
+			}
+		},
+		'loading': {
+			handler(newVal) {
+				this.$emit('changeLoading', newVal)
+				this.$refs.uploadComponent.changeLoading(newVal)
+			}
+		}
+	},
+	methods: {
+		getKeyWatch(keyWatch) {
+			this.keyWatch = keyWatch
+		},
+		init(method, id) {
+			this.method = method
+			this.inputForm = {
+				fileInfoLost: [],
+				handledByOffice: '',
+				handledBy: this.$store.state.user.name,
+				handledById: this.$store.state.user.id,
+				collectNo: '', // 领用编号
+				userId: this.$store.state.user.id,
+				collectDate: new Date(),
+				remarks: '',
+				detailInfos: [],
+				recordList: [],
+				// amountInfos: [],
+				files: [], // 附件信息
+				procInsId: '',
+				statusReturn: '',
+				procInsIdReturn: '',
+				processDefinitionIdReturn: '',
+				returnId: '',
+				returnCause: '',
+				returnFiles: []
+			}
+			if (method === 'add') {
+				this.title = `新建领用类型`
+			} else if (method === 'edit') {
+				this.title = '修改领用类型'
+			}
+			this.inputForm.id = id
+			this.visible = true
+			this.loading = false
+			this.$nextTick(() => {
+				if (this.commonJS.isEmpty(this.inputForm.handledByOffice)) {
+					this.inputForm.handledByOffice = this.$store.state.user.office.id
+				}
+				if (this.status === 'audit' || this.status === 'taskFormDetail') {
+					method = 'view'
+				} else {
+					method = 'edit'
+				}
+				this.loading = true
+				this.$refs.inputForm.resetFields()
+				this.collectService.findByReturnId(this.inputForm.id).then((data) => {
+					this.$refs.uploadComponent.clearUpload()
+					if (this.inputForm.id !== 'false') {
+						this.inputForm = this.recover(this.inputForm, data)
+						this.inputForm = JSON.parse(JSON.stringify(this.inputForm))
+						if (this.commonJS.isEmpty(this.inputForm.handledByOffice)) {
+							this.inputForm.handledByOffice = this.$store.state.user.office.id
+						}
+						if (this.commonJS.isNotEmpty(data.recipientAgentId)) {
+							this.recipientAgentId = data.recipientAgentId
+						}
+						if (this.commonJS.isNotEmpty(data.collectTypeId)) {
+							this.collectTypeId = data.collectTypeId
+						}
+						if (this.commonJS.isNotEmpty(this.inputForm.detailInfos)) {
+							let i = this.inputForm.detailInfos.length
+							for (let j = 0; j < i; j++) {
+								if (this.commonJS.isNotEmpty(this.inputForm.detailInfos[j].tradePrice)) {
+									if (this.commonJS.isNotEmpty(this.inputForm.detailInfos[j].tradeNumber)) {
+										this.inputForm.detailInfos[j].priceSum = this.inputForm.detailInfos[j].tradePrice * this.inputForm.detailInfos[j].tradeNumber
+									}
+								}
+							}
+						}
+						if (this.commonJS.isNotEmpty(this.inputForm.recordList)) {
+							this.inputForm.recordList.forEach(item => {
+								if (item.surplusStock) {
+									item.surplusStockBak = item.surplusStock
+									item.notSurplusStockBak = item.notSurplusStock
+									item.returnedNumBak = item.returnedNum
+								}
+							})
+						}
+						console.log(this.inputForm, data)
+						if (this.commonJS.isEmpty(this.inputForm.returnFiles)) {
+							this.inputForm.returnFiles = []
+						}
+						this.$refs.uploadComponent.newUpload(method, this.inputForm.returnFiles, 'collect_return')
+						this.inputForm = JSON.parse(JSON.stringify(this.inputForm))
+						this.loading = false
+					} else {
+						if (this.commonJS.isEmpty(this.inputForm.handledByOffice)) {
+							this.inputForm.handledByOffice = this.$store.state.user.office.id
+						}
+						if (this.commonJS.isEmpty(this.inputForm.handledBy)) {
+							this.inputForm.handledBy = this.$store.state.user.name
+						}
+						if (this.commonJS.isEmpty(this.inputForm.handledById)) {
+							this.inputForm.handledById = this.$store.state.user.id
+						}
+						if (this.commonJS.isEmpty(this.inputForm.collectDate)) {
+							this.inputForm.collectDate = new Date()
+						}
+						this.inputForm.detailInfos = []
+						this.inputForm.recordList = []
+						this.loading = false
+					}
+				})
+			})
+		},
+		getUpload(p, index) {
+			p.then((list) => {
+				// list为返回数据
+				this.inputForm.detailInfos[index].fileInfoLost = list
+				this.inputForm.detailInfos[index].fileNumber = list.length
+				this.tableKeyClient = Math.random()
+			})
+		},
+		seeFileInfo(index) {
+			if (this.commonJS.isEmpty(this.inputForm.detailInfos[index].fileInfoLost)) {
+				this.inputForm.detailInfos[index].fileInfoLost = []
+			}
+			this.$refs.materialManagementDialog.newUpload('view', this.inputForm.detailInfos[index].fileInfoLost, null, null, null, null, null, false, index)
+		},
+		sss(index) {
+			if (this.commonJS.isEmpty(this.inputForm.detailInfos[index].fileInfoLost)) {
+				this.inputForm.detailInfos[index].fileInfoLost = []
+			}
+			this.$refs.materialManagementDialog.newUpload(null, this.inputForm.detailInfos[index].fileInfoLost, null, null, null, null, null, false, index)
+		},
+		// 表单提交
+		doSubmit() {
+			this.$refs['inputForm'].validate((valid) => {
+				if (valid) {
+					this.loading = true
+					if (this.$refs.uploadComponent.checkProgress()) {
+						this.loading = false
+						return
+					}
+					if (this.commonJS.isEmpty(this.inputForm.files)) {
+						this.inputForm.files = []
+					}
+					this.inputForm.id = this.businessId
+					this.inputForm.files = this.$refs.uploadComponent.getDataList()
+					this.collectService.save(this.inputForm).then((data) => {
+						this.close()
+						this.$message.success(data)
+						this.$emit('refreshDataList')
+						this.loading = false
+					}).catch(() => {
+						this.loading = false
+					})
+				}
+			})
+		},
+		close() {
+			this.inputForm.detailInfos = []
+			// this.inputForm.amountInfos = []
+			this.$refs.uploadComponent.clearUpload()
+
+			this.visible = false
+			this.$refs.inputForm.resetFields()
+		},
+		// 删除
+		removeEvent(row, rowIndex, type) {
+			if (type === 'detail') {
+				this.$refs.detailTable.remove(row)
+				this.inputForm.detailInfos.splice(rowIndex, 1)
+			}
+			if (type === 'amount') {
+				this.$refs.amountTable.remove(row)
+				// this.inputForm.amountInfos.splice(rowIndex, 1)
+			}
+		},
+		// 新增
+		async insertEvent(type) {
+			if (type === 'detail') {
+				await this.$refs.detailTable.insert().then((data) => {
+					data.recipientAgent = this.$store.state.user.name
+					data.recipientAgentId = this.recipientAgentId
+					data.recipientOffice = this.officeName
+					this.inputForm.detailInfos.push(data)
+				})
+			}
+			if (type === 'amount') {
+				await this.$refs.amountTable.insert().then((data) => {
+					// this.inputForm.amountInfos.push(data)
+				})
+			}
+		},
+		reapplyForm(callback) {
+			this.loading = true
+			this.collectService.findById(this.inputForm.id).then((data) => {
+				if (data.statusReturn !== '4') { // 审核状态不是“驳回”,就弹出提示
+					this.loading = false
+					this.$message.error('任务数据已发生改变或不存在,请在待办任务中确认此任务是否存在')
+					throw new Error('任务数据已发生改变或不存在,请在待办任务中确认此任务是否存在')
+				} else {
+					this.startFormTrue(callback)
+				}
+			})
+		},
+		startForm(callback) {
+			this.loading = true
+			if (this.commonJS.isNotEmpty(this.inputForm.id)) {
+				this.collectService.findById(this.inputForm.id).then((data) => {
+					// 审核状态不是“未发起”或“暂存”或“撤回”,就弹出提示
+					if (this.commonJS.isNotEmpty(data.statusReturn) && data.statusReturn !== '0' && data.statusReturn !== '1' && data.statusReturn !== '3' && data.statusReturn !== '5') {
+						this.loading = false
+						this.$message.error('任务数据已发生改变或不存在,请在待办任务中确认此任务是否存在')
+						throw new Error('任务数据已发生改变或不存在,请在待办任务中确认此任务是否存在')
+					} else {
+						this.startFormTrue(callback)
+					}
+				})
+			} else {
+				this.startFormTrue(callback)
+			}
+		},
+		// 暂存
+		async saveForm(callback) {
+			this.loading = true
+			if (this.$refs.uploadComponent.checkProgress()) {
+				this.loading = false
+				return
+			}
+			if (this.commonJS.isEmpty(this.inputForm.returnFiles)) {
+				this.inputForm.returnFiles = []
+			}
+
+			this.inputForm.returnFiles = this.$refs.uploadComponent.getDataList()
+			this.inputForm.statusReturn = '1'
+			this.collectService.saveReturn(this.inputForm).then((data) => {
+				callback()
+				this.$refs.inputForm.resetFields()
+				this.loading = false
+			}).catch(() => {
+				this.$refs.inputForm.resetFields()
+				this.loading = false
+			})
+		},
+		// 送审
+		async startFormTrue(callback) {
+			this.loading = true
+			this.$refs['inputForm'].validate(async (valid) => {
+				if (valid) {
+					this.loading = true
+					if (this.$refs.uploadComponent.checkProgress()) {
+						this.loading = false
+						return
+					}
+					if (this.commonJS.isEmpty(this.inputForm.returnFiles)) {
+						this.inputForm.returnFiles = []
+					}
+					if (this.commonJS.isEmpty(this.inputForm.detailInfos)) {
+						this.$message.error('至少填写一条领用详情信息')
+						this.loading = false
+						return
+					} else {
+						let i = this.inputForm.detailInfos.length
+						for (let j = 0; j < i; j++) {
+							let k = j + 1
+							if (this.commonJS.isEmpty(this.inputForm.detailInfos[j].recipientAgent)) {
+								this.$message.error('领用详情第' + k + '行请选择领用人')
+								this.loading = false
+								return
+							}
+							if (this.commonJS.isEmpty(this.inputForm.detailInfos[j].collectType)) {
+								this.$message.error('领用详情第' + k + '行请选择领用类型')
+								this.loading = false
+								return
+							}
+							if (this.commonJS.isEmpty(this.inputForm.detailInfos[j].goodsName)) {
+								this.$message.error('领用详情第' + k + '行请选择物品名称')
+								this.loading = false
+								return
+							}
+							if (this.commonJS.isEmpty(this.inputForm.detailInfos[j].collectNumber)) {
+								this.$message.error('领用详情第' + k + '行请输入领用数量')
+								this.loading = false
+								return
+							}
+						}
+
+					}
+					this.inputForm.returnFiles = this.$refs.uploadComponent.getDataList()
+					this.inputForm.statusReturn = '2'
+					this.collectService.saveReturn(this.inputForm).then((data) => {
+						this.inputForm.id = data.businessId
+						callback(data.businessTable, data.businessId, this.inputForm)
+						this.$refs.inputForm.resetFields()
+						this.loading = false
+					}).catch(() => {
+						this.$refs.inputForm.resetFields()
+						this.loading = false
+					})
+				} else {
+					this.loading = false
+				}
+			})
+		},
+		// 通过
+		async agreeForm(callback) {
+			this.loading = true
+			this.$refs['inputForm'].validate(async (valid) => {
+				if (valid) {
+					this.loading = true
+					if (this.$refs.uploadComponent.checkProgress()) {
+						this.loading = false
+						return
+					}
+					if (this.commonJS.isEmpty(this.inputForm.returnFiles)) {
+						this.inputForm.returnFiles = []
+					}
+					this.inputForm.returnFiles = this.$refs.uploadComponent.getDataList()
+					// this.commonApi.getTaskNameByProcInsId(this.inputForm.procInsId).then((data) => {
+					//   if (this.commonJS.isNotEmpty(data)) {
+					//     if (data === '仓库管理员审核') {
+					//       this.inputForm.status = '5'
+					//     }
+					//   }
+					//   this.collectService.save(this.inputForm).then((data) => {
+					//     callback(data.businessTable, data.businessId, this.inputForm)
+					//     this.loading = false
+					//   }).catch(() => {
+					//     this.loading = false
+					//   })
+					// })
+					this.inputForm.statusReturn = '5'
+					this.collectService.saveReturnAgree(this.inputForm).then((data) => {
+						callback(data.businessTable, data.businessId, this.inputForm)
+						this.loading = false
+					}).catch(() => {
+						this.loading = false
+					})
+				} else {
+					this.loading = false
+				}
+			})
+		},
+		// 修改状态
+		async updateStatusById(type, callback) {
+			this.loading = true
+			if (await this.$refs.uploadComponent.checkProgress()) {
+				this.loading = false
+				throw new Error()
+			} else {
+				if (type === 'reject' || type === 'reback') {
+					this.collectService.findById(this.inputForm.id).then((data) => {
+						if (data.statusReturn !== '2') { // status的值不等于“审核中”,就弹出提示
+							this.loading = false
+							this.$message.error('任务数据已发生改变或不存在,请在待办任务中确认此任务是否存在')
+							throw new Error()
+						} else {
+							if (type === 'reject') {
+								// 驳回
+								this.inputForm.statusReturn = '4'
+							}
+							if (type === 'reback') {
+								// 撤回
+								this.inputForm.statusReturn = '3'
+							}
+							if (type === 'reject' || type === 'reback') {
+								let param = { status: this.inputForm.statusReturn, id: this.inputForm.id }
+								this.collectService.updateStatusByIdReturn(param).then(() => {
+									this.loading = false
+									callback()
+								})
+							}
+						}
+					})
+				} else if (type === 'hold') {
+					this.collectService.findById(this.inputForm.id).then((data) => {
+						if (data.statusReturn !== '4') { // status的值不等于“驳回”就弹出提示
+							this.loading = false
+							this.$message.error('任务数据已发生改变或不存在,请在待办任务中确认此任务是否存在')
+							throw new Error()
+						} else {
+							// 终止
+							this.collectService.returnRequest({ id: this.inputForm.id }).then((data) => {
+								this.loading = false
+								callback()
+							})
+							// 终止
+							// let param = {status: '0', id: this.inputForm.id}
+							// this.collectService.updateStatusByIdReturn(param).then(() => {
+							//   this.loading = false
+							//   callback()
+							// })
+						}
+					})
+				}
+			}
+		},
+		// updateStatusById (type) {
+		//   if (type === 'reject') {
+		//     this.inputForm.status = '4'
+		//     this.collectService.updateStatusById(this.inputForm)
+		//   }
+		// },
+		// footerMethod ({ columns, data }) {
+		//   const footerData = [
+		//     columns.map((column, columnIndex) => {
+		//       if (columnIndex === 0) {
+		//         return '商品总价'
+		//       }
+		//       if (['priceSum'].includes(column.property)) {
+		//         // eslint-disable-next-line no-undef
+		//         this.inputForm.tradeTotalPrice = XEUtils.sum(data, column.property)
+		//         return XEUtils.sum(data, column.property)
+		//       }
+		//       return null
+		//     })
+		//   ]
+		//   return footerData
+		// },
+		// twoDecimalPlaces (num, index) {
+		//   let str = num.toString()
+		//   var len1 = str.substr(0, 1)
+		//   var len2 = str.substr(1, 1)
+		//   // eslint-disable-next-line eqeqeq
+		//   if (str.length > 1 && len1 == 0 && len2 != '.') {
+		//     str = str.substr(1, 1)
+		//   }
+		//   // eslint-disable-next-line eqeqeq
+		//   if (len1 == '.') {
+		//     str = ''
+		//   }
+		//   // eslint-disable-next-line eqeqeq
+		//   if (str.indexOf('.') != -1) {
+		//     var str_ = str.substr(str.indexOf('.') + 1)
+		//     // eslint-disable-next-line eqeqeq
+		//     if (str_.indexOf('.') != -1) {
+		//       str = str.substr(0, str.indexOf('.') + str_.indexOf('.') + 1)
+		//     }
+		//     if (str_.length > 2) {
+		//       this.$message.warning(`金额小数点后只能输入两位,请正确输入!`)
+		//       return (str = '')
+		//     }
+		//   }
+		//   // eslint-disable-next-line no-useless-escape
+		//   this.inputForm.detailInfos[index].priceSum = str.replace(/[^\d^\.]+/g, '') // 保留数字和小数点
+		// },
+		twoDecimalPlaces2(num) {
+			let str = num.toString()
+			var len1 = str.substr(0, 1)
+			var len2 = str.substr(1, 1)
+			// eslint-disable-next-line eqeqeq
+			if (str.length > 1 && len1 == 0 && len2 != '.') {
+				str = str.substr(1, 1)
+			}
+			// eslint-disable-next-line eqeqeq
+			if (len1 == '.') {
+				str = ''
+			}
+			// eslint-disable-next-line eqeqeq
+			if (str.indexOf('.') != -1) {
+				var str_ = str.substr(str.indexOf('.') + 1)
+				// eslint-disable-next-line eqeqeq
+				if (str_.indexOf('.') != -1) {
+					str = str.substr(0, str.indexOf('.') + str_.indexOf('.') + 1)
+				}
+				if (str_.length > 2) {
+					this.$message.warning(`领用数量小数点后只能输入两位,请正确输入!`)
+					return (str = '')
+				}
+			}
+			// eslint-disable-next-line no-useless-escape
+			str = str.replace(/[^\d^\.]+/g, '') // 保留数字和小数点
+			return str
+		},
+		// 自动计算:surplusStock = collectNumber - 输入的数字
+		handleSurplusStockChange(row) {
+			//完善判断。如果退回数量超过领用数量,弹出提示并清空输入框
+			if (parseInt(row.surplusStock) < 0) {
+				this.$message.error('退回数量不能小于0')
+				row.surplusStock = row.surplusStockBak || '0'
+				return
+			}
+			//完善判断。如果退回数量超过领用数量,弹出提示并清空输入框
+			if (parseInt(row.surplusStock) > parseInt(row.notSurplusStockBak)) {
+				this.$message.error('退回数量不能大于未退回数量')
+				row.surplusStock = row.surplusStockBak || '0'
+				return
+			}
+			//如果输入的退回数量不是数字,弹出提示并清空输入框
+			if (isNaN(parseInt(row.surplusStock))) {
+				this.$message.error('请输入有效的退回数量')
+				row.surplusStock = row.surplusStockBak || '0'
+				return
+			}
+
+			if (parseInt(row.notSurplusStock) && parseInt(row.returnedNum) && parseInt(row.returnedNum) != '0' && parseInt(row.notSurplusStock) != '0') {
+				if ((parseInt(row.surplusStock) + parseInt(row.returnedNum)) == parseInt(row.collectNumber)) {
+					console.log("走1");
+					row.isReturn = '1' // 已退回
+				} else if (parseInt(row.surplusStock) == '0') {
+					console.log("走2");
+					row.isReturn = '0' // 未退回
+				} else {
+					console.log("走3");
+					row.isReturn = '2' // 部分退回
+				}
+			} else {
+				// 如果输入的退回数量等于领用数量,将isReturn设置为1(已退回),否则设置为2(部分退回)
+				if (parseInt(row.surplusStock) === parseInt(row.collectNumber)) {
+					row.isReturn = '1' // 已退回
+				} else if (parseInt(row.surplusStock) < parseInt(row.notSurplusStock)) {
+					row.isReturn = '2' // 部分退回
+				} else if (parseInt(row.surplusStock) == '0') {
+					row.isReturn = '0' // 未退回
+				}
+			}
+		},
+		countAmount(row) {
+			let amount
+			let taxAmount
+			let count = 0
+			if (!this.commonJS.isEmpty(row.amount)) {
+				amount = parseFloat(row.amount)
+				count = count + amount
+			}
+			if (!this.commonJS.isEmpty(row.taxAmount)) {
+				taxAmount = parseFloat(row.taxAmount)
+				count = count + taxAmount
+			}
+			row.count = parseFloat(count).toFixed(2)
+		},
+		getProgram(rows) {
+			this.inputForm.detailInfos[this.indexRow].projectId = rows[0].id
+			this.inputForm.detailInfos[this.indexRow].projectName = rows[0].name
+			this.inputForm.detailInfos[this.indexRow].reportNumber = rows[0].reportNo
+			this.indexRow = ''
+			this.$forceUpdate()
+		},
+		// 领用类型下拉弹窗
+		typePullForm(rowIndex) {
+			this.indexRow = rowIndex
+			this.$refs.materialTypePullForm.init()
+		},
+		getProgramForType(rows) {
+			this.inputForm.detailInfos[this.indexRow].collectTypeId = rows.id
+			this.inputForm.detailInfos[this.indexRow].collectType = rows.name
+			this.inputForm.detailInfos[this.indexRow].goodsName = ''
+			this.indexRow = ''
+			this.$forceUpdate()
+		},
+		// 领用人下拉弹窗
+		userPullListForm(rowIndex) {
+			this.indexRow = rowIndex
+			this.$refs.userPullForm.init()
+		},
+		getProgramForUser(rows) {
+			this.inputForm.detailInfos[this.indexRow].recipientAgentId = rows[0].id
+			this.inputForm.detailInfos[this.indexRow].recipientAgent = rows[0].name
+			this.inputForm.detailInfos[this.indexRow].deptId = rows[0].parentId
+			this.inputForm.detailInfos[this.indexRow].recipientOffice = rows[0].officeName
+			this.indexRow = ''
+			this.$forceUpdate()
+		},
+		getUserInfo(rows) {
+		},
+		openPurchasePageForm(rowIndex, row) {
+			if (this.commonJS.isEmpty(row.collectType)) {
+				this.$message.error('请选择领用类型')
+				return
+			}
+			this.indexRow = rowIndex
+			this.$refs.purchasePageForm.init(row.collectTypeId)
+		},
+		getContract(row) {
+			this.inputForm.detailInfos[this.indexRow].surplusNumber = row.tradeNumber
+			this.inputForm.detailInfos[this.indexRow].goodsName = row.tradeName
+			// 去除重复的领用详情
+			let i = this.inputForm.detailInfos.length
+			for (let j = 0; j < i; j++) {
+				for (let k = j + 1; k < i; k++) {
+					if (this.inputForm.detailInfos[j].collectTypeId === this.inputForm.detailInfos[k].collectTypeId) {
+						if (this.commonJS.isNotEmpty(this.inputForm.detailInfos[j].goodsName) &&
+							this.commonJS.isNotEmpty(this.inputForm.detailInfos[k].goodsName) && this.inputForm.detailInfos[j].goodsName === this.inputForm.detailInfos[k].goodsName) {
+							// parseFloat(item.account).toFixed(2)
+							this.inputForm.detailInfos.splice(k, 1)
+							this.$message.warning(`同种领用类型的商品名称只能输入一条信息!`)
+						}
+					}
+				}
+			}
+			this.indexRow = ''
+			this.$forceUpdate()
+		},
+
+		// 退回
+		returnCollect(index) {
+			this.inputForm.recordList[index].isReturn = '1'
+		},
+		// 取消退回
+		cancelReturn(index) {
+			this.inputForm.recordList[index].isReturn = '0'
+		},
+		// 列表行颜色
+		rowClassName({ row, rowIndex }) {
+			if (row.isReturn === '1') { // 退回
+				return 'row-grey'
+			} else if (row.isReturn === '2') { // 部分退回
+				return 'row-warning'
+			} else { // 未退回
+				return ''
+			}
+		}
+	}
+}
+</script>
+<style scoped>
+.el-divider__text {
+	font-size: 16px;
+	font-weight: bold;
+}
+
+/deep/ .row-green {
+	/*background-color: #67c23ad1;*/
+	/*color: #fff;*/
+	font-weight: bold;
+}
+
+/deep/ .row-grey {
+	background-color: #b8b7b7;
+	color: #fff;
+}
+
+/* 警告黄色 透明度*/
+/deep/ .row-warning {
+	background-color: rgba(249, 47, 47, 0.5);
+	color: #fff;
+}
+
+/deep/ .row-red {
+	background-color: #f56c6c66;
+	/*color: #fff;*/
+	font-weight: bold;
+}
+</style>

+ 851 - 0
src/views/psiManagement/collect/CollectReturnHiForm.vue

@@ -0,0 +1,851 @@
+<template>
+  <div>
+    <el-dialog
+      :title="title"
+      :close-on-click-modal="false"
+	  draggable
+      append-to-body
+      width="1300px"
+      @close="close"
+      v-model="visible">
+    <el-form :model="inputForm" ref="inputForm" v-loading="loading" :class="method==='view'?'readonly':''"  :disabled="status === 'audit' || status === 'taskFormDetail'"
+             label-width="100px" @submit.native.prevent>
+
+      <el-divider content-position="left"><i class="el-icon-document"></i> 基础信息</el-divider>
+      <el-row :gutter="26">
+        <el-col :span="12">
+          <el-form-item label="领用编号" prop="collectNo">
+            <el-input placeholder="自动生成" v-model="inputForm.collectNo" :disabled="true"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="经办人" prop="handledBy">
+            <el-input v-model="inputForm.handledBy" :disabled="true"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="经办人部门" prop="handledByOffice">
+            <SelectTree
+              :disabled="true"
+              ref="officeTree"
+              :props="{
+                  value: 'id',             // ID字段名
+                  label: 'name',         // 显示名称
+                  children: 'children'    // 子级字段名
+                }"
+
+              :url="`/system-server/sys/office/treeData?type=2`"
+              :value="inputForm.handledByOffice"
+              :accordion="true"
+              size="default"
+              @getValue="(value) => {inputForm.handledByOffice=value}"/>
+<!--            <el-input v-model="inputForm.handledByOffice" :disabled="true"></el-input>-->
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="领用时间" prop="collectTime" :rules="[{required: true, message:'请选择领用时间', trigger:'blur'}]">
+            <el-date-picker
+              :disabled="true"
+              v-model="inputForm.collectDate"
+              type="date"
+              placement="bottom-start"
+              value-format="YYYY-MM-DD"
+              style="width: 100%"
+              placeholder="选择日期">
+            </el-date-picker>
+          </el-form-item>
+        </el-col>
+        <el-col :span="24">
+          <el-form-item label="备注" prop="remarks">
+            <el-input v-model="inputForm.remarks"
+                      type="textarea"
+                      :rows="5"
+                      maxlength="500"
+                      placeholder="请填写备注信息"
+                      :disabled="true"
+                      show-word-limit>
+            </el-input>
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+      <el-divider content-position="left"><i class="el-icon-document"></i>
+        领用详情
+      </el-divider>
+      <el-row  :gutter="15" >
+        <el-col :span="24">
+			<vxe-table
+				border
+				show-footer
+				show-overflow
+				ref="detailTable"
+				class="vxe-table-element"
+				:data="inputForm.detailInfos"
+				style="margin-left: 5em"
+				:row-class-name="rowClassName"
+			>
+				<vxe-table-column field="recipientAgent" title="领用人" align="center">
+					<template #default="scope">
+						<span>{{scope.row.recipientAgent}}</span><span v-if="scope.row.isReturn === '1'">(已退回)</span>
+					</template>
+				</vxe-table-column>
+				<vxe-table-column field="recipientOffice" title="领用人部门" align="center"></vxe-table-column>
+				<vxe-table-column field="collectType" title="领用类型" align="center"></vxe-table-column>
+				<vxe-table-column field="goodsName" title="物品名称" align="center"></vxe-table-column>
+				<vxe-table-column field="collectNumber" title="领用数量" align="center"></vxe-table-column>
+				<vxe-table-column field="surplusNumber" title="库存数量" align="center"></vxe-table-column>
+				<vxe-table-column field="company" title="单位" align="center"></vxe-table-column>
+				<vxe-table-column field="remarks" title="备注" align="center"></vxe-table-column>
+				<vxe-table-column title="操作" width="170" align="center">
+					<template #default="scope">
+						<el-button type="primary" :disabled="false" @click="seeFileInfo(scope.$rowIndex)">附件</el-button>
+					</template>
+				</vxe-table-column>
+			</vxe-table>
+		</el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="24" style="margin-top: 20px">
+          <el-form-item label="退回原因" prop="returnCause">
+            <el-input v-model="inputForm.returnCause"
+                      type="textarea"
+                      :rows="5"
+                      maxlength="500"
+                      placeholder="请填写退回原因"
+                      :disabled="true"
+                      show-word-limit>
+            </el-input>
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+    </el-form>
+    <PurchasePageForm  ref="purchasePageForm" @getProject="getContract"></PurchasePageForm>
+    <!-- 附件 -->
+    <MaterialManagementDialog ref="materialManagementDialog" @getUpload="getUpload"></MaterialManagementDialog>
+    <UpLoadComponent ref="uploadComponent"></UpLoadComponent>
+    <CwProgramPageForm ref="cwProgramPageForm" @getProgram="getProgram"></CwProgramPageForm>
+    <MaterialTypePullForm ref="materialTypePullForm" @getProgramForType="getProgramForType"></MaterialTypePullForm>
+    <UserPullForm ref="userPullForm" @getProgramForUser="getProgramForUser"></UserPullForm>
+      <template #footer>
+		  <span class="dialog-footer">
+			  <el-button  @click="close()" icon="el-icon-circle-close">关闭</el-button>
+		  </span>
+	  </template>
+
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+  import MaterialManagementDialog from '../file/MaterialManagementDialog'
+  import CollectService from '@/api/psi/CollectService'
+  import UpLoadComponent from '@/views/common/UpLoadComponent'
+  import SelectTree from '@/components/treeSelect/treeSelect.vue'
+  import CwProgramPageForm from '@/views/cw/reimbursementApproval/info/CwProgramPageForm'
+  import MaterialTypePullForm from '../info/MaterialTypePullForm'
+  import UserPullForm from '@/views/finance/invoice/UserPullForm'
+  import PurchasePageForm from './PurchasePageForm'
+  import CommonApi from '@/api/cw/common/CommonApi'
+  export default {
+    data () {
+      return {
+        validRules: {
+          recipientAgent: [
+            {required: true, message: '领用人不能为空'}
+          ],
+          recipientOffice: [
+            {required: true, message: '领用人部门不能为空'}
+          ],
+          collectType: [
+            {required: true, message: '领用类型不能为空'}
+          ],
+          goodsName: [
+            {required: true, message: '物品名称不能为空'}
+          ],
+          collectNumber: [
+            {required: true, message: '领用数量不能为空'}
+          ]
+        },
+        title: '',
+        method: '',
+        visible: false,
+        loading: false,
+        indexRow: '',
+        inputForm: {
+          fileInfoLost: [],
+          handledByOffice: '',
+          handledBy: '',
+          handledById: '',
+          collectNo: '', // 领用编号
+          userId: '',
+          collectDate: '',
+          remarks: '',
+          detailInfos: [],
+          // amountInfos: [],
+          files: [], // 附件信息
+          procInsId: '',
+          statusReturn: '',
+          procInsIdReturn: '',
+          processDefinitionIdReturn: '',
+          returnId: '',
+          returnCause: '',
+          returnFiles: []
+        },
+        keyWatch: ''
+      }
+    },
+    collectService: null,
+    commonApi: null,
+    created () {
+      this.collectService = new CollectService()
+      this.commonApi = new CommonApi()
+    },
+    props: {
+      businessId: {
+        type: String,
+        default: ''
+      },
+      formReadOnly: {
+        type: Boolean,
+        default: false
+      },
+      status: {
+        type: String,
+        default: ''
+      }
+    },
+    components: {
+      MaterialManagementDialog,
+      UpLoadComponent,
+      SelectTree,
+      CwProgramPageForm,
+      MaterialTypePullForm,
+      UserPullForm,
+      PurchasePageForm
+    },
+    computed: {
+      bus: {
+        get () {
+          return this.businessId
+        },
+        set (val) {
+          this.businessId = val
+        }
+      },
+      name () {
+        return this.$store.state.user.name
+      },
+      officeName () {
+        return this.$store.state.user.office.name
+      },
+      userId () {
+        return this.$store.state.user.id
+      },
+      recipientAgentId () {
+        return this.$store.state.user.id
+      },
+      collectTypeId () {
+        return ''
+      }
+    },
+    watch: {
+      'keyWatch': {
+        handler (newVal) {
+          if (this.commonJS.isNotEmpty(this.bus)) {
+            this.init('', this.bus)
+          } else {
+            this.$nextTick(() => {
+              this.$refs.inputForm.resetFields()
+            })
+          }
+        }
+      },
+      'loading': {
+        handler (newVal) {
+          this.$emit('changeLoading', newVal)
+          this.$refs.uploadComponent.changeLoading(newVal)
+        }
+      }
+    },
+    methods: {
+      getKeyWatch (keyWatch) {
+        this.keyWatch = keyWatch
+      },
+      init (id) {
+        let method = 'view'
+        this.method = method
+        this.inputForm = {
+          fileInfoLost: [],
+          handledByOffice: '',
+          handledBy: this.$store.state.user.name,
+          handledById: this.$store.state.user.id,
+          collectNo: '', // 领用编号
+          userId: this.$store.state.user.id,
+          collectDate: new Date(),
+          remarks: '',
+          detailInfos: [],
+          // amountInfos: [],
+          files: [], // 附件信息
+          procInsId: '',
+          statusReturn: '',
+          procInsIdReturn: '',
+          processDefinitionIdReturn: '',
+          returnId: '',
+          returnCause: '',
+          returnFiles: []
+        }
+        this.title = '领用退回历史详情'
+        this.inputForm.id = id
+        this.visible = true
+        this.loading = false
+        this.$nextTick(() => {
+          if (this.commonJS.isEmpty(this.inputForm.handledByOffice)) {
+            this.inputForm.handledByOffice = this.$store.state.user.office.id
+          }
+          if (this.status === 'audit' || this.status === 'taskFormDetail') {
+            method = 'view'
+          }
+          this.loading = true
+          this.$refs.inputForm.resetFields()
+          this.collectService.findHiByHiId(this.inputForm.id).then((data) => {
+            this.$refs.uploadComponent.clearUpload()
+            if (this.inputForm.id !== 'false') {
+              this.inputForm = this.recover(this.inputForm, data)
+              this.inputForm = JSON.parse(JSON.stringify(this.inputForm))
+              if (this.commonJS.isEmpty(this.inputForm.handledByOffice)) {
+                this.inputForm.handledByOffice = this.$store.state.user.office.id
+              }
+              if (this.commonJS.isNotEmpty(data.recipientAgentId)) {
+                this.recipientAgentId = data.recipientAgentId
+              }
+              if (this.commonJS.isNotEmpty(data.collectTypeId)) {
+                this.collectTypeId = data.collectTypeId
+              }
+              if (this.commonJS.isNotEmpty(this.inputForm.detailInfos)) {
+                let i = this.inputForm.detailInfos.length
+                for (let j = 0; j < i; j++) {
+                  if (this.commonJS.isNotEmpty(this.inputForm.detailInfos[j].tradePrice)) {
+                    if (this.commonJS.isNotEmpty(this.inputForm.detailInfos[j].tradeNumber)) {
+                      this.inputForm.detailInfos[j].priceSum = this.inputForm.detailInfos[j].tradePrice * this.inputForm.detailInfos[j].tradeNumber
+                    }
+                  }
+                }
+              }
+              if (this.commonJS.isEmpty(this.inputForm.returnFiles)) {
+                this.inputForm.returnFiles = []
+              }
+              this.$refs.uploadComponent.newUpload('view', this.inputForm.returnFiles, 'collect_return')
+              this.inputForm = JSON.parse(JSON.stringify(this.inputForm))
+              this.loading = false
+            } else {
+              if (this.commonJS.isEmpty(this.inputForm.handledByOffice)) {
+                this.inputForm.handledByOffice = this.$store.state.user.office.id
+              }
+              if (this.commonJS.isEmpty(this.inputForm.handledBy)) {
+                this.inputForm.handledBy = this.$store.state.user.name
+              }
+              if (this.commonJS.isEmpty(this.inputForm.handledById)) {
+                this.inputForm.handledById = this.$store.state.user.id
+              }
+              if (this.commonJS.isEmpty(this.inputForm.collectDate)) {
+                this.inputForm.collectDate = new Date()
+              }
+              this.inputForm.detailInfos = []
+              this.loading = false
+            }
+          })
+        })
+      },
+      getUpload (p, index) {
+        p.then((list) => {
+          // list为返回数据
+          this.inputForm.detailInfos[index].fileInfoLost = list
+          this.inputForm.detailInfos[index].fileNumber = list.length
+          this.tableKeyClient = Math.random()
+        })
+      },
+      seeFileInfo (index) {
+        if (this.commonJS.isEmpty(this.inputForm.detailInfos[index].fileInfoLost)) {
+          this.inputForm.detailInfos[index].fileInfoLost = []
+        }
+        this.$refs.materialManagementDialog.newUpload('view', this.inputForm.detailInfos[index].fileInfoLost, null, null, null, null, null, false, index)
+      },
+      sss (index) {
+        if (this.commonJS.isEmpty(this.inputForm.detailInfos[index].fileInfoLost)) {
+          this.inputForm.detailInfos[index].fileInfoLost = []
+        }
+        this.$refs.materialManagementDialog.newUpload(null, this.inputForm.detailInfos[index].fileInfoLost, null, null, null, null, null, false, index)
+      },
+      // 表单提交
+      doSubmit () {
+        this.$refs['inputForm'].validate((valid) => {
+          if (valid) {
+            this.loading = true
+            if (this.$refs.uploadComponent.checkProgress()) {
+              this.loading = false
+              return
+            }
+            if (this.commonJS.isEmpty(this.inputForm.files)) {
+              this.inputForm.files = []
+            }
+            this.inputForm.id = this.businessId
+            this.inputForm.files = this.$refs.uploadComponent.getDataList()
+            this.collectService.save(this.inputForm).then((data) => {
+              this.close()
+              this.$message.success(data)
+              this.$emit('refreshDataList')
+              this.loading = false
+            }).catch(() => {
+              this.loading = false
+            })
+          }
+        })
+      },
+      close () {
+        this.inputForm.detailInfos = []
+        // this.inputForm.amountInfos = []
+        this.$refs.uploadComponent.clearUpload()
+
+        this.visible = false
+        this.$refs.inputForm.resetFields()
+      },
+      // 删除
+      removeEvent (row, rowIndex, type) {
+        if (type === 'detail') {
+          this.$refs.detailTable.remove(row)
+          this.inputForm.detailInfos.splice(rowIndex, 1)
+        }
+        if (type === 'amount') {
+          this.$refs.amountTable.remove(row)
+          // this.inputForm.amountInfos.splice(rowIndex, 1)
+        }
+      },
+      // 新增
+      async insertEvent (type) {
+        if (type === 'detail') {
+          await this.$refs.detailTable.insert().then((data) => {
+            data.recipientAgent = this.$store.state.user.name
+            data.recipientAgentId = this.recipientAgentId
+            data.recipientOffice = this.officeName
+            this.inputForm.detailInfos.push(data)
+          })
+        }
+        if (type === 'amount') {
+          await this.$refs.amountTable.insert().then((data) => {
+            // this.inputForm.amountInfos.push(data)
+          })
+        }
+      },
+      reapplyForm (callback) {
+        this.loading = true
+        this.collectService.findById(this.inputForm.id).then((data) => {
+          if (data.statusReturn !== '4') { // 审核状态不是“驳回”,就弹出提示
+            this.loading = false
+            this.$message.error('任务数据已发生改变或不存在,请在待办任务中确认此任务是否存在')
+            throw new Error('任务数据已发生改变或不存在,请在待办任务中确认此任务是否存在')
+          } else {
+            this.startFormTrue(callback)
+          }
+        })
+      },
+      startForm (callback) {
+        this.loading = true
+        if (this.commonJS.isNotEmpty(this.inputForm.id)) {
+          this.collectService.findById(this.inputForm.id).then((data) => {
+            // 审核状态不是“未发起”或“暂存”或“撤回”,就弹出提示
+            if (this.commonJS.isNotEmpty(data.statusReturn) && data.statusReturn !== '0' && data.statusReturn !== '1' && data.statusReturn !== '3') {
+              this.loading = false
+              this.$message.error('任务数据已发生改变或不存在,请在待办任务中确认此任务是否存在')
+              throw new Error('任务数据已发生改变或不存在,请在待办任务中确认此任务是否存在')
+            } else {
+              this.startFormTrue(callback)
+            }
+          })
+        } else {
+          this.startFormTrue(callback)
+        }
+      },
+      // 暂存
+      async saveForm (callback) {
+        this.loading = true
+        if (this.$refs.uploadComponent.checkProgress()) {
+          this.loading = false
+          return
+        }
+        if (this.commonJS.isEmpty(this.inputForm.files)) {
+          this.inputForm.files = []
+        }
+        this.inputForm.files = this.$refs.uploadComponent.getDataList()
+        this.inputForm.statusReturn = '1'
+        this.collectService.saveReturn(this.inputForm).then((data) => {
+          callback()
+          this.$refs.inputForm.resetFields()
+          this.loading = false
+        }).catch(() => {
+          this.$refs.inputForm.resetFields()
+          this.loading = false
+        })
+      },
+      // 送审
+      async startFormTrue (callback) {
+        this.loading = true
+        this.$refs['inputForm'].validate(async (valid) => {
+          if (valid) {
+            this.loading = true
+            if (this.$refs.uploadComponent.checkProgress()) {
+              this.loading = false
+              return
+            }
+            if (this.commonJS.isEmpty(this.inputForm.files)) {
+              this.inputForm.files = []
+            }
+            if (this.commonJS.isEmpty(this.inputForm.detailInfos)) {
+              this.$message.error('至少填写一条领用详情信息')
+              this.loading = false
+              return
+            } else {
+              let i = this.inputForm.detailInfos.length
+              for (let j = 0; j < i; j++) {
+                let k = j + 1
+                if (this.commonJS.isEmpty(this.inputForm.detailInfos[j].recipientAgent)) {
+                  this.$message.error('领用详情第' + k + '行请选择领用人')
+                  this.loading = false
+                  return
+                }
+                if (this.commonJS.isEmpty(this.inputForm.detailInfos[j].collectType)) {
+                  this.$message.error('领用详情第' + k + '行请选择领用类型')
+                  this.loading = false
+                  return
+                }
+                if (this.commonJS.isEmpty(this.inputForm.detailInfos[j].goodsName)) {
+                  this.$message.error('领用详情第' + k + '行请选择物品名称')
+                  this.loading = false
+                  return
+                }
+                if (this.commonJS.isEmpty(this.inputForm.detailInfos[j].collectNumber)) {
+                  this.$message.error('领用详情第' + k + '行请输入领用数量')
+                  this.loading = false
+                  return
+                }
+              }
+            }
+            this.inputForm.files = this.$refs.uploadComponent.getDataList()
+            this.inputForm.statusReturn = '2'
+            this.collectService.saveReturn(this.inputForm).then((data) => {
+              this.inputForm.id = data.businessId
+              callback(data.businessTable, data.businessId, this.inputForm)
+              this.$refs.inputForm.resetFields()
+              this.loading = false
+            }).catch(() => {
+              this.$refs.inputForm.resetFields()
+              this.loading = false
+            })
+          } else {
+            this.loading = false
+          }
+        })
+      },
+      // 通过
+      async agreeForm (callback) {
+        this.loading = true
+        this.$refs['inputForm'].validate(async (valid) => {
+          if (valid) {
+            this.loading = true
+            if (this.$refs.uploadComponent.checkProgress()) {
+              this.loading = false
+              return
+            }
+            if (this.commonJS.isEmpty(this.inputForm.files)) {
+              this.inputForm.files = []
+            }
+            this.inputForm.files = this.$refs.uploadComponent.getDataList()
+            // this.commonApi.getTaskNameByProcInsId(this.inputForm.procInsId).then((data) => {
+            //   if (this.commonJS.isNotEmpty(data)) {
+            //     if (data === '仓库管理员审核') {
+            //       this.inputForm.status = '5'
+            //     }
+            //   }
+            //   this.collectService.save(this.inputForm).then((data) => {
+            //     callback(data.businessTable, data.businessId, this.inputForm)
+            //     this.loading = false
+            //   }).catch(() => {
+            //     this.loading = false
+            //   })
+            // })
+            this.inputForm.statusReturn = '5'
+            this.collectService.saveReturnAgree(this.inputForm).then((data) => {
+              callback(data.businessTable, data.businessId, this.inputForm)
+              this.loading = false
+            }).catch(() => {
+              this.loading = false
+            })
+          } else {
+            this.loading = false
+          }
+        })
+      },
+      // 修改状态
+      async updateStatusById (type, callback) {
+        this.loading = true
+        if (await this.$refs.uploadComponent.checkProgress()) {
+          this.loading = false
+          throw new Error()
+        } else {
+          if (type === 'reject' || type === 'reback') {
+            this.collectService.findById(this.inputForm.id).then((data) => {
+              if (data.statusReturn !== '2') { // status的值不等于“审核中”,就弹出提示
+                this.loading = false
+                this.$message.error('任务数据已发生改变或不存在,请在待办任务中确认此任务是否存在')
+                throw new Error()
+              } else {
+                if (type === 'reject') {
+                  // 驳回
+                  this.inputForm.statusReturn = '4'
+                }
+                if (type === 'reback') {
+                  // 撤回
+                  this.inputForm.statusReturn = '3'
+                }
+                if (type === 'reject' || type === 'reback') {
+                  let param = {status: this.inputForm.statusReturn, id: this.inputForm.id}
+                  this.collectService.updateStatusByIdReturn(param).then(() => {
+                    this.loading = false
+                    callback()
+                  })
+                }
+              }
+            })
+          } else if (type === 'hold') {
+            this.collectService.findById(this.inputForm.id).then((data) => {
+              if (data.statusReturn !== '4') { // status的值不等于“驳回”就弹出提示
+                this.loading = false
+                this.$message.error('任务数据已发生改变或不存在,请在待办任务中确认此任务是否存在')
+                throw new Error()
+              } else {
+                // 终止
+                this.collectService.returnRequest({id: this.inputForm.id}).then((data) => {
+                  this.loading = false
+                  callback()
+                })
+                // 终止
+                // let param = {status: '0', id: this.inputForm.id}
+                // this.collectService.updateStatusByIdReturn(param).then(() => {
+                //   this.loading = false
+                //   callback()
+                // })
+              }
+            })
+          }
+        }
+      },
+      // updateStatusById (type) {
+      //   if (type === 'reject') {
+      //     this.inputForm.status = '4'
+      //     this.collectService.updateStatusById(this.inputForm)
+      //   }
+      // },
+      // footerMethod ({ columns, data }) {
+      //   const footerData = [
+      //     columns.map((column, columnIndex) => {
+      //       if (columnIndex === 0) {
+      //         return '商品总价'
+      //       }
+      //       if (['priceSum'].includes(column.property)) {
+      //         // eslint-disable-next-line no-undef
+      //         this.inputForm.tradeTotalPrice = XEUtils.sum(data, column.property)
+      //         return XEUtils.sum(data, column.property)
+      //       }
+      //       return null
+      //     })
+      //   ]
+      //   return footerData
+      // },
+      // twoDecimalPlaces (num, index) {
+      //   let str = num.toString()
+      //   var len1 = str.substr(0, 1)
+      //   var len2 = str.substr(1, 1)
+      //   // eslint-disable-next-line eqeqeq
+      //   if (str.length > 1 && len1 == 0 && len2 != '.') {
+      //     str = str.substr(1, 1)
+      //   }
+      //   // eslint-disable-next-line eqeqeq
+      //   if (len1 == '.') {
+      //     str = ''
+      //   }
+      //   // eslint-disable-next-line eqeqeq
+      //   if (str.indexOf('.') != -1) {
+      //     var str_ = str.substr(str.indexOf('.') + 1)
+      //     // eslint-disable-next-line eqeqeq
+      //     if (str_.indexOf('.') != -1) {
+      //       str = str.substr(0, str.indexOf('.') + str_.indexOf('.') + 1)
+      //     }
+      //     if (str_.length > 2) {
+      //       this.$message.warning(`金额小数点后只能输入两位,请正确输入!`)
+      //       return (str = '')
+      //     }
+      //   }
+      //   // eslint-disable-next-line no-useless-escape
+      //   this.inputForm.detailInfos[index].priceSum = str.replace(/[^\d^\.]+/g, '') // 保留数字和小数点
+      // },
+      twoDecimalPlaces2 (num) {
+        let str = num.toString()
+        var len1 = str.substr(0, 1)
+        var len2 = str.substr(1, 1)
+        // eslint-disable-next-line eqeqeq
+        if (str.length > 1 && len1 == 0 && len2 != '.') {
+          str = str.substr(1, 1)
+        }
+        // eslint-disable-next-line eqeqeq
+        if (len1 == '.') {
+          str = ''
+        }
+        // eslint-disable-next-line eqeqeq
+        if (str.indexOf('.') != -1) {
+          var str_ = str.substr(str.indexOf('.') + 1)
+          // eslint-disable-next-line eqeqeq
+          if (str_.indexOf('.') != -1) {
+            str = str.substr(0, str.indexOf('.') + str_.indexOf('.') + 1)
+          }
+          if (str_.length > 2) {
+            this.$message.warning(`领用数量小数点后只能输入两位,请正确输入!`)
+            return (str = '')
+          }
+        }
+        // eslint-disable-next-line no-useless-escape
+        str = str.replace(/[^\d^\.]+/g, '') // 保留数字和小数点
+        return str
+      },
+      countAmount (row) {
+        let amount
+        let taxAmount
+        let count = 0
+        if (!this.commonJS.isEmpty(row.amount)) {
+          amount = parseFloat(row.amount)
+          count = count + amount
+        }
+        if (!this.commonJS.isEmpty(row.taxAmount)) {
+          taxAmount = parseFloat(row.taxAmount)
+          count = count + taxAmount
+        }
+        row.count = parseFloat(count).toFixed(2)
+      },
+      getProgram (rows) {
+        this.inputForm.detailInfos[this.indexRow].projectId = rows[0].id
+        this.inputForm.detailInfos[this.indexRow].projectName = rows[0].name
+        this.inputForm.detailInfos[this.indexRow].reportNumber = rows[0].reportNo
+        this.indexRow = ''
+        this.$forceUpdate()
+      },
+      // 领用类型下拉弹窗
+      typePullForm (rowIndex) {
+        this.indexRow = rowIndex
+        this.$refs.materialTypePullForm.init()
+      },
+      getProgramForType (rows) {
+        this.inputForm.detailInfos[this.indexRow].collectTypeId = rows.id
+        this.inputForm.detailInfos[this.indexRow].collectType = rows.name
+        this.inputForm.detailInfos[this.indexRow].goodsName = ''
+        this.indexRow = ''
+        this.$forceUpdate()
+      },
+      // 领用人下拉弹窗
+      userPullListForm (rowIndex) {
+        this.indexRow = rowIndex
+        this.$refs.userPullForm.init()
+      },
+      getProgramForUser (rows) {
+        this.inputForm.detailInfos[this.indexRow].recipientAgentId = rows[0].id
+        this.inputForm.detailInfos[this.indexRow].recipientAgent = rows[0].name
+        this.inputForm.detailInfos[this.indexRow].deptId = rows[0].parentId
+        this.inputForm.detailInfos[this.indexRow].recipientOffice = rows[0].officeName
+        this.indexRow = ''
+        this.$forceUpdate()
+      },
+      getUserInfo (rows) {
+      },
+      openPurchasePageForm (rowIndex, row) {
+        if (this.commonJS.isEmpty(row.collectType)) {
+          this.$message.error('请选择领用类型')
+          return
+        }
+        this.indexRow = rowIndex
+        this.$refs.purchasePageForm.init(row.collectTypeId)
+      },
+      getContract (row) {
+        this.inputForm.detailInfos[this.indexRow].surplusNumber = row.tradeNumber
+        this.inputForm.detailInfos[this.indexRow].goodsName = row.tradeName
+        // 去除重复的领用详情
+        let i = this.inputForm.detailInfos.length
+        for (let j = 0; j < i; j++) {
+          console.log('进来了')
+          for (let k = j + 1; k < i; k++) {
+            if (this.inputForm.detailInfos[j].collectTypeId === this.inputForm.detailInfos[k].collectTypeId) {
+              if (this.commonJS.isNotEmpty(this.inputForm.detailInfos[j].goodsName) &&
+                this.commonJS.isNotEmpty(this.inputForm.detailInfos[k].goodsName) && this.inputForm.detailInfos[j].goodsName === this.inputForm.detailInfos[k].goodsName) {
+                // parseFloat(item.account).toFixed(2)
+                this.inputForm.detailInfos.splice(k, 1)
+                this.$message.warning(`同种领用类型的商品名称只能输入一条信息!`)
+              }
+            }
+          }
+        }
+        this.indexRow = ''
+        this.$forceUpdate()
+      },
+      // 值改变事件
+      changeValue () {
+        let i = this.inputForm.detailInfos.length
+        for (let j = 0; j < i; j++) {
+          if (this.commonJS.isEmpty(this.inputForm.detailInfos[j].surplusNumber)) {
+            this.$message.error('请选择领用物品名称')
+            return
+          }
+          if (this.commonJS.isNotEmpty(this.inputForm.detailInfos[j].collectNumber)) {
+            if (parseFloat(this.inputForm.detailInfos[j].surplusNumber) < parseFloat(this.inputForm.detailInfos[j].collectNumber)) {
+              this.$message.error('领用数量不能大于剩余数量')
+              this.inputForm.detailInfos[j].collectNumber = ''
+              return
+            }
+          }
+        }
+      },
+      // 退回
+      returnCollect (index) {
+        this.inputForm.detailInfos[index].isReturn = '1'
+      },
+      // 取消退回
+      cancelReturn (index) {
+        this.inputForm.detailInfos[index].isReturn = '0'
+      },
+      // 列表行颜色
+      rowClassName ({ row, rowIndex }) {
+        if (row.isReturn === '1') { // 退回
+          return 'row-grey'
+        } else {
+          return ''
+        }
+      }
+    }
+  }
+</script>
+<style scoped>
+  .el-divider__text {
+    font-size: 16px;
+    font-weight: bold;
+  }
+  /deep/  .row-green {
+    /*background-color: #67c23ad1;*/
+    /*color: #fff;*/
+    font-weight: bold;
+  }
+  /deep/  .row-grey {
+    background-color: #b8b7b7;
+    color: #fff;
+  }
+  /deep/  .row-red {
+    background-color: #f56c6c66;
+    /*color: #fff;*/
+    font-weight: bold;
+  }
+</style>

+ 149 - 0
src/views/psiManagement/collect/PurchasePageForm.vue

@@ -0,0 +1,149 @@
+<template>
+	<div>
+		<el-dialog title="选择商品" :close-on-click-modal="false" draggable width="1100px" height="500px" @close="close"
+			append-to-body v-model="visible">
+			<div style="height: calc(100% - 80px);">
+				<el-form :inline="true" class="query-form" ref="searchForm" :model="searchForm" @submit.native.prevent>
+					<!-- 搜索框-->
+					<el-form-item label="商品名称" prop="tradeName">
+						<el-input v-model="searchForm.tradeName" placeholder="请输入商品名称" clearable></el-input>
+					</el-form-item>
+
+					<el-form-item>
+						<el-button type="primary" @click="list()" icon="el-icon-search">查询</el-button>
+						<el-button @click="resetSearch()" icon="el-icon-refresh-right">重置</el-button>
+					</el-form-item>
+				</el-form>
+
+				<vxe-table border="inner" auto-resize resizable height="400px" :loading="loading" ref="projectTable"
+					show-header-overflow show-overflow highlight-hover-row :menu-config="{}" :print-config="{}"
+					:sort-config="{ remote: true }" :data="dataList" :row-config="{ isCurrent: true }"
+					:radio-config="{ trigger: 'row' }">
+					<vxe-column type="seq" width="60" title="序号"></vxe-column>
+					<vxe-column type="radio" width="60px"></vxe-column>
+					<vxe-column min-width="230" align="center" title="商品名称" field="tradeName"></vxe-column>
+					<!--          <vxe-column min-width="230" align="center" title="商品数量" field="tradeNumber"></vxe-column>-->
+
+				</vxe-table>
+				<vxe-pager background :current-page="tablePage.currentPage" :page-size="tablePage.pageSize"
+					:total="tablePage.total" :page-sizes="[10, 20, 100, 1000, { label: '全量数据', value: 1000000 }]"
+					:layouts="['PrevPage', 'JumpNumber', 'NextPage', 'FullJump', 'Sizes', 'Total']"
+					@page-change="currentChangeHandle">
+				</vxe-pager>
+			</div>
+			<template #footer>
+				<span class="dialog-footer">
+					<el-button @click="close()" icon="el-icon-circle-close">关闭</el-button>
+					<el-button type="primary" v-if="method != 'view'" @click="getProject()" icon="el-icon-circle-check"
+						v-noMoreClick>确定</el-button>
+				</span>
+			</template>
+		</el-dialog>
+	</div>
+</template>
+
+<script>
+// import CollectService from '@/api/materialManagement/CollectService'
+import WareHouseService from '@/api/psi/WareHouseService'
+import Template from '../../../assets/icons/template.vue'
+export default {
+	data() {
+		return {
+			title: '',
+			method: '',
+			visible: false,
+			loading: false,
+			tablePage: {
+				total: 0,
+				currentPage: 1,
+				pageSize: 10,
+				orders: []
+			},
+			dataList: [],
+			searchForm: {
+				wareHouseType: '',
+				tradeName: ''
+			},
+			typeTest: ''
+		}
+	},
+	// collectService: null,
+	wareHouseService: null,
+	created() {
+		// this.collectService = new CollectService()
+		this.wareHouseService = new WareHouseService()
+	},
+	components: {
+		Template
+	},
+	methods: {
+		init(collectType) {
+			this.visible = true
+			this.typeTest = collectType
+			this.list()
+		},
+		// 表单提交
+		getProject() {
+			let row = this.$refs.projectTable.getRadioRecord()
+			if (this.commonJS.isEmpty(row)) {
+				this.$message.error('请选择一条数据')
+				return
+			}
+			if (row.tradeNumber == "0") {
+				this.$message.error('暂无库存,请选择其他商品')
+				return
+			}
+			this.close()
+			this.$emit('getProject', row)
+		},
+		list() {
+			this.loading = true
+			// this.searchForm.createId = this.$store.state.user.id
+			// this.searchForm.status = '5'
+			this.searchForm.wareHouseType = this.typeTest
+			// this.collectService.wareHouseList({
+			//   'current': this.tablePage.currentPage,
+			//   'size': this.tablePage.pageSize,
+			//   'orders': this.tablePage.orders,
+			//   ...this.searchForm
+			// }).then((data) => {
+			//   this.dataList = data.records
+			//   this.tablePage.total = data.total
+			//   this.loading = false
+			// })
+			this.wareHouseService.getByProduceDateAndNameGroup({
+				'current': this.tablePage.currentPage,
+				'size': this.tablePage.pageSize,
+				'orders': this.tablePage.orders,
+				...this.searchForm
+			}).then((data) => {
+				this.dataList = data.records
+				this.tablePage.total = data.total
+				this.tableKey = Math.random()
+				this.loading = false
+			})
+		},
+		// 当前页
+		currentChangeHandle({ currentPage, pageSize }) {
+			this.tablePage.currentPage = currentPage
+			this.tablePage.pageSize = pageSize
+			this.list()
+		},
+		resetSearch() {
+			this.$refs.searchForm.resetFields()
+			this.list()
+		},
+		close() {
+			this.$refs.searchForm.resetFields()
+			this.visible = false
+			this.typeTest = ''
+		}
+	}
+}
+</script>
+<style scoped>
+/deep/ .el-dialog__body {
+	padding-top: 0px;
+	padding-bottom: 15px;
+}
+</style>

+ 122 - 0
src/views/psiManagement/collect/PurchasePageFormByOption.vue

@@ -0,0 +1,122 @@
+<template>
+	<div>
+		<el-dialog title="选择商品" :close-on-click-modal="false" draggable width="1100px" height="500px" @close="close"
+			append-to-body v-model="visible">
+			<div style="height: calc(100% - 80px);">
+				<vxe-table border="inner" auto-resize resizable height="400px" :loading="loading" ref="projectTable"
+					show-header-overflow show-overflow highlight-hover-row :menu-config="{}" :print-config="{}"
+					:sort-config="{ remote: true }" :data="dataList" :row-config="{ isCurrent: true }"
+					:radio-config="{ trigger: 'row' }">
+					<vxe-column type="seq" width="60" title="序号"></vxe-column>
+					<vxe-column type="radio" width="60px"></vxe-column>
+					<vxe-column min-width="230" align="center" title="商品名称" field="tradeName"></vxe-column>
+				</vxe-table>
+			</div>
+			<template #footer>
+				<span class="dialog-footer">
+					<el-button @click="close()" icon="el-icon-circle-close">关闭</el-button>
+					<el-button type="primary" v-if="method != 'view'" @click="getProject()" icon="el-icon-circle-check"
+						v-noMoreClick>确定</el-button>
+				</span>
+			</template>
+		</el-dialog>
+	</div>
+</template>
+
+<script>
+// import CollectService from '@/api/materialManagement/CollectService'
+import WareHouseService from '@/api/psi/WareHouseService'
+import Template from '../../../assets/icons/template.vue'
+export default {
+	data() {
+		return {
+			title: '',
+			method: '',
+			visible: false,
+			loading: false,
+			tablePage: {
+				total: 0,
+				currentPage: 1,
+				pageSize: 10,
+				orders: []
+			},
+			dataList: [],
+			searchForm: {
+				wareHouseType: '',
+				tradeName: ''
+			},
+		}
+	},
+	// collectService: null,
+	wareHouseService: null,
+	created() {
+		// this.collectService = new CollectService()
+		this.wareHouseService = new WareHouseService()
+	},
+	components: {
+		Template
+	},
+	methods: {
+		init(uniqueGoods) {
+			this.visible = true
+			this.dataList = uniqueGoods
+
+		},
+		// 表单提交
+		getProject() {
+			let row = this.$refs.projectTable.getRadioRecord()
+			if (this.commonJS.isEmpty(row)) {
+				this.$message.error('请选择一条数据')
+				return
+			}
+			this.close()
+			this.$emit('getProject', row)
+		},
+		list() {
+			this.loading = true
+			// this.searchForm.createId = this.$store.state.user.id
+			// this.searchForm.status = '5'
+			this.searchForm.wareHouseType = this.typeTest
+			// this.collectService.wareHouseList({
+			//   'current': this.tablePage.currentPage,
+			//   'size': this.tablePage.pageSize,
+			//   'orders': this.tablePage.orders,
+			//   ...this.searchForm
+			// }).then((data) => {
+			//   this.dataList = data.records
+			//   this.tablePage.total = data.total
+			//   this.loading = false
+			// })
+			this.wareHouseService.getByProduceDateAndNameGroup({
+				'current': this.tablePage.currentPage,
+				'size': this.tablePage.pageSize,
+				'orders': this.tablePage.orders,
+				...this.searchForm
+			}).then((data) => {
+				this.dataList = data.records
+				this.tablePage.total = data.total
+				this.tableKey = Math.random()
+				this.loading = false
+			})
+		},
+		// 当前页
+		currentChangeHandle({ currentPage, pageSize }) {
+			this.tablePage.currentPage = currentPage
+			this.tablePage.pageSize = pageSize
+			this.list()
+		},
+		resetSearch() {
+			this.list()
+		},
+		close() {
+			this.visible = false
+		}
+	}
+}
+</script>
+<style scoped>
+/deep/ .el-dialog__body {
+	padding-top: 0px;
+	padding-bottom: 15px;
+}
+</style>

+ 621 - 0
src/views/psiManagement/collect/UpdateCollectInfoForm.vue

@@ -0,0 +1,621 @@
+<template>
+	<div>
+		<el-dialog :title="title" :close-on-click-modal="false" draggable width="1500px" @close="close"
+			@keyup.enter.native="doSubmit" v-model="visible">
+			<el-form :model="inputForm" ref="inputForm" v-loading="loading" :class="method === 'view' ? 'readonly' : ''"
+				:disabled="method === 'view'" label-width="100px" @submit.native.prevent>
+
+				<el-divider content-position="left"><i class="el-icon-document"></i> 基础信息</el-divider>
+				<el-row :gutter="26">
+					<el-col :span="12">
+						<el-form-item label="领用编号" prop="collectNo">
+							<el-input placeholder="自动生成" v-model="inputForm.collectNo" :disabled="true"></el-input>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="经办人" prop="handledBy">
+							<el-input v-model="inputForm.handledBy" :disabled="true"></el-input>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="经办人部门" prop="handledByOffice">
+							<SelectTree :disabled="true" ref="officeTree" :props="{
+								value: 'id',             // ID字段名
+								label: 'name',         // 显示名称
+								children: 'children'    // 子级字段名
+							}" :url="`/system-server/sys/office/treeData?type=2`" :value="inputForm.handledByOffice" :accordion="true"
+								size="default" @getValue="(value) => { inputForm.handledByOffice = value }" />
+							<!--            <el-input v-model="inputForm.handledByOffice" :disabled="true"></el-input>-->
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="领用时间" prop="collectDate"
+							:rules="[{ required: true, message: '请选择领用时间', trigger: 'blur' }]">
+							<el-date-picker v-model="inputForm.collectDate" type="date" value-format="YYYY-MM-DD"
+								style="width: 100%" placeholder="选择日期">
+							</el-date-picker>
+						</el-form-item>
+					</el-col>
+					<el-col :span="24">
+						<el-form-item label="备注" prop="remarks">
+							<el-input v-model="inputForm.remarks" type="textarea" :rows="5" maxlength="500"
+								placeholder="请填写备注信息" show-word-limit>
+							</el-input>
+						</el-form-item>
+					</el-col>
+				</el-row>
+				<!--method==='view' || this.formReadOnly-->
+				<el-divider content-position="left"><i class="el-icon-document"></i>
+					领用详情
+					<el-button style="margin-left: 20px" type="primary" :disabled="true" @click="insertEvent('detail')"
+						plain>
+						新增
+					</el-button>
+				</el-divider>
+				<el-row :gutter="15">
+					<el-col :span="24">
+						<vxe-table border show-footer show-overflow ref="detailTable" class="vxe-table-element"
+							:data="inputForm.detailInfos" style="margin-left: 5em" highlight-current-row
+							:edit-config="{ trigger: 'click', mode: 'row', showStatus: false, autoClear: true, icon: '-' }"
+							:edit-rules="validRules">
+							<vxe-table-column field="recipientAgent" title="领用人" :edit-render="{}"
+								:rules="[{ required: true, message: '请选择领用人', trigger: 'blur' }]">
+								<template v-slot:edit="scope">
+									<el-input :disabled='true' v-model="scope.row.recipientAgent"
+										@focus="userPullListForm(scope.$rowIndex)"></el-input>
+								</template>
+							</vxe-table-column>
+							<vxe-table-column field="recipientOffice" title="领用人部门" :edit-render="{}">
+								<template v-slot:edit="scope">
+									<el-input :disabled='true' v-model="scope.row.recipientOffice"></el-input>
+								</template>
+							</vxe-table-column>
+							<vxe-table-column field="collectType" title="领用类型" :edit-render="{}"
+								:rules="[{ required: true, message: '请选择领用类型', trigger: 'blur' }]">
+								<template v-slot:edit="scope">
+									<el-input :disabled='true' v-model="scope.row.collectType"
+										@focus="typePullForm(scope.$rowIndex)"></el-input>
+								</template>
+							</vxe-table-column>
+							<vxe-table-column field="goodsName" title="物品名称" :edit-render="{}"
+								:rules="[{ required: true, message: '请填写物品名称', trigger: 'blur' }]">
+								<template v-slot:edit="scope">
+									<el-input :disabled='true' v-model="scope.row.goodsName"
+										@focus="openPurchasePageForm(scope.$rowIndex, scope.row)"></el-input>
+								</template>
+							</vxe-table-column>
+							<!--            <vxe-table-column field="surplusNumber" title="剩余数量" :edit-render="{}">-->
+							<!--              <template v-slot:edit="scope">-->
+							<!--                <el-input :disabled="true" v-model="scope.row.surplusNumber" maxlength="10"></el-input>-->
+							<!--              </template>-->
+							<!--            </vxe-table-column>-->
+							<vxe-table-column field="collectNumber" title="领用数量" :edit-render="{}">
+								<template v-slot:edit="scope">
+									<el-input :disabled='true' v-model="scope.row.collectNumber"
+										@blur="scope.row.collectNumber = twoDecimalPlaces2(scope.row.collectNumber)"
+										maxlength="10"></el-input>
+								</template>
+							</vxe-table-column>
+							<vxe-table-column field="company" title="单位" :edit-render="{}"
+								:rules="[{ required: true, message: '请填写单位', trigger: 'blur' }]">
+								<template v-slot:edit="scope">
+									<el-input :disabled='true' v-model="scope.row.company"></el-input>
+								</template>
+							</vxe-table-column>
+							<vxe-table-column field="remarks" title="备注" :edit-render="{}">
+								<template v-slot:edit="scope">
+									<el-input :disabled='true' v-model="scope.row.remarks"></el-input>
+								</template>
+							</vxe-table-column>
+							<vxe-table-column title="操作" width="180">
+								<template v-slot="scope">
+									<!--                <el-button :disabled='true' type="danger" v-if="method!=='view'" @click="removeEvent(scope.row,scope.$rowIndex,'detail')">删除</el-button>-->
+									<!--                <el-button :disabled='true' type="primary" v-if="method!=='view'" @click="sss(scope.$rowIndex)">上传附件</el-button>-->
+									<vxe-button status="primary" :disabled="false"
+										@click="seeFileInfo(scope.$rowIndex)">查看文件详情</vxe-button>
+								</template>
+							</vxe-table-column>
+						</vxe-table>
+					</el-col>
+				</el-row>
+				<el-form :model="inputForm" :disabled="true" @submit.native.prevent>
+					<el-divider content-position="left" v-if="inputForm.status == '5'"><i class="el-icon-document"></i>
+						领用分配详情
+
+						<!-- <el-button style="margin-left: 20px" type="primary" :disabled="status != 'audit'"
+						@click="insertEvent('record')" plain>
+						新增
+					</el-button> -->
+					</el-divider>
+					<el-row :gutter="15" v-if="inputForm.status == '5'">
+						<el-col :span="24">
+							<vxe-table border show-footer show-overflow ref="auditDetailTable" class="vxe-table-element"
+								:data="inputForm.recordList" style="margin-left: 5em" :key="clientTableKey"
+								highlight-current-row
+								:edit-config="{ trigger: 'click', mode: 'row', showStatus: false, autoClear: !produceDateSelectVisible, icon: '-' }"
+								:edit-rules="validRules">
+								<vxe-table-column field="recipientAgent" title="领用人" :edit-render="{}"
+									:rules="[{ required: true, message: '请选择领用人', trigger: 'blur' }]">
+									<template v-slot:edit="scope">
+										<el-input v-model="scope.row.recipientAgent" :disabled='true'
+											@focus="userPullListForm(scope.$rowIndex)"></el-input>
+									</template>
+								</vxe-table-column>
+								<vxe-table-column field="recipientOffice" title="领用人部门" :edit-render="{}">
+									<template v-slot:edit="scope">
+										<el-input :disabled='true' v-model="scope.row.recipientOffice"></el-input>
+									</template>
+								</vxe-table-column>
+								<vxe-table-column field="collectType" title="领用类型" :edit-render="{}"
+									:rules="[{ required: true, message: '请选择领用类型', trigger: 'blur' }]">
+									<template v-slot:edit="scope">
+										<el-input v-model="scope.row.collectType" :disabled='true'
+											@focus="typePullForm1(scope.$rowIndex)"></el-input>
+									</template>
+								</vxe-table-column>
+								<vxe-table-column field="goodsName" title="物品名称"
+									:rules="[{ required: true, message: '请填写物品名称', trigger: 'blur' }]"
+									:edit-render="{}">
+									<template v-slot:edit="scope">
+										<el-input v-model="scope.row.goodsName" :disabled='true'
+											@focus="openPurchasePageForm1(scope.$rowIndex, scope.row)"></el-input>
+									</template>
+								</vxe-table-column>
+								<vxe-table-column field="inventoryId" title="分配生产日期" min-width="160"
+									:rules="[{ required: true, message: '请选择', trigger: 'change' }]">
+									<template #default="scope">
+										<el-select v-model="scope.row.inventoryId" :disabled="true" style="width:220px"
+											@change="value => handleInventoryChange(value, scope.row, scope.$rowIndex)"
+											@visible-change="handleProduceDateVisibleChange">
+											<el-option
+												:label="`${item.tradeName}(生产日期:${item.produceDate ? item.produceDate : '暂无生产日期'})`"
+												:value="item.id" v-for="(item, index) in scope.row.psiWareHouseDtoList"
+												:key="index" />
+										</el-select>
+									</template>
+								</vxe-table-column>
+								<vxe-table-column field="collectNumber" title="领用数量" :edit-render="{}">
+									<template v-slot:edit="scope">
+										<el-input v-model="scope.row.collectNumber" disabled
+											@input="handleInputInventory(scope.row, scope.$rowIndex)"
+											@blur="scope.row.collectNumber = twoDecimalPlaces2(scope.row.collectNumber)"
+											maxlength="10"></el-input>
+									</template>
+								</vxe-table-column>
+								<vxe-table-column field="surplusNumber" title="库存数量">
+									<template #default="scope">
+										<span
+											v-if="scope.row.surplusNumber !== undefined && scope.row.surplusNumber !== null && scope.row.spec !== undefined && scope.row.spec !== null">
+											{{ parseInt(scope.row.spec) * parseFloat(scope.row.surplusNumber) }}
+										</span>
+										<span v-else>
+											{{ scope.row.surplusNumber }}
+										</span>
+									</template>
+								</vxe-table-column>
+							</vxe-table>
+						</el-col>
+					</el-row>
+				</el-form>
+
+			</el-form>
+			<PurchasePageForm ref="purchasePageForm" @getProject="getContract"></PurchasePageForm>
+			<!-- 附件 -->
+			<MaterialManagementDialog ref="materialManagementDialog" @getUpload="getUpload"></MaterialManagementDialog>
+			<UpLoadComponent ref="uploadComponent"></UpLoadComponent>
+			<CwProgramPageForm ref="cwProgramPageForm" @getProgram="getProgram"></CwProgramPageForm>
+			<MaterialTypePullForm ref="materialTypePullForm" @getProgramForType="getProgramForType">
+			</MaterialTypePullForm>
+			<UserPullForm ref="userPullForm" @getProgramForUser="getProgramForUser"></UserPullForm>
+			<template #footer>
+				<span class="dialog-footer">
+					<el-button @click="close()" icon="el-icon-circle-close">关闭</el-button>
+					<el-button type="primary" v-if="method != 'view'" @click="doSubmit()" icon="el-icon-circle-check"
+						v-noMoreClick>确定</el-button>
+				</span>
+			</template>
+		</el-dialog>
+	</div>
+</template>
+
+<script>
+import PurchasePageForm from './PurchasePageForm'
+import CollectService from '@/api/psi/CollectService'
+import SelectTree from '@/components/treeSelect/treeSelect.vue'
+import MaterialManagementDialog from '../file/MaterialManagementDialog'
+import CwProgramPageForm from '@/views/cw/reimbursementApproval/info/CwProgramPageForm'
+import MaterialTypePullForm from '../info/MaterialTypePullForm'
+import MaterialManagementService from '@/api/materialManagement/MaterialManagementService'
+import UpLoadComponent from '@/views/common/UpLoadComponent'
+import UserPullForm from '@/views/finance/invoice/UserPullForm'
+export default {
+	data() {
+		return {
+			validRules: {
+				recipientAgent: [
+					{ required: true, message: '领用人不能为空' }
+				],
+				recipientOffice: [
+					{ required: true, message: '领用人部门不能为空' }
+				],
+				collectType: [
+					{ required: true, message: '领用类型不能为空' }
+				],
+				goodsName: [
+					{ required: true, message: '物品名称不能为空' }
+				],
+				collectNumber: [
+					{ required: true, message: '领用数量不能为空' }
+				]
+			},
+			title: '',
+			method: '',
+			visible: false,
+			loading: false,
+			inputForm: {
+				sign: '', // 管理员修改标记
+				fileInfoLost: [],
+				handledByOffice: '',
+				handledBy: '',
+				handledById: '',
+				collectNo: '', // 领用编号
+				userId: '',
+				collectDate: '',
+				remarks: '',
+				detailInfos: [],
+				// amountInfos: [],
+				files: [] // 附件信息
+			}
+		}
+	},
+	CollectService: null,
+	MaterialManagementService: null,
+	created() {
+		this.collectService = new CollectService()
+		this.materialManagementService = new MaterialManagementService()
+	},
+	props: {
+		businessId: {
+			type: String,
+			default: ''
+		},
+		formReadOnly: {
+			type: Boolean,
+			default: false
+		},
+		status: {
+			type: String,
+			default: ''
+		}
+	},
+	components: {
+		SelectTree,
+		MaterialTypePullForm,
+		CwProgramPageForm,
+		MaterialManagementDialog,
+		UpLoadComponent,
+		UserPullForm,
+		PurchasePageForm
+	},
+	computed: {
+		bus: {
+			get() {
+				return this.businessId
+			},
+			set(val) {
+				this.businessId = val
+			}
+		},
+		name() {
+			return this.$store.state.user.name
+		},
+		officeName() {
+			return this.$store.state.user.office.name
+		},
+		userId() {
+			return this.$store.state.user.id
+		},
+		recipientAgentId() {
+			return this.$store.state.user.id
+		},
+		collectTypeId() {
+			return ''
+		}
+	},
+	methods: {
+		init(method, id) {
+			this.method = method
+			this.inputForm = {
+				sign: '', // 管理员修改标记
+				fileInfoLost: [],
+				handledByOffice: '',
+				handledBy: this.$store.state.user.name,
+				handledById: this.$store.state.user.id,
+				collectNo: '', // 领用编号
+				userId: this.$store.state.user.id,
+				collectDate: new Date(),
+				remarks: '',
+				detailInfos: [],
+				// amountInfos: [],
+				files: [] // 附件信息
+			}
+			if (method === 'add') {
+				this.title = `新建领用类型`
+			} else if (method === 'edit') {
+				this.inputForm.id = id
+				this.title = '修改领用类型'
+			} else if (method === 'view') {
+				this.inputForm.id = id
+				this.title = '查看领用类型'
+			}
+			this.visible = true
+			this.loading = false
+			this.$nextTick(() => {
+				if (method === 'edit' || method === 'view') { // 修改或者查看
+					this.loading = true
+					this.$refs.inputForm.resetFields()
+					this.collectService.findById(this.inputForm.id).then((data) => {
+						this.inputForm = this.recover(this.inputForm, data)
+						if (this.commonJS.isEmpty(this.inputForm.handledByOffice)) {
+							this.inputForm.handledByOffice = this.$store.state.user.office.id
+						}
+						if (this.commonJS.isNotEmpty(data.collectDate)) {
+							this.inputForm.collectDate = data.collectDate
+						}
+						if (this.commonJS.isNotEmpty(data.recipientAgentId)) {
+							this.recipientAgentId = data.recipientAgentId
+						}
+						if (this.commonJS.isNotEmpty(data.collectTypeId)) {
+							this.collectTypeId = data.collectTypeId
+						}
+						let i = this.inputForm.detailInfos.length
+						for (let j = 0; j < i; j++) {
+							if (this.commonJS.isNotEmpty(this.inputForm.detailInfos[j].tradePrice)) {
+								if (this.commonJS.isNotEmpty(this.inputForm.detailInfos[j].tradeNumber)) {
+									this.inputForm.detailInfos[j].priceSum = this.inputForm.detailInfos[j].tradePrice * this.inputForm.detailInfos[j].tradeNumber
+								}
+							}
+						}
+						this.$refs.uploadComponent.newUpload(method, this.inputForm.files, 'reimbursement')
+						this.inputForm = JSON.parse(JSON.stringify(this.inputForm))
+						this.loading = false
+					})
+				}
+			})
+		},
+		// 值改变事件
+		changeValue() {
+			let i = this.inputForm.detailInfos.length
+			for (let j = 0; j < i; j++) {
+				if (this.commonJS.isEmpty(this.inputForm.detailInfos[j].surplusNumber)) {
+					this.$message.error('请选择领用物品名称')
+					return
+				}
+				if (this.commonJS.isNotEmpty(this.inputForm.detailInfos[j].collectNumber)) {
+					if (this.inputForm.detailInfos[j].surplusNumber < this.inputForm.detailInfos[j].collectNumber) {
+						this.$message.error('领用数量不能大于剩余数量')
+						return
+					}
+				}
+			}
+		},
+		getProgramForUser(rows) {
+			this.inputForm.detailInfos[this.indexRow].recipientAgentId = rows[0].id
+			this.inputForm.detailInfos[this.indexRow].recipientAgent = rows[0].name
+			this.inputForm.detailInfos[this.indexRow].deptId = rows[0].parentId
+			this.inputForm.detailInfos[this.indexRow].recipientOffice = rows[0].officeName
+			this.indexRow = ''
+			this.$forceUpdate()
+		},
+		getProgramForType(rows) {
+			this.inputForm.detailInfos[this.indexRow].collectTypeId = rows.id
+			this.inputForm.detailInfos[this.indexRow].collectType = rows.name
+			this.indexRow = ''
+			this.$forceUpdate()
+		},
+		getProgram(rows) {
+			this.inputForm.detailInfos[this.indexRow].projectId = rows[0].id
+			this.inputForm.detailInfos[this.indexRow].projectName = rows[0].name
+			this.inputForm.detailInfos[this.indexRow].reportNumber = rows[0].reportNo
+			this.indexRow = ''
+			this.$forceUpdate()
+		},
+		getUpload(p, index) {
+			p.then((list) => {
+				// list为返回数据
+				this.inputForm.detailInfos[index].fileInfoLost = list
+				this.inputForm.detailInfos[index].fileNumber = list.length
+				this.tableKeyClient = Math.random()
+			})
+		},
+		twoDecimalPlaces2(num) {
+			let str = num.toString()
+			var len1 = str.substr(0, 1)
+			var len2 = str.substr(1, 1)
+			// eslint-disable-next-line eqeqeq
+			if (str.length > 1 && len1 == 0 && len2 != '.') {
+				str = str.substr(1, 1)
+			}
+			// eslint-disable-next-line eqeqeq
+			if (len1 == '.') {
+				str = ''
+			}
+			// eslint-disable-next-line eqeqeq
+			if (str.indexOf('.') != -1) {
+				var str_ = str.substr(str.indexOf('.') + 1)
+				// eslint-disable-next-line eqeqeq
+				if (str_.indexOf('.') != -1) {
+					str = str.substr(0, str.indexOf('.') + str_.indexOf('.') + 1)
+				}
+				if (str_.length > 2) {
+					this.$message.warning(`领用数量小数点后只能输入两位,请正确输入!`)
+					return (str = '')
+				}
+			}
+			// eslint-disable-next-line no-useless-escape
+			str = str.replace(/[^\d^\.]+/g, '') // 保留数字和小数点
+			return str
+		},
+		// 采购人下拉弹窗
+		userPullListForm(rowIndex) {
+			this.indexRow = rowIndex
+			this.$refs.userPullForm.init()
+		},
+		// footerMethod ({ columns, data }) {
+		//   const footerData = [
+		//     columns.map((column, columnIndex) => {
+		//       if (columnIndex === 0) {
+		//         return '商品总价'
+		//       }
+		//       if (['priceSum'].includes(column.property)) {
+		//         // eslint-disable-next-line no-undef
+		//         this.inputForm.tradeTotalPrice = XEUtils.sum(data, column.property)
+		//         return XEUtils.sum(data, column.property)
+		//       }
+		//       return null
+		//     })
+		//   ]
+		//   return footerData
+		// },
+		seeFileInfo(index) {
+			if (this.commonJS.isEmpty(this.inputForm.detailInfos[index].fileInfoLost)) {
+				this.inputForm.detailInfos[index].fileInfoLost = []
+			}
+			this.$refs.materialManagementDialog.newUpload('view', this.inputForm.detailInfos[index].fileInfoLost, null, null, null, null, null, false, index)
+		},
+		sss(index) {
+			if (this.commonJS.isEmpty(this.inputForm.detailInfos[index].fileInfoLost)) {
+				this.inputForm.detailInfos[index].fileInfoLost = []
+			}
+			this.$refs.materialManagementDialog.newUpload(null, this.inputForm.detailInfos[index].fileInfoLost, null, null, null, null, null, false, index)
+		},
+		// 采购类型下拉弹窗
+		typePullForm(rowIndex) {
+			this.indexRow = rowIndex
+			this.$refs.materialTypePullForm.init()
+		},
+		// 表单提交
+		doSubmit() {
+			this.$refs['inputForm'].validate((valid) => {
+				if (valid) {
+					this.loading = true
+					if (this.$refs.uploadComponent.checkProgress()) {
+						this.loading = false
+						return
+					}
+					if (this.commonJS.isEmpty(this.inputForm.files)) {
+						this.loading = false
+						this.inputForm.files = []
+					}
+					if (this.commonJS.isEmpty(this.inputForm.detailInfos)) {
+						this.$message.error('至少填写一条领用详情信息')
+						this.loading = false
+						return
+					} else {
+						let i = this.inputForm.detailInfos.length
+						for (let j = 0; j < i; j++) {
+							let k = j + 1
+							if (this.commonJS.isEmpty(this.inputForm.detailInfos[j].recipientAgent)) {
+								this.$message.error('领用详情第' + k + '行请选择领用人')
+								this.loading = false
+								return
+							}
+							if (this.commonJS.isEmpty(this.inputForm.detailInfos[j].collectType)) {
+								this.$message.error('领用详情第' + k + '行请选择领用类型')
+								this.loading = false
+								return
+							}
+							if (this.commonJS.isEmpty(this.inputForm.detailInfos[j].goodsName)) {
+								this.$message.error('领用详情第' + k + '行请选择物品名称')
+								this.loading = false
+								return
+							}
+							if (this.commonJS.isEmpty(this.inputForm.detailInfos[j].collectNumber)) {
+								this.$message.error('领用详情第' + k + '行请输入领用数量')
+								this.loading = false
+								return
+							}
+						}
+					}
+					this.inputForm.sign = '测试'
+					this.inputForm.files = this.$refs.uploadComponent.getDataList()
+					this.collectService.save(this.inputForm).then((data) => {
+						// eslint-disable-next-line no-undef
+						// callback(data.businessTable, data.businessId, this.inputForm)
+						// this.$refs.inputForm.resetFields()
+						this.$emit('refreshList')
+						this.loading = false
+						this.close()
+					}).catch(() => {
+						// this.$refs.inputForm.resetFields()
+						this.loading = false
+					})
+				}
+			})
+		},
+		close() {
+			this.$refs.inputForm.resetFields()
+			this.inputForm.detailInfos = []
+			this.inputForm.amountInfos = []
+			this.$refs.uploadComponent.clearUpload()
+			this.visible = false
+		},
+		// 删除
+		removeEvent(row, rowIndex, type) {
+			if (type === 'detail') {
+				this.$refs.detailTable.remove(row)
+				this.inputForm.detailInfos.splice(rowIndex, 1)
+			}
+			if (type === 'amount') {
+				this.$refs.amountTable.remove(row)
+				// this.inputForm.amountInfos.splice(rowIndex, 1)
+			}
+		},
+		// 新增
+		async insertEvent(type) {
+			if (type === 'detail') {
+				await this.$refs.detailTable.insert().then((data) => {
+					data.recipientAgent = this.$store.state.user.name
+					data.recipientAgentId = this.recipientAgentId
+					data.recipientOffice = this.officeName
+					this.inputForm.detailInfos.push(data)
+				})
+			}
+			if (type === 'amount') {
+				await this.$refs.amountTable.insert().then((data) => {
+					this.inputForm.amountInfos.push(data)
+				})
+			}
+		},
+		getContract(row) {
+			this.inputForm.detailInfos[this.indexRow].surplusNumber = row.tradeNumber
+			this.inputForm.detailInfos[this.indexRow].goodsName = row.tradeName
+			// 去除重复的领用详情
+			let i = this.inputForm.detailInfos.length
+			for (let j = 0; j < i; j++) {
+				console.log('进来了')
+				for (let k = j + 1; k < i; k++) {
+					if (this.inputForm.detailInfos[j].collectTypeId === this.inputForm.detailInfos[k].collectTypeId) {
+						if (this.commonJS.isNotEmpty(this.inputForm.detailInfos[j].goodsName) &&
+							this.commonJS.isNotEmpty(this.inputForm.detailInfos[k].goodsName) && this.inputForm.detailInfos[j].goodsName === this.inputForm.detailInfos[k].goodsName) {
+							// parseFloat(item.account).toFixed(2)
+							this.inputForm.detailInfos.splice(k, 1)
+							this.$message.warning(`同种领用类型的商品名称只能输入一条信息!`)
+						}
+					}
+				}
+			}
+			this.indexRow = ''
+			this.$forceUpdate()
+		},
+		openPurchasePageForm(rowIndex, row) {
+			if (this.commonJS.isEmpty(row.collectType)) {
+				this.$message.error('请选择领用类型')
+				return
+			}
+			this.indexRow = rowIndex
+			this.$refs.purchasePageForm.init(row.collectTypeId)
+		}
+	}
+}
+</script>

+ 138 - 0
src/views/psiManagement/contract/ContractChooseForm.vue

@@ -0,0 +1,138 @@
+<template>
+	<div>
+		<el-dialog title="选择合同信息" :close-on-click-modal="false" draggable width="1100px" height="500px" @close="close"
+			append-to-body v-model="visible">
+			<div style="height: calc(100% - 80px);">
+				<el-form :inline="true" class="query-form" ref="searchForm" :model="searchForm" @submit.native.prevent>
+					<!-- 搜索框-->
+					<el-form-item label="合同名称" prop="contractName">
+						<el-input v-model="searchForm.contractName" placeholder="请输入合同名称" clearable></el-input>
+					</el-form-item>
+					<el-form-item label="合同生效日期" prop="effectiveDates">
+						<el-date-picker placement="bottom-start" format="YYYY-MM-DD HH:mm:ss"
+							value-format="YYYY-MM-DD HH:mm:ss" v-model="searchForm.effectiveDates" type="datetimerange"
+							range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期">
+						</el-date-picker>
+					</el-form-item>
+
+					<el-form-item>
+						<el-button type="primary" @click="list()" icon="el-icon-search">查询</el-button>
+						<el-button @click="resetSearch()" icon="el-icon-refresh-right">重置</el-button>
+					</el-form-item>
+				</el-form>
+
+				<vxe-table border="inner" auto-resize resizable height="400px" :loading="loading" ref="projectTable"
+					show-header-overflow show-overflow highlight-hover-row :menu-config="{}" :print-config="{}"
+					:sort-config="{ remote: true }" :data="dataList" :row-config="{ isCurrent: true }"
+					:radio-config="{ trigger: 'row' }">
+					<vxe-column type="seq" width="60" title="序号"></vxe-column>
+					<vxe-column type="radio" width="40px"></vxe-column>
+					<vxe-column min-width="160" align="center" title="合同编号" field="contractNo"></vxe-column>
+					<vxe-column min-width="160" align="center" title="合同名称" field="contractName"></vxe-column>
+					<vxe-column min-width="160" align="center" title="客户名称" field="name"></vxe-column>
+					<vxe-column min-width="160" align="center" title="统一社会信用代码" field="uscCode"></vxe-column>
+					<vxe-column min-width="160" align="center" title="详细地址" field="address"></vxe-column>
+					<vxe-column min-width="160" align="center" title="合同生效日期" field="effectiveDate"></vxe-column>
+					<vxe-column min-width="160" align="center" title="合同终止日期" field="endTime"></vxe-column>
+
+				</vxe-table>
+				<vxe-pager background :current-page="tablePage.currentPage" :page-size="tablePage.pageSize"
+					:total="tablePage.total" :page-sizes="[10, 20, 100, 1000, { label: '全量数据', value: 1000000 }]"
+					:layouts="['PrevPage', 'JumpNumber', 'NextPage', 'FullJump', 'Sizes', 'Total']"
+					@page-change="currentChangeHandle">
+				</vxe-pager>
+			</div>
+			<template #footer>
+				<span class="dialog-footer">
+					<el-button @click="close()" icon="el-icon-circle-close">关闭</el-button>
+					<el-button type="primary" v-if="method != 'view'" @click="getProject()" icon="el-icon-circle-check"
+						v-noMoreClick>确定</el-button>
+				</span>
+			</template>
+		</el-dialog>
+	</div>
+</template>
+
+<script>
+import ContractService from '@/api/psi/ContractService'
+export default {
+	data() {
+		return {
+			title: '',
+			method: '',
+			visible: false,
+			loading: false,
+			tablePage: {
+				total: 0,
+				currentPage: 1,
+				pageSize: 10,
+				orders: []
+			},
+			dataList: [],
+			searchForm: {
+				contractName: '',
+				status: '',
+				effectiveDates: []
+			}
+		}
+	},
+	contractService: null,
+	created() {
+		this.contractService = new ContractService()
+	},
+	components: {
+	},
+	methods: {
+		init() {
+			this.visible = true
+			this.list()
+		},
+		// 表单提交
+		getProject() {
+			let row = this.$refs.projectTable.getRadioRecord()
+			if (this.commonJS.isEmpty(row)) {
+				this.$message.error('请选择一条数据')
+				return
+			}
+			this.close()
+			this.$emit('getProject', row)
+		},
+		list() {
+			this.loading = true
+			// this.searchForm.createId = this.$store.state.user.id
+			this.searchForm.status = '5'
+			this.contractService.list({
+				'current': this.tablePage.currentPage,
+				'size': this.tablePage.pageSize,
+				'orders': this.tablePage.orders,
+				...this.searchForm
+			}).then((data) => {
+				this.dataList = data.records
+				this.tablePage.total = data.total
+				this.tableKey = Math.random()
+				this.loading = false
+			})
+		},
+		// 当前页
+		currentChangeHandle({ currentPage, pageSize }) {
+			this.tablePage.currentPage = currentPage
+			this.tablePage.pageSize = pageSize
+			this.list()
+		},
+		resetSearch() {
+			this.$refs.searchForm.resetFields()
+			this.list()
+		},
+		close() {
+			this.$refs.searchForm.resetFields()
+			this.visible = false
+		}
+	}
+}
+</script>
+<style scoped>
+/deep/ .el-dialog__body {
+	padding-top: 0px;
+	padding-bottom: 15px;
+}
+</style>

+ 632 - 0
src/views/psiManagement/contract/ContractForm.vue

@@ -0,0 +1,632 @@
+<template>
+	<div>
+		<el-form :model="inputForm" ref="inputForm" v-loading="loading" :class="method === 'view' ? 'readonly' : ''"
+			:disabled="formReadOnly" label-width="200px" @submit.native.prevent>
+
+			<el-divider content-position="left"><i class="el-icon-document"></i> 客户信息</el-divider>
+			<el-row :gutter="0">
+				<el-col :span="10">
+					<el-form-item label="客户名称" prop="name" :rules="[
+					]">
+						<span slot="label"><span style="color: red;border-top: 20px">*</span> 客户名称</span>
+						<el-input maxlength="64" v-model="inputForm.name" placeholder="请输入客户名称" clearable></el-input>
+						<div class="usc_code_append_message">{{ nameMessage }}</div>
+					</el-form-item>
+				</el-col>
+				<el-col :span="2">
+					<el-popover v-model="visiblePop" placement="left" width="400" height="800" trigger="click"
+						:popper-options="{ boundariesElement: 'viewport', removeOnDestroy: true }" ref="pops">
+						<vxe-table border="inner" auto-resize resizable :row-config="{ isHover: true }" :data="gridData"
+							:checkbox-config="{}" :row-style="rowStyle" :key="tableKey" @cell-click="rowClick"
+							:show-header="false">
+							<vxe-column title="" field="entname"></vxe-column>
+						</vxe-table>
+						<el-button type="info" slot="reference" @click="getPopTable" style="width: 100%"
+							plain>查询</el-button>
+					</el-popover>
+				</el-col>
+				<el-col :span="12">
+					<el-form-item label="是否有统一社会信用代码" prop="isUscCode" :rules="[
+						{ required: true, message: '请选择是否有统一社会信用代码', trigger: 'blur' }
+					]">
+						<el-radio-group v-model="inputForm.isUscCode">
+							<el-radio v-for="item in $dictUtils.getDictList('yes_no')" :label="item.value">{{ item.label
+								}}</el-radio>
+						</el-radio-group>
+					</el-form-item>
+				</el-col>
+			</el-row>
+			<el-row :gutter="15">
+				<el-col v-if="inputForm.isUscCode === '1'" :span="12">
+					<el-form-item label="统一社会信用代码" prop="uscCode" :rules="[
+						{ required: true, message: '统一社会信用代码不能为空', trigger: 'blur' }
+					]">
+						<el-input v-model="inputForm.uscCode" placeholder="请填写统一社会信用代码" clearable></el-input>
+						<div class="usc_code_append_message">{{ uscCodeMessage }}</div>
+					</el-form-item>
+				</el-col>
+				<el-col :span="12">
+					<el-form-item label="注册地址" prop="companyAddress" :rules="[
+					]">
+						<el-input v-model="inputForm.companyAddress" placeholder="注册地址" clearable></el-input>
+					</el-form-item>
+				</el-col>
+				<el-col :span="12">
+					<el-form-item label="详细地址" prop="address" :rules="[
+						{ required: true, message: '详细地址不能为空', trigger: 'blur' }
+					]">
+						<el-input v-model="inputForm.address" placeholder="详细地址" clearable></el-input>
+					</el-form-item>
+				</el-col>
+				<el-col :span="12">
+					<el-form-item label="公司电话" prop="mobile" :rules="[
+					]">
+						<el-input v-model="inputForm.mobile" placeholder="公司电话" clearable></el-input>
+					</el-form-item>
+				</el-col>
+				<el-col :span="24">
+					<el-form-item label="备注" prop="remarks1" :rules="[
+					]">
+						<el-input type="textarea" maxlength="500" v-model="inputForm.remarks1" placeholder="请填写备注"
+							show-word-limit></el-input>
+					</el-form-item>
+				</el-col>
+			</el-row>
+			<el-divider content-position="left"><i class="el-icon-document"></i> 合同信息</el-divider>
+			<el-row :gutter="0">
+				<el-col :span="12">
+					<el-form-item label="合同名称" prop="contractName" :rules="[{ required: true, message: '合同名称不能为空', trigger: 'blur' }
+					]">
+						<el-input v-model="inputForm.contractName" placeholder="请输入合同名称" clearable></el-input>
+					</el-form-item>
+				</el-col>
+				<el-col :span="12">
+					<el-form-item label="合同编号" prop="contractNo" :rules="[
+					]">
+						<el-input :disabled="true" v-model="inputForm.contractNo" placeholder="自动生成"
+							clearable></el-input>
+					</el-form-item>
+				</el-col>
+				<el-col :span="12">
+					<el-form-item label="签订日期" prop="signingDate" :rules="[
+						{ required: true, message: '请输入签订日期', trigger: 'blur' }
+					]">
+						<el-date-picker placement="bottom-start" value-format="YYYY-MM-DD"
+							v-model="inputForm.signingDate" style="width: 100%" placeholder="选择日期">
+						</el-date-picker>
+					</el-form-item>
+				</el-col>
+				<el-col :span="12">
+					<el-form-item label="合同生效日期" prop="effectiveDate" :rules="[
+					]">
+						<el-date-picker placement="bottom-start" value-format="YYYY-MM-DD"
+							v-model="inputForm.effectiveDate" style="width: 100%" placeholder="选择日期">
+						</el-date-picker>
+					</el-form-item>
+				</el-col>
+				<el-col :span="12">
+					<el-form-item label="合同终止日期" prop="endTime" :rules="[
+					]">
+						<el-date-picker @change="checkFiledNo" placement="bottom-start" value-format="YYYY-MM-DD"
+							v-model="inputForm.endTime" style="width: 100%" placeholder="选择日期">
+						</el-date-picker>
+					</el-form-item>
+				</el-col>
+				<el-col :span="24">
+					<el-form-item label="备注" prop="remarks2" :rules="[
+					]">
+						<el-input type="textarea" maxlength="500" v-model="inputForm.remarks2" placeholder="请填写备注"
+							show-word-limit></el-input>
+					</el-form-item>
+				</el-col>
+			</el-row>
+			<el-tabs v-model="activeName" type="border-card" @tab-click="tabHandleClick">
+				<el-tab-pane label="客户联系人" name="contact">
+					<span slot="label">客户联系人</span>
+					<el-row :gutter="15">
+						<el-button type="primary" style="margin-bottom: 15px"
+							:disabled="status === 'audit' || status === 'taskFormDetail'"
+							@click="insertEvent('contact')">
+							新增客户联系人
+						</el-button>
+					</el-row>
+					<el-row :gutter="15">
+						<el-form :disabled="status === 'audit' || status === 'taskFormDetail'">
+							<vxe-table border show-overflow show-footer :column-config="{ resizable: true }"
+								ref="contactTable" :key="tableKeyContact" class="vxe-table-element"
+								:data="inputForm.cwProjectClientContactDTOList" style="" highlight-current-row
+								:edit-config="{ trigger: 'click', mode: 'row', showStatus: false, autoClear: true, icon: '-' }">
+								<vxe-table-column align="center" field="name" title="姓名" :edit-render="{}">
+									<template v-slot:edit="scope">
+										<el-input v-model="scope.row.name" placeholder="姓名" clearable></el-input>
+									</template>
+								</vxe-table-column>
+								<vxe-table-column align="center" field="position" title="职务" :edit-render="{}">
+									<template v-slot:edit="scope">
+										<el-input v-model="scope.row.position" placeholder="职务" clearable></el-input>
+									</template>
+								</vxe-table-column>
+								<vxe-table-column align="center" field="contactFirst" title="联系方式1" :edit-render="{}">
+									<template v-slot:edit="scope">
+										<el-input v-model="scope.row.contactFirst"
+											oninput="value=value.replace(/[^\d]/g,'')" placeholder="联系方式1"
+											clearable></el-input>
+									</template>
+								</vxe-table-column>
+								<vxe-table-column align="center" field="contactSecond" title="联系方式2" :edit-render="{}">
+									<template v-slot:edit="scope">
+										<el-input v-model="scope.row.contactSecond"
+											oninput="value=value.replace(/[^\d]/g,'')" placeholder="联系方式2"
+											clearable></el-input>
+									</template>
+								</vxe-table-column>
+								<vxe-table-column align="center" field="remarks" title="备注" :edit-render="{}">
+									<template v-slot:edit="scope">
+										<el-input maxlength="500" v-model="scope.row.remarks" placeholder="备注"
+											clearable></el-input>
+									</template>
+								</vxe-table-column>
+								<vxe-table-column align="center" title="操作" width="100">
+									<template v-slot="scope">
+										<el-button size="small" type="danger"
+											@click="removeEvent(scope.row, scope.$rowIndex, 'contact')">删除</el-button>
+									</template>
+								</vxe-table-column>
+							</vxe-table>
+						</el-form>
+					</el-row>
+				</el-tab-pane>
+				<el-tab-pane label="附件" name="files">
+					<!--        附件-->
+					<UpLoadComponent ref="uploadComponent"></UpLoadComponent>
+				</el-tab-pane>
+
+
+			</el-tabs>
+		</el-form>
+	</div>
+</template>
+
+<script>
+import EnterpriseSearchService from '@/api/cw/common/EnterpriseSearchService'
+import CommonApi from '@/api/cw/common/CommonApi'
+import MaterialManagementService from '@/api/psi/MaterialManagementService'
+import ContractService from '@/api/psi/ContractService'
+import UpLoadComponent from '@/views/common/UpLoadComponent'
+export default {
+	data() {
+		return {
+			validRules: {
+				purchaserAgent: [
+					{ required: true, message: '采购人不能为空' }
+				],
+				procurementOffice: [
+					{ required: true, message: '采购部门不能为空' }
+				],
+				procurementType: [
+					{ required: true, message: '采购类型不能为空' }
+				]
+			},
+			title: '',
+			method: '',
+			visible: false,
+			loading: false,
+			indexRow: '',
+			inputForm: {
+				id: '',
+				createDate: '',
+				name: '',
+				uscCode: '',
+				isUscCode: '',
+				address: '',
+				companyAddress: '',
+				mobile: '',
+				remarks1: '',
+				remarks2: '',
+				contractName: '',
+				signingDate: '',
+				effectiveDate: '',
+				endTime: '',
+				cwProjectClientContactDTOList: [],
+				files: [] // 附件信息
+			},
+			activeName: 'contact',
+			uscCodeMessage: '',
+			nameMessage: '',
+			tableKey: '',
+			tableKeyContact: '2',
+			keyWatch: '',
+			visiblePop: false,
+			gridData: []
+		}
+	},
+	enterpriseSearchService: null,
+	materialManagementService: null,
+	contractService: null,
+	commonApi: null,
+	created() {
+		this.enterpriseSearchService = new EnterpriseSearchService()
+		this.materialManagementService = new MaterialManagementService()
+		this.contractService = new ContractService()
+		this.commonApi = new CommonApi()
+	},
+	props: {
+		businessId: {
+			type: String,
+			default: ''
+		},
+		formReadOnly: {
+			type: Boolean,
+			default: false
+		},
+		status: {
+			type: String,
+			default: ''
+		}
+	},
+	components: {
+		UpLoadComponent,
+	},
+	computed: {
+		bus: {
+			get() {
+				return this.businessId
+			},
+			set(val) {
+				this.businessId = val
+			}
+		},
+		name() {
+			return JSON.parse(localStorage.getItem('user')).name
+		},
+		officeName() {
+			return JSON.parse(localStorage.getItem('user')).officeDTO.name
+		},
+		purchaserAgentId() {
+			return JSON.parse(localStorage.getItem('user')).id
+		},
+		procurementTypeId() {
+			return ''
+		}
+	},
+	watch: {
+		'keyWatch': {
+			handler(newVal) {
+				if (this.commonJS.isNotEmpty(this.bus)) {
+					this.init('', this.bus)
+				} else {
+					this.$nextTick(() => {
+						this.$refs.inputForm.resetFields()
+						if (this.commonJS.isEmpty(this.inputForm.isUscCode)) {
+							this.inputForm.isUscCode = '1'
+						}
+					})
+				}
+			}
+		}
+	},
+	methods: {
+		getKeyWatch(keyWatch) {
+			this.keyWatch = keyWatch
+		},
+		init(method, id) {
+			this.method = method
+			this.inputForm = {
+				id: '',
+				createDate: '',
+				name: '',
+				isUscCode: '',
+				mobile: '',
+				uscCode: '',
+				address: '',
+				companyAddress: '',
+				remarks1: '',
+				remarks2: '',
+				contractName: '',
+				contractNo: '',
+				signingDate: '',
+				effectiveDate: '',
+				endTime: '',
+				cwProjectClientContactDTOList: [],
+				files: [] // 附件信息
+			}
+			this.activeName = 'contact'
+			this.uscCodeMessage = ''
+			this.nameMessage = ''
+			if (method === 'add') {
+				this.title = `新建采购类型`
+			} else if (method === 'edit') {
+				this.title = '修改采购类型'
+			}
+			this.inputForm.id = id
+			this.visible = true
+			this.loading = false
+			this.$nextTick(() => {
+				if (this.formReadOnly === true && this.businessId !== 'false') {
+					method = 'view'
+				}
+				if (this.commonJS.isEmpty(this.inputForm.handledByOffice)) {
+					this.inputForm.handledByOffice = JSON.parse(localStorage.getItem('user')).officeDTO.id
+				}
+				if (this.status === 'audit' || this.status === 'taskFormDetail') {
+					method = 'view'
+				}
+				this.loading = true
+				this.$refs.inputForm.resetFields()
+				this.contractService.findById(this.inputForm.id).then((data) => {
+					if (this.inputForm.id !== 'false') {
+						this.inputForm = this.recover(this.inputForm, data)
+						this.$refs.uploadComponent.newUpload(method, this.inputForm.files, 'reimbursement')
+						this.inputForm = JSON.parse(JSON.stringify(this.inputForm))
+						this.loading = false
+					} else {
+						this.inputForm.cwProjectClientContactDTOList = []
+						this.loading = false
+					}
+				})
+				if (method !== 'edit' && method !== 'view') {
+					this.$refs.uploadComponent.newUpload(method, [], 'reimbursement')
+				}
+			})
+		},
+		// 表单提交
+		doSubmit() {
+			this.$refs['inputForm'].validate((valid) => {
+				if (valid) {
+					this.loading = true
+					if (this.$refs.uploadComponent.checkProgress()) {
+						this.loading = false
+						return
+					}
+					if (this.commonJS.isEmpty(this.inputForm.files)) {
+						this.inputForm.files = []
+					}
+					this.inputForm.id = this.businessId
+					this.inputForm.files = this.$refs.uploadComponent.getDataList()
+					this.contractService.save(this.inputForm).then((data) => {
+						this.close()
+						this.$message.success(data)
+						this.$emit('refreshDataList')
+						this.loading = false
+					}).catch(() => {
+						this.loading = false
+					})
+				}
+			})
+		},
+		close() {
+			this.$refs.inputForm.resetFields()
+			this.inputForm.detailInfos = []
+			this.$refs.uploadComponent.clearUpload()
+			this.visible = false
+			this.nameMessage = ''
+			this.uscCodeMessage = ''
+		},
+		reapplyForm(callback) {
+			this.contractService.findById(this.inputForm.id).then((data) => {
+				if (data.status !== '4') { // 审核状态不是“驳回”,就弹出提示
+					this.$message.error('任务数据已发生改变或不存在,请在待办任务中确认此任务是否存在')
+					throw new Error('任务数据已发生改变或不存在,请在待办任务中确认此任务是否存在')
+				} else {
+					this.startForm(callback)
+				}
+			})
+		},
+		// 暂存
+		async saveForm(callback) {
+			this.loading = true
+			if (this.$refs.uploadComponent.checkProgress()) {
+				this.loading = false
+				return
+			}
+			if (this.commonJS.isEmpty(this.inputForm.files)) {
+				this.inputForm.files = []
+			}
+			this.inputForm.files = this.$refs.uploadComponent.getDataList()
+			this.inputForm.status = '1'
+			this.contractService.save(this.inputForm).then((data) => {
+				callback()
+				this.$refs.inputForm.resetFields()
+				this.loading = false
+			}).catch(() => {
+				this.$refs.inputForm.resetFields()
+				this.loading = false
+			})
+		},
+		// 送审
+		async startForm(callback) {
+			this.$refs['inputForm'].validate(async (valid) => {
+				if (valid) {
+					this.loading = true
+					if (this.$refs.uploadComponent.checkProgress()) {
+						this.loading = false
+						return
+					}
+					if (this.commonJS.isEmpty(this.inputForm.files)) {
+						this.inputForm.files = []
+					}
+					if (this.commonJS.isEmpty(this.inputForm.cwProjectClientContactDTOList)) {
+						this.$message.error('最少添加一个联系人')
+						this.loading = false
+						throw new Error()
+					}
+					this.inputForm.files = this.$refs.uploadComponent.getDataList()
+					this.inputForm.status = '2'
+					this.contractService.save(this.inputForm).then((data) => {
+						callback(data.businessTable, data.businessId, this.inputForm)
+						this.$refs.inputForm.resetFields()
+						this.loading = false
+					}).catch(() => {
+						this.$refs.inputForm.resetFields()
+						this.loading = false
+					})
+				}
+			})
+		},
+		// 通过
+		async agreeForm(callback) {
+			this.$refs['inputForm'].validate(async (valid) => {
+				if (valid) {
+					this.loading = true
+					if (this.$refs.uploadComponent.checkProgress()) {
+						this.loading = false
+						return
+					}
+					if (this.commonJS.isEmpty(this.inputForm.files)) {
+						this.inputForm.files = []
+					}
+					this.inputForm.files = this.$refs.uploadComponent.getDataList()
+					this.inputForm.status = '5'
+					this.contractService.save(this.inputForm).then((data) => {
+						callback(data.businessTable, data.businessId, this.inputForm)
+						this.loading = false
+					}).catch(() => {
+						this.loading = false
+					})
+					// this.commonApi.getTaskNameByProcInsId(this.inputForm.procInsId).then((data) => {
+					//   if (this.commonJS.isNotEmpty(data)) {
+					//     console.log('进来了', data)
+					//     if (data === '公司领导审批') {
+					//       this.inputForm.status = '5'
+					//     }
+					//   }
+					//   this.contractService.save(this.inputForm).then((data) => {
+					//     callback(data.businessTable, data.businessId, this.inputForm)
+					//     this.loading = false
+					//   }).catch(() => {
+					//     this.loading = false
+					//   })
+					// })
+				}
+			})
+		},
+		async updateStatusById(type, callback) {
+			if (await this.$refs.uploadComponent.checkProgress()) {
+				this.loading = false
+				throw new Error()
+			} else {
+				if (type === 'reject' || type === 'reback') {
+					this.contractService.findById(this.inputForm.id).then((data) => {
+						if (data.status !== '2') { // status的值不等于“审核中”,就弹出提示
+							this.$message.error('任务数据已发生改变或不存在,请在待办任务中确认此任务是否存在')
+							throw new Error()
+						} else {
+							if (type === 'reject') {
+								// 驳回
+								this.inputForm.status = '4'
+							}
+							if (type === 'reback') {
+								// 撤回
+								this.inputForm.status = '3'
+							}
+							if (type === 'reject' || type === 'reback') {
+								let param = { status: this.inputForm.status, id: this.inputForm.id }
+								this.contractService.updateStatusById(param).then(() => {
+									callback()
+								})
+							}
+						}
+					})
+				} else if (type === 'hold') {
+					this.contractService.findById(this.inputForm.id).then((data) => {
+						if (data.status !== '4') { // status的值不等于“驳回”就弹出提示
+							this.$message.error('任务数据已发生改变或不存在,请在待办任务中确认此任务是否存在')
+							throw new Error()
+						} else {
+							// 终止
+							let param = { status: '1', id: this.inputForm.id }
+							this.contractService.updateStatusById(param).then(() => {
+								callback()
+							})
+						}
+					})
+				}
+			}
+		},
+		async getPopTable() {
+			let name = this.inputForm.name
+			if (this.commonJS.isNotEmpty(name)) {
+				await this.enterpriseSearchService.enterpriseSearchByName(name).then((data) => {
+					this.gridData = data.items
+					this.$refs.pops.updatePopper()
+					this.tableKey = Math.random()
+				})
+			}
+			this.$refs.pops.updatePopper()
+		},
+		closePop() {
+			this.visiblePop = false
+		},
+		rowStyle(event) {
+			return 'cursor:pointer;'
+		},
+		async rowClick(event) {
+			let id = this.gridData[event.rowIndex].companyid
+			await this.enterpriseSearchService.enterpriseTicketInfo(id).then((data) => {
+				this.inputForm.name = data.ENTNAME
+				this.inputForm.uscCode = data.UNCID
+				this.inputForm.address = data.OPLOC
+			})
+			this.visiblePop = false
+		},
+		tabHandleClick(event) {
+			// console.log(event)
+		},
+		insertEvent(type) {
+			if (type === 'contact') {
+				let d = {
+					contactFirst: '',
+					contactSecond: '',
+					email: '',
+					fax: '',
+					name: '',
+					officeId: '',
+					position: '',
+					remarks: '',
+					sex: ''
+				}
+				if (this.commonJS.isEmpty(this.inputForm.cwProjectClientContactDTOList)) {
+					this.inputForm.cwProjectClientContactDTOList = []
+				}
+				this.$refs.contactTable.insertAt(d)
+				this.inputForm.cwProjectClientContactDTOList.push(d)
+				this.tableKeyContact = Math.random()
+			}
+		},
+		// 删除
+		removeEvent(row, rowIndex, type) {
+			if (type === 'contact') {
+				this.$refs.contactTable.remove(row)
+				this.inputForm.cwProjectClientContactDTOList.splice(rowIndex, 1)
+			}
+		},
+		checkFiledNo() {
+			console.log('进来了时间比较')
+			// eslint-disable-next-line no-unused-vars
+			let date1 = this.inputForm.effectiveDate
+			// eslint-disable-next-line no-unused-vars
+			let date2 = this.inputForm.endTime
+			if (Date.parse(this.inputForm.endTime) < Date.parse(this.inputForm.effectiveDate)) {
+				this.$message.warning(`合同终止日期要大于合同生效日期`)
+				this.inputForm.endTime = ''
+			}
+		}
+	}
+}
+</script>
+<style scoped>
+/deep/ .el-input-number .el-input__inner {
+	text-align: left;
+}
+</style>
+<style>
+.usc_code_append_message {
+	color: #F56C6C;
+	font-size: 12px;
+	line-height: 1;
+	padding-top: 4px;
+	position: absolute;
+	top: 100%;
+	left: 0;
+}
+</style>

+ 369 - 0
src/views/psiManagement/contract/ContractList.vue

@@ -0,0 +1,369 @@
+<template>
+	<div class="page">
+		<el-form :inline="true" class="query-form m-b-10" v-if="searchVisible" ref="searchForm" :model="searchForm"
+			@keyup.enter.native="refreshList()" @submit.native.prevent>
+			<!-- 搜索框-->
+			<el-form-item label="客户名称" prop="name">
+				<el-input v-model="searchForm.name" placeholder="请输入客户名称" clearable></el-input>
+			</el-form-item>
+			<el-form-item label="合同名称" prop="contractName">
+				<el-input v-model="searchForm.contractName" placeholder="请输入合同名称" clearable></el-input>
+			</el-form-item>
+			<el-form-item v-if="showHideItem" label="状态" prop="status">
+				<el-select v-model="searchForm.status" placeholder="请选择" style="width:100%;">
+					<el-option v-for="item in $dictUtils.getDictList('cw_status')" :key="item.value" :label="item.label"
+						:value="item.value">
+					</el-option>
+				</el-select>
+			</el-form-item>
+			<el-form-item v-if="showHideItem" label="合同生效日期" prop="effectiveDates">
+				<el-date-picker placement="bottom-start" format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss"
+					v-model="searchForm.effectiveDates" type="datetimerange" range-separator="至"
+					start-placeholder="开始日期" end-placeholder="结束日期">
+				</el-date-picker>
+			</el-form-item>
+
+			<el-form-item>
+				<el-button type="default" @click="showHide" :icon="showHideIcon">{{ showHideName }}</el-button>
+				<el-button type="primary" @click="refreshList()" icon="el-icon-search">查询</el-button>
+				<el-button @click="resetSearch()" icon="el-icon-refresh-right">重置</el-button>
+			</el-form-item>
+		</el-form>
+		<div class="jp-table top" style="">
+			<vxe-toolbar :refresh="{ query: refreshList }" custom>
+				<template #buttons>
+					<el-button v-if="hasPermission('contract:add')" type="primary" icon="el-icon-plus"
+						@click="start()">新建</el-button>
+				</template>
+				<template #tools>
+					<vxe-button text type="primary" :title="searchVisible ? '收起检索' : '展开检索'" icon="vxe-icon-search"
+						class="tool-btn" @click="searchVisible = !searchVisible"></vxe-button>
+				</template>
+			</vxe-toolbar>
+			<div style="height: calc(100% - 90px)">
+				<vxe-table :key="tableKey" border="inner" auto-resize resizable height="auto" :loading="loading"
+					ref="clientTable" show-header-overflow show-overflow highlight-hover-row :menu-config="{}"
+					@sort-change="sortChangeHandle" :sort-config="{ remote: true }" :data="dataList"
+					:checkbox-config="{}">
+					<vxe-column type="seq" width="60" title="序号"></vxe-column>
+					<vxe-column min-width="160" align="center" title="合同编号" field="contractNo"></vxe-column>
+					<vxe-column min-width="160" align="center" title="合同名称" field="contractName">
+						<template slot-scope="scope">
+							<el-link type="primary" :underline="false" v-if="hasPermission('psi:list')"
+								@click="view(scope.row.id)">{{ scope.row.contractName }}</el-link>
+							<el-link type="primary" :underline="false" v-else-if="hasPermission('psi:list')"
+								@click="view(scope.row.id,)">{{ scope.row.contractName }}</el-link>
+							<span v-else>{{ scope.row.contractName }}</span>
+						</template>
+					</vxe-column>
+					<vxe-column min-width="160" align="center" title="客户名称" field="name"></vxe-column>
+					<vxe-column min-width="160" align="center" title="统一社会信用代码" field="uscCode"></vxe-column>
+					<vxe-column min-width="160" align="center" title="详细地址" field="address"></vxe-column>
+					<vxe-column min-width="160" align="center" title="合同生效日期" field="effectiveDate"></vxe-column>
+					<vxe-column min-width="160" align="center" title="合同终止日期" field="endTime"></vxe-column>
+					<vxe-column min-width="150px" align="center" fixed="right" title="状态" field="status">
+						<template #default="scope">
+							<el-button @click="detail(scope.row)" effect="dark"
+								:type="$dictUtils.getDictLabel('cw_status_flag', scope.row.status, '-')">
+								{{ $dictUtils.getDictLabel("cw_status", scope.row.status, '-') }}
+							</el-button>
+						</template>
+					</vxe-column>
+
+					<vxe-column title="操作" width="150px" fixed="right" align="center">
+						<template slot-scope="scope">
+							<el-button
+								v-if="hasPermission('contract:edit') && scope.row.createBy === $store.state.user.id && (scope.row.status === '1' || scope.row.status === '3')"
+								type="text" size="small" @click="push(scope.row)">修改</el-button>
+							<el-button
+								v-else-if="hasPermission('contract:edit') && isAdmin && (scope.row.status === '1' || scope.row.status === '3' || scope.row.status === '4' || scope.row.status === '5')"
+								type="text" size="small" @click="edit(scope.row.id)">修改</el-button>
+							<el-button
+								v-if="hasPermission('contract:edit') && scope.row.createBy === $store.state.user.id && scope.row.status === '2'"
+								type="text" size="small" @click="reback(scope.row)">撤回</el-button>
+							<el-button
+								v-if="hasPermission('contract:del') && scope.row.createBy === $store.state.user.id && (scope.row.status === '1' || scope.row.status === '3')"
+								type="text" size="small" @click="del(scope.row.id)">删除</el-button>
+							<el-button
+								v-else-if="hasPermission('contract:del') && isAdmin && (scope.row.status === '1' || scope.row.status === '3' || scope.row.status === '4' || scope.row.status === '5')"
+								type="text" size="small" @click="del(scope.row.id)">删除</el-button>
+						</template>
+					</vxe-column>
+				</vxe-table>
+				<vxe-pager background :current-page="tablePage.currentPage" :page-size="tablePage.pageSize"
+					:total="tablePage.total" :page-sizes="[10, 20, 100, 1000, { label: '全量数据', value: 1000000 }]"
+					:layouts="['PrevPage', 'JumpNumber', 'NextPage', 'FullJump', 'Sizes', 'Total']"
+					@page-change="currentChangeHandle">
+				</vxe-pager>
+				<UpdateContractInfoForm ref="updateContractInfoForm" @refreshDataList="refreshList">
+				</UpdateContractInfoForm>
+			</div>
+		</div>
+	</div>
+</template>
+
+<script>
+import UpdateContractInfoForm from './UpdateContractInfoForm'
+import MaterialManagementService from '@/api/psi/MaterialManagementService'
+import ContractService from '@/api/psi/ContractService'
+import taskService from '@/api/flowable/taskService'
+import processService from '@/api/flowable/processService'
+import pick from 'lodash.pick'
+import userService from '@/api/sys/userService'
+export default {
+	data() {
+		return {
+			searchVisible: true,
+			showHideItem: false,
+			showHideIcon: 'el-icon-arrow-down',
+			showHideName: '展示',
+			num: 0,
+			searchForm: {
+				contractName: '',
+				name: '',
+				handledBy: '',
+				handledByOffice: '',
+				status: '',
+				effectiveDates: [],
+				procurementType: '',
+				createBy: ''
+			},
+			dataList: [],
+			tablePage: {
+				total: 0,
+				currentPage: 1,
+				pageSize: 10,
+				orders: []
+			},
+			tableKey: '',
+			loading: false,
+			processDefinitionAuditId: '',
+			procDefAuditKey: '',
+			isAdmin: false,
+			create: ''
+		}
+	},
+	materialManagementService: null,
+	contractService: null,
+	created() {
+		this.materialManagementService = new MaterialManagementService()
+		this.contractService = new ContractService()
+	},
+	components: {
+		UpdateContractInfoForm,
+	},
+	computed: {
+		userName() {
+			return this.$store.state.user.name
+		},
+		user() {
+			this.createName = this.$store.state.user.name
+			return this.$store.state.user
+		}
+	},
+	mounted() {
+		this.refreshList()
+	},
+	activated() {
+		this.refreshList()
+	},
+	methods: {
+		showHide() {
+			if (this.showHideItem === false) {
+				this.showHideItem = true
+				this.showHideIcon = 'el-icon-arrow-up'
+				this.showHideName = '隐藏'
+			} else {
+				this.showHideItem = false
+				this.showHideIcon = 'el-icon-arrow-down'
+				this.showHideName = '展示'
+			}
+		},
+		// 新增
+		add() {
+			// this.$refs.reportManagementForm.init('add', '')
+		},
+		// 修改
+		edit(id) {
+			id = id || this.$refs.clientTable.getCheckboxRecords().map(item => {
+				return item.id
+			})[0]
+			this.$refs.updateContractInfoForm.init('edit', id)
+		},
+		// 查看
+		view(id) {
+			this.$refs.updateContractInfoForm.init('view', id)
+		},
+		// 查询当前用户是否是管理员用户
+		checkIsAdmin() {
+			userService.is().then((data) => {
+				this.isAdmin = data
+			})
+		},
+		// 获取数据列表
+		refreshList() {
+			this.loading = true
+			this.contractService.list({
+				'current': this.tablePage.currentPage,
+				'size': this.tablePage.pageSize,
+				'orders': this.tablePage.orders,
+				...this.searchForm
+			}).then((data) => {
+				this.dataList = data.records
+				this.tablePage.total = data.total
+				this.tableKey = Math.random()
+				this.loading = false
+			})
+			this.checkIsAdmin()
+			processService.getByName('物资管理-合同').then((data) => {
+				if (!this.commonJS.isEmpty(data.id)) {
+					this.processDefinitionAuditId = data.id
+					this.procDefAuditKey = data.key
+				}
+			})
+		},
+		// 当前页
+		currentChangeHandle({ currentPage, pageSize }) {
+			this.tablePage.currentPage = currentPage
+			this.tablePage.pageSize = pageSize
+			this.refreshList()
+		},
+		// 排序
+		sortChangeHandle(column) {
+			this.tablePage.orders = []
+			if (column.order != null) {
+				this.tablePage.orders.push({ column: this.$utils.toLine(column.property), asc: column.order === 'asc' })
+			}
+			this.refreshList()
+		},
+		// 删除
+		del(id) {
+			let ids = id || this.$refs.clientTable.getCheckboxRecords().map(item => {
+				return item.id
+			}).join(',')
+			this.$confirm(`确定删除所选项吗?`, '提示', {
+				confirmButtonText: '确定',
+				cancelButtonText: '取消',
+				type: 'warning'
+			}).then(() => {
+				this.loading = true
+				this.contractService.remove(ids).then((data) => {
+					this.$message.success(data)
+					this.refreshList()
+					this.loading = false
+				})
+			})
+		},
+		resetSearch() {
+			this.$refs.searchForm.resetFields()
+			this.refreshList()
+		},
+		start() {
+			// 读取流程表单
+			let tabTitle = `发起流程【物资管理-合同申请】`
+			let processTitle = `${this.userName} 在 ${this.moment(new Date()).format('YYYY-MM-DD HH:mm')} 发起了 [物资管理-合同申请]`
+			taskService.getTaskDef({
+				procDefId: this.processDefinitionAuditId,
+				status: 'startAndHold'
+			}).then((data) => {
+				this.$router.push({
+					path: '/flowable/task/TaskForm',
+					query: {
+						...pick(data, 'formType', 'formUrl', 'procDefKey', 'taskDefKey', 'procInsId', 'procDefId', 'taskId', 'status', 'title'),
+						procDefId: this.processDefinitionAuditId,
+						procDefKey: this.procDefAuditKey,
+						status: 'startAndHold',
+						title: tabTitle,
+						formType: data.formType,
+						formUrl: data.formUrl,
+						formTitle: processTitle,
+						businessId: 'false',
+						isShow: false,
+						routePath: '/materialManagement/contract/ContractList'
+					}
+				})
+			})
+		},
+		// 发起物资管理-合同申请
+		push(row) {
+			// 读取流程表单
+			let title = `发起流程【物资管理-合同申请】`
+			let processTitle = `${this.userName} 在 ${this.moment(new Date()).format('YYYY-MM-DD HH:mm')} 发起了[物资管理-合同申请]`
+			let status = 'startAndHold'
+			if (row.status === '3') {
+				status = 'startAndClose'
+			} else if (row.status === '4') {
+				status = 'reapplyFlag'
+			}
+			taskService.getTaskDef({
+				procDefId: this.processDefinitionAuditId,
+				businessId: row.id,
+				businessTable: 'material_management_pruchase_request_basics'
+			}).then((data) => {
+				this.$router.push({
+					path: '/flowable/task/TaskForm',
+					query: {
+						...pick(data, 'formType', 'formUrl', 'procDefKey', 'taskDefKey', 'procInsId', 'procDefId', 'taskId', 'status', 'title'),
+						procDefId: this.processDefinitionAuditId,
+						procDefKey: this.procDefAuditKey,
+						title: title,
+						formType: data.formType,
+						formUrl: data.formUrl,
+						formTitle: processTitle,
+						businessTable: 'material_management_pruchase_request_basics',
+						businessId: row.id,
+						isShow: 'false',
+						status: status,
+						routePath: '/materialManagement/contract/ContractList'
+					}
+				})
+			})
+		},
+		// 查看客户登记流程结果
+		detail(row) {
+			if (row.status !== '0' && row.status !== '1') {
+				// eslint-disable-next-line eqeqeq
+				taskService.getTaskDef({
+					procInsId: row.procInsId,
+					procDefId: this.processDefinitionAuditId
+				}).then((data) => {
+					this.$router.push({
+						path: '/flowable/task/TaskFormDetail',
+						query: {
+							...pick(data, 'formType', 'formUrl', 'procDefKey', 'taskDefKey', 'procInsId', 'procDefId', 'taskId', 'status', 'title'),
+							isShow: 'false',
+							readOnly: true,
+							title: '质控管理' + '流程详情',
+							formTitle: '质控管理' + '流程详情',
+							businessId: row.id,
+							status: 'reback'
+						}
+					})
+				})
+			}
+		},
+		// 撤回报告流程
+		reback(row) {
+			this.$confirm(`确定要撤回该申请吗?`, '提示', {
+				confirmButtonText: '确定',
+				cancelButtonText: '取消',
+				type: 'warning'
+			}).then(async () => {
+				await this.contractService.findById(row.id).then((data) => {
+					if (data.status !== '2') { // status的值不等于“审核中”,就弹出提示
+						this.$message.error('数据已发生改变或不存在,请刷新数据')
+						this.refreshList()
+					} else {
+						processService.revokeProcIns(row.procInsId).then((data) => {
+							let form = { status: '3', id: row.id }
+							this.contractService.updateStatusById(form)
+							this.$message.success(data)
+							this.refreshList()
+						})
+					}
+				})
+			})
+		}
+	}
+}
+</script>

+ 515 - 0
src/views/psiManagement/contract/UpdateContractInfoForm.vue

@@ -0,0 +1,515 @@
+<template>
+	<div>
+		<el-dialog :title="title" :close-on-click-modal="false" draggable width="1500px" @close="close"
+			@keyup.enter.native="doSubmit" v-model="visible" append-to-body>
+			<el-form :model="inputForm" ref="inputForm" v-loading="loading" :class="method === 'view' ? 'readonly' : ''"
+				:disabled="method === 'view'" label-width="200px" @submit.native.prevent>
+
+				<el-divider content-position="left"><i class="el-icon-document"></i> 客户信息</el-divider>
+				<el-row :gutter="0">
+					<el-col :span="10">
+						<el-form-item label="客户名称" prop="name" :rules="[
+						]">
+							<span slot="label"><span style="color: red;border-top: 20px">*</span> 客户名称</span>
+							<el-input maxlength="64" v-model="inputForm.name" placeholder="请输入客户名称"
+								clearable></el-input>
+							<div class="usc_code_append_message">{{ nameMessage }}</div>
+						</el-form-item>
+					</el-col>
+					<el-col :span="2">
+						<el-popover v-model="visiblePop" placement="left" width="400" height="800" trigger="click"
+							:popper-options="{ boundariesElement: 'viewport', removeOnDestroy: true }" ref="pops">
+							<vxe-table border="inner" auto-resize resizable :row-config="{ isHover: true }"
+								:data="gridData" :checkbox-config="{}" :row-style="rowStyle" :key="tableKey"
+								@cell-click="rowClick" :show-header="false">
+								<vxe-column title="" field="entname"></vxe-column>
+							</vxe-table>
+							<el-button type="info" slot="reference" @click="getPopTable" style="width: 100%"
+								plain>查询</el-button>
+						</el-popover>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="是否有统一社会信用代码" prop="isUscCode" :rules="[
+							{ required: true, message: '请选择是否有统一社会信用代码', trigger: 'blur' }
+						]">
+							<el-radio-group v-model="inputForm.isUscCode">
+								<el-radio v-for="item in $dictUtils.getDictList('yes_no')"
+									:label="item.value">{{ item.label }}</el-radio>
+							</el-radio-group>
+						</el-form-item>
+					</el-col>
+				</el-row>
+				<el-row :gutter="15">
+					<el-col v-if="inputForm.isUscCode === '1'" :span="12">
+						<el-form-item label="统一社会信用代码" prop="uscCode" :rules="[
+							{ required: true, message: '统一社会信用代码不能为空', trigger: 'blur' }
+						]">
+							<el-input v-model="inputForm.uscCode" placeholder="请填写统一社会信用代码" clearable></el-input>
+							<div class="usc_code_append_message">{{ uscCodeMessage }}</div>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="注册地址" prop="companyAddress" :rules="[
+						]">
+							<el-input v-model="inputForm.companyAddress" placeholder="注册地址" clearable></el-input>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="详细地址" prop="address" :rules="[
+							{ required: true, message: '详细地址不能为空', trigger: 'blur' }
+						]">
+							<el-input v-model="inputForm.address" placeholder="详细地址" clearable></el-input>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="公司电话" prop="mobile" :rules="[
+						]">
+							<el-input v-model="inputForm.mobile" placeholder="公司电话" clearable></el-input>
+						</el-form-item>
+					</el-col>
+					<el-col :span="24">
+						<el-form-item label="备注" prop="remarks1" :rules="[
+						]">
+							<el-input type="textarea" maxlength="500" v-model="inputForm.remarks1" placeholder="请填写备注"
+								show-word-limit></el-input>
+						</el-form-item>
+					</el-col>
+				</el-row>
+				<el-divider content-position="left"><i class="el-icon-document"></i> 合同信息</el-divider>
+				<el-row :gutter="0">
+					<el-col :span="12">
+						<el-form-item label="合同名称" prop="contractName" :rules="[{ required: true, message: '合同名称不能为空', trigger: 'blur' }
+						]">
+							<el-input v-model="inputForm.contractName" placeholder="请输入合同名称" clearable></el-input>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="合同编号" prop="contractNo" :rules="[
+						]">
+							<el-input :disabled="true" v-model="inputForm.contractNo" placeholder="自动生成"
+								clearable></el-input>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="签订日期" prop="signingDate" :rules="[
+							{ required: true, message: '请输入签订日期', trigger: 'blur' }
+						]">
+							<el-date-picker placement="bottom-start" value-format="YYYY-MM-DD"
+								v-model="inputForm.signingDate" style="width: 100%" placeholder="选择日期">
+							</el-date-picker>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="合同生效日期" prop="effectiveDate" :rules="[
+							{ required: true, message: '请输入合同生效日期', trigger: 'blur' }
+						]">
+							<el-date-picker placement="bottom-start" value-format="YYYY-MM-DD"
+								v-model="inputForm.effectiveDate" style="width: 100%" placeholder="选择日期">
+							</el-date-picker>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="合同终止日期" prop="endTime" :rules="[
+							{ required: true, message: '请输入合同终止日期', trigger: 'blur' }
+						]">
+							<el-date-picker @change="checkFiledNo" placement="bottom-start" value-format="YYYY-MM-DD"
+								v-model="inputForm.endTime" style="width: 100%" placeholder="选择日期">
+							</el-date-picker>
+						</el-form-item>
+					</el-col>
+					<el-col :span="24">
+						<el-form-item label="备注" prop="remarks2" :rules="[
+						]">
+							<el-input type="textarea" maxlength="500" v-model="inputForm.remarks2" placeholder="请填写备注"
+								show-word-limit></el-input>
+						</el-form-item>
+					</el-col>
+				</el-row>
+				<el-tabs v-model="activeName" type="border-card" @tab-click="tabHandleClick">
+					<el-tab-pane label="客户联系人" name="contact">
+						<span slot="label"><span style="color: red;border-top: 20px">*</span> 客户联系人</span>
+						<el-row :gutter="15">
+							<el-button type="primary" style="margin-bottom: 15px"
+								:disabled="status === 'audit' || status === 'taskFormDetail' || method === 'view'"
+								@click="insertEvent('contact')">
+								新增客户联系人
+							</el-button>
+						</el-row>
+						<el-row :gutter="15">
+							<el-form :disabled="status === 'audit' || status === 'taskFormDetail' || method === 'view'">
+								<vxe-table border show-overflow show-footer :column-config="{ resizable: true }"
+									ref="contactTable" :key="tableKeyContact" class="vxe-table-element"
+									:data="inputForm.cwProjectClientContactDTOList" style="" highlight-current-row
+									:edit-config="{ trigger: 'click', mode: 'row', showStatus: false, autoClear: true, icon: '-' }">
+									<vxe-table-column align="center" field="name" title="姓名" :edit-render="{}">
+										<template v-slot:edit="scope">
+											<el-input v-model="scope.row.name" placeholder="姓名" clearable></el-input>
+										</template>
+									</vxe-table-column>
+									<vxe-table-column align="center" field="position" title="职务" :edit-render="{}">
+										<template v-slot:edit="scope">
+											<el-input v-model="scope.row.position" placeholder="职务"
+												clearable></el-input>
+										</template>
+									</vxe-table-column>
+									<vxe-table-column align="center" field="contactFirst" title="联系方式1"
+										:edit-render="{}">
+										<template v-slot:edit="scope">
+											<el-input v-model="scope.row.contactFirst"
+												oninput="value=value.replace(/[^\d]/g,'')" placeholder="联系方式1"
+												clearable></el-input>
+										</template>
+									</vxe-table-column>
+									<vxe-table-column align="center" field="contactSecond" title="联系方式2"
+										:edit-render="{}">
+										<template v-slot:edit="scope">
+											<el-input v-model="scope.row.contactSecond"
+												oninput="value=value.replace(/[^\d]/g,'')" placeholder="联系方式2"
+												clearable></el-input>
+										</template>
+									</vxe-table-column>
+									<vxe-table-column align="center" field="remarks" title="备注" :edit-render="{}">
+										<template v-slot:edit="scope">
+											<el-input maxlength="500" v-model="scope.row.remarks" placeholder="备注"
+												clearable></el-input>
+										</template>
+									</vxe-table-column>
+									<vxe-table-column align="center" title="操作" width="100">
+										<template v-slot="scope">
+											<el-button size="small" type="danger"
+												@click="removeEvent(scope.row, scope.$rowIndex, 'contact')">删除</el-button>
+										</template>
+									</vxe-table-column>
+								</vxe-table>
+							</el-form>
+						</el-row>
+					</el-tab-pane>
+					<el-tab-pane label="附件" name="files">
+						<!--        附件-->
+						<UpLoadComponent ref="uploadComponent"></UpLoadComponent>
+					</el-tab-pane>
+
+
+				</el-tabs>
+			</el-form>
+			<template #footer>
+				<span class="dialog-footer">
+					<el-button @click="close()" icon="el-icon-circle-close">关闭</el-button>
+					<el-button type="primary" v-if="method != 'view'" @click="doSubmit()" icon="el-icon-circle-check"
+						v-noMoreClick>确定</el-button>
+				</span>
+			</template>
+		</el-dialog>
+	</div>
+</template>
+
+<script>
+import EnterpriseSearchService from '@/api/cw/common/EnterpriseSearchService'
+import CommonApi from '@/api/cw/common/CommonApi'
+import MaterialManagementService from '@/api/psi/MaterialManagementService'
+import ContractService from '@/api/psi/ContractService'
+import UpLoadComponent from '@/views/common/UpLoadComponent'
+export default {
+	data() {
+		return {
+			validRules: {
+				purchaserAgent: [
+					{ required: true, message: '采购人不能为空' }
+				],
+				procurementOffice: [
+					{ required: true, message: '采购部门不能为空' }
+				],
+				procurementType: [
+					{ required: true, message: '采购类型不能为空' }
+				]
+			},
+			title: '',
+			method: '',
+			visible: false,
+			loading: false,
+			indexRow: '',
+			inputForm: {
+				id: '',
+				createDate: '',
+				name: '',
+				uscCode: '',
+				isUscCode: '',
+				address: '',
+				companyAddress: '',
+				mobile: '',
+				remarks1: '',
+				remarks2: '',
+				contractName: '',
+				contractNo: '',
+				signingDate: '',
+				effectiveDate: '',
+				endTime: '',
+				cwProjectClientContactDTOList: [],
+				files: [] // 附件信息
+			},
+			activeName: 'contact',
+			uscCodeMessage: '',
+			nameMessage: '',
+			tableKey: '',
+			tableKeyContact: '2',
+			keyWatch: '',
+			visiblePop: false,
+			gridData: []
+		}
+	},
+	enterpriseSearchService: null,
+	materialManagementService: null,
+	contractService: null,
+	commonApi: null,
+	created() {
+		this.enterpriseSearchService = new EnterpriseSearchService()
+		this.materialManagementService = new MaterialManagementService()
+		this.contractService = new ContractService()
+		this.commonApi = new CommonApi()
+	},
+	props: {
+		businessId: {
+			type: String,
+			default: ''
+		},
+		formReadOnly: {
+			type: Boolean,
+			default: false
+		},
+		status: {
+			type: String,
+			default: ''
+		}
+	},
+	components: {
+		UpLoadComponent,
+	},
+	computed: {
+		bus: {
+			get() {
+				return this.businessId
+			},
+			set(val) {
+				this.businessId = val
+			}
+		},
+		name() {
+			return JSON.parse(localStorage.getItem('user')).name
+		},
+		officeName() {
+			return JSON.parse(localStorage.getItem('user')).officeDTO.name
+		},
+		purchaserAgentId() {
+			return JSON.parse(localStorage.getItem('user')).id
+		},
+		procurementTypeId() {
+			return ''
+		}
+	},
+	watch: {
+		'keyWatch': {
+			handler(newVal) {
+				if (this.commonJS.isNotEmpty(this.bus)) {
+					this.init('', this.bus)
+				} else {
+					this.$nextTick(() => {
+						this.$refs.inputForm.resetFields()
+					})
+				}
+			}
+		}
+	},
+	methods: {
+		getKeyWatch(keyWatch) {
+			this.keyWatch = keyWatch
+		},
+		init(method, id) {
+			this.method = method
+			this.inputForm = {
+				id: '',
+				createDate: '',
+				name: '',
+				isUscCode: '',
+				mobile: '',
+				uscCode: '',
+				address: '',
+				companyAddress: '',
+				remarks1: '',
+				remarks2: '',
+				contractName: '',
+				signingDate: '',
+				effectiveDate: '',
+				endTime: '',
+				cwProjectClientContactDTOList: [],
+				files: [] // 附件信息
+			}
+			this.activeName = 'contact'
+			this.uscCodeMessage = ''
+			this.nameMessage = ''
+			if (method === 'add') {
+				this.title = `新建采购类型`
+			} else if (method === 'edit') {
+				this.title = '修改合同信息'
+			} else if (method === 'view') {
+				this.title = '查看合同信息'
+			}
+			this.inputForm.id = id
+			this.visible = true
+			this.loading = false
+			this.$nextTick(() => {
+				if (this.formReadOnly === true && this.businessId !== 'false') {
+					method = 'view'
+				}
+				if (this.commonJS.isEmpty(this.inputForm.handledByOffice)) {
+					this.inputForm.handledByOffice = JSON.parse(localStorage.getItem('user')).officeDTO.id
+				}
+				if (this.status === 'audit' || this.status === 'taskFormDetail') {
+					method = 'view'
+				}
+				this.loading = true
+				this.$refs.inputForm.resetFields()
+				this.contractService.findById(this.inputForm.id).then((data) => {
+					if (this.inputForm.id !== 'false') {
+						this.inputForm = this.recover(this.inputForm, data)
+						this.$refs.uploadComponent.newUpload(method, this.inputForm.files, 'reimbursement')
+						this.inputForm = JSON.parse(JSON.stringify(this.inputForm))
+						this.loading = false
+					} else {
+						this.inputForm.cwProjectClientContactDTOList = []
+						this.loading = false
+					}
+				})
+				if (method !== 'edit' && method !== 'view') {
+					this.$refs.uploadComponent.newUpload(method, [], 'reimbursement')
+				}
+			})
+		},
+		// 表单提交
+		doSubmit() {
+			this.$refs['inputForm'].validate((valid) => {
+				if (valid) {
+					this.loading = true
+					if (this.$refs.uploadComponent.checkProgress()) {
+						this.loading = false
+						return
+					}
+					if (this.commonJS.isEmpty(this.inputForm.files)) {
+						this.inputForm.files = []
+					}
+					this.inputForm.files = this.$refs.uploadComponent.getDataList()
+					this.contractService.save(this.inputForm).then((data) => {
+						this.$emit('refreshDataList')
+						this.loading = false
+						this.close()
+						// this.$message.success(data)
+					}).catch(() => {
+						this.loading = false
+					})
+				}
+			})
+		},
+		close() {
+			this.$refs.inputForm.resetFields()
+			this.inputForm.detailInfos = []
+			this.$refs.uploadComponent.clearUpload()
+			this.visible = false
+			this.nameMessage = ''
+			this.uscCodeMessage = ''
+		},
+		reapplyForm(callback) {
+			this.contractService.findById(this.inputForm.id).then((data) => {
+				if (data.status !== '4') { // 审核状态不是“驳回”,就弹出提示
+					this.$message.error('任务数据已发生改变或不存在,请在待办任务中确认此任务是否存在')
+					throw new Error('任务数据已发生改变或不存在,请在待办任务中确认此任务是否存在')
+				} else {
+					this.startForm(callback)
+				}
+			})
+		},
+		async getPopTable() {
+			let name = this.inputForm.name
+			if (this.commonJS.isNotEmpty(name)) {
+				await this.enterpriseSearchService.enterpriseSearchByName(name).then((data) => {
+					this.gridData = data.items
+					this.$refs.pops.updatePopper()
+					this.tableKey = Math.random()
+				})
+			}
+			this.$refs.pops.updatePopper()
+		},
+		closePop() {
+			this.visiblePop = false
+		},
+		rowStyle(event) {
+			return 'cursor:pointer;'
+		},
+		async rowClick(event) {
+			let id = this.gridData[event.rowIndex].companyid
+			await this.enterpriseSearchService.enterpriseTicketInfo(id).then((data) => {
+				this.inputForm.name = data.ENTNAME
+				this.inputForm.uscCode = data.UNCID
+				this.inputForm.address = data.OPLOC
+			})
+			this.visiblePop = false
+		},
+		tabHandleClick(event) {
+			// console.log(event)
+		},
+		insertEvent(type) {
+			if (type === 'contact') {
+				let d = {
+					contactFirst: '',
+					contactSecond: '',
+					email: '',
+					fax: '',
+					name: '',
+					officeId: '',
+					position: '',
+					remarks: '',
+					sex: ''
+				}
+				if (this.commonJS.isEmpty(this.inputForm.cwProjectClientContactDTOList)) {
+					this.inputForm.cwProjectClientContactDTOList = []
+				}
+				this.$refs.contactTable.insertAt(d)
+				this.inputForm.cwProjectClientContactDTOList.push(d)
+				this.tableKeyContact = Math.random()
+			}
+		},
+		// 删除
+		removeEvent(row, rowIndex, type) {
+			if (type === 'contact') {
+				this.$refs.contactTable.remove(row)
+				this.inputForm.cwProjectClientContactDTOList.splice(rowIndex, 1)
+			}
+		},
+		checkFiledNo() {
+			console.log('进来了时间比较')
+			// eslint-disable-next-line no-unused-vars
+			let date1 = this.inputForm.effectiveDate
+			// eslint-disable-next-line no-unused-vars
+			let date2 = this.inputForm.endTime
+			if (Date.parse(this.inputForm.endTime) < Date.parse(this.inputForm.effectiveDate)) {
+				this.$message.warning(`合同终止日期要大于合同生效日期`)
+				this.inputForm.endTime = ''
+			}
+		}
+	}
+}
+</script>
+<style scoped>
+/deep/ .el-input-number .el-input__inner {
+	text-align: left;
+}
+</style>
+<style>
+.usc_code_append_message {
+	color: #F56C6C;
+	font-size: 12px;
+	line-height: 1;
+	padding-top: 4px;
+	position: absolute;
+	top: 100%;
+	left: 0;
+}
+</style>

+ 91 - 0
src/views/psiManagement/file/MaterialManagementDialog.vue

@@ -0,0 +1,91 @@
+<!--文件上传组件-->
+<template>
+  <div>
+    <el-dialog
+      :title="title"
+      :close-on-click-modal="false"
+	  draggable
+      width="800px"
+      height="500px"
+      @close="close"
+      append-to-body
+      v-model="visible">
+      <UpLoadComponentV2 ref="upLoadComponentV2"></UpLoadComponentV2>
+		<template #footer>
+			<span class="dialog-footer">
+			  <el-button @click="close()" icon="el-icon-circle-close">关闭</el-button>
+			  <el-button type="primary" icon="el-icon-circle-check" @click="doSubmit()">确定</el-button>
+			</span>
+		</template>
+    </el-dialog>
+
+  </div>
+</template>
+
+<script>
+  import UpLoadComponentV2 from './MaterialManagementV2'
+  export default {
+    data () {
+      return {
+        visible: false,
+        title: '',
+        index: ''
+      }
+    },
+    computed: {
+    },
+    watch: {
+    },
+    created () {
+    },
+    components: {
+      UpLoadComponentV2
+    },
+    mounted () {
+    },
+    methods: {
+      /**
+       * 文件上传组件初始化
+       * @param auth
+       *    auth的值为"view"时,不可上传/编辑文件
+       *    auth为其他值时,可上传/编辑文件
+       * @param fileList  要显示到文件上传列表中的文件。
+       *    注:文件必须要有url属性并且文件的url属性值必须是在oss中的路径值
+       *    例:'/attachment-file/xxx/xxx/2022/9/08/xxx.jpg'
+       * @param directory  要存放到oss的哪个文件夹下。
+       *    注:值为空时,默认存放到"public"文件夹
+       * @param maxValue  上传文件允许的最大值,单位:MB
+       *    注:值为空时,默认值为300MB
+       * @param dividerName  组件中divider的名称
+       *    注:值为空时,默认值为‘附件’
+       * @param uploadFlag  ‘上传文件’按钮是否禁用
+       *    注:值为空时,默认值为false
+       *    auth=view&&uploadFlag=false时 ‘上传文件’按钮禁用
+       * @param delFlag  ‘删除’按钮是否禁用
+       *    注:值为空时,默认值为false
+       *    auth=view&&delFlag=false时 ‘删除’按钮禁用
+       * @param showDivider  ‘附件‘Divider是否展示
+       *    注:值为空时,默认值为true
+       *    showDivider=false时 ‘附件‘Divider隐藏
+       */
+      newUpload (auth, fileList, directory, maxValue, dividerName, uploadFlag, delFlag, showDivider, index) {
+        this.index = index
+        this.title = '附件'
+        this.visible = true
+        this.$nextTick(() => {
+          this.$refs.upLoadComponentV2.newUpload(auth, fileList, directory, maxValue, dividerName, uploadFlag, delFlag, showDivider)
+        })
+      },
+      doSubmit () {
+        if (!this.$refs.upLoadComponentV2.checkProgress()) {
+          this.$emit('getUpload', this.$refs.upLoadComponentV2.getDataList(), this.index)
+          this.close()
+        }
+      },
+      close () {
+        this.$refs.upLoadComponentV2.clearUpload()
+        this.visible = false
+      }
+    }
+  }
+</script>

+ 674 - 0
src/views/psiManagement/file/MaterialManagementV2.vue

@@ -0,0 +1,674 @@
+<!--文件上传组件-->
+<template>
+  <div>
+    <el-divider v-if="showDivider" content-position="left"><i class="el-icon-document"></i> {{dividerName}}</el-divider>
+    <el-upload ref="upload" style="display: inline-block; :show-header='status'" action=""
+               :limit="999" :http-request="httpRequest"
+               multiple
+               :on-exceed="(files, fileList) =>{
+                      $message.warning(`当前限制选择 999 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`)
+                     }"
+               :show-file-list="false"
+               :on-change="changes"
+               :on-progress="uploadVideoProcess"
+               :file-list="fileList">
+      <el-button type="primary" :slot="auth==='view'&&uploadFlag===false?'tip':'trigger'" @click="clickHandel" :disabled="auth==='view'&&uploadFlag===false">点击上传</el-button>
+    </el-upload>
+    <div style="height: calc(100% - 80px);margin-top: 10px">
+      <!-- 进度条 -->
+      <el-progress style="margin-left: 5em" v-if="progressFlag" :percentage="loadProgress"></el-progress>
+      <el-table
+        ref="uploadTable"
+        :key="tableKey"
+        @row-click="tableRowClick"
+        :row-class-name="tableRowClassName"
+        :data="dataListNew">
+        <el-table-column type="seq" width="40"></el-table-column>
+        <el-table-column label="文件名称" prop="name" align="center">
+          <template #default="scope">
+            <div v-if="ifName(scope.row) === true">
+              <el-image
+                style="width: 30px; height: 30px;padding-top: 4px"
+                :src="scope.row.lsUrl"
+                :preview-src-list="[scope.row.lsUrl]"
+              ></el-image>
+            </div>
+            <div v-else>
+              <el-link  type="primary" :underline="false" @click="showFile(scope.row)">{{scope.row.name}}</el-link>
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column v-if="auth !== 'view'" label="创建人" prop="createBy.name" align="center"></el-table-column>
+        <el-table-column v-if="auth !== 'view'" label="创建时间" prop="createTime" align="center"></el-table-column>
+        <el-table-column label="文件大小" prop="size" align="center">
+          <template #default="scope">
+            {{getSize(scope.row.size)}}
+          </template>
+        </el-table-column>
+<!--        <el-table-column label="文件类型" prop="fileType" align="center">-->
+<!--          <template slot-scope="scope">-->
+<!--            <component-->
+<!--              :is="scope.row.fileTypeComponent || 'fileTypeComponentA'"-->
+<!--              :options="$dictUtils.getDictList('cw_project_report_file_type')"-->
+<!--              :value="scope.row.fileType"-->
+<!--              @updateFileType="updateFileType"-->
+<!--            ></component>-->
+<!--          </template>-->
+<!--        </el-table-column>-->
+<!--        <el-table-column label="盖章类型" prop="sealType" align="center">-->
+<!--          <template slot-scope="scope">-->
+<!--            <component-->
+<!--              :is="scope.row.sealTypeComponent || 'sealTypeComponentA'"-->
+<!--              :options="$dictUtils.getDictList('cw_seal_type')"-->
+<!--              :value="scope.row.sealType"-->
+<!--              :scope="scope"-->
+<!--              @updateSealType="updateSealType"-->
+<!--            ></component>-->
+<!--          </template>-->
+<!--        </el-table-column>-->
+<!--        <el-table-column label="备注" prop="remarks" align="center">-->
+<!--          <template slot-scope="scope">-->
+<!--            <component-->
+<!--              :is="scope.row.remarksComponent || 'remarksComponentA'"-->
+<!--              :value="scope.row.remarks"-->
+<!--              @updateRemarks="updateRemarks"-->
+<!--            ></component>-->
+<!--          </template>-->
+<!--        </el-table-column>-->
+        <el-table-column label="操作" width="200px" fixed="right" align="center">
+          <template  #default="scope">
+            <el-button text type="primary"  icon="el-icon-edit" size="small" @click="toHref(scope.row)" :disabled="false">下载</el-button>
+            <el-button text type="primary"  icon="el-icon-delete" size="small"  @click="deleteById(scope.row, scope.$index)" :disabled="auth==='view'&&delFlag === false&&createBy!==scope.row.createBy.name">删除</el-button>
+            <!--<el-button size="small" type="text" icon="el-icon-edit"
+                     @click="handleUpdate(scope.row, scope.$index)"
+            >{{ scope.row.btn || "修改" }}</el-button>-->
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+    <el-image-viewer v-if="showViewer" :on-close="closeViewer" :url-list="[url]" :zIndex=9999></el-image-viewer>
+
+  </div>
+</template>
+
+<script>
+  // eslint-disable-next-line no-unused-vars
+  import OSSSerivce, {
+    httpRequest,
+    // eslint-disable-next-line no-unused-vars
+    handleRemove,
+    fileName,
+    // eslint-disable-next-line no-unused-vars
+    beforeAvatarUpload,
+    // eslint-disable-next-line no-unused-vars
+    openWindowOnUrl,
+    // eslint-disable-next-line no-unused-vars
+    toHref
+  } from '@/api/sys/OSSService'
+  // import ElImageViewer from 'element-ui/packages/image/src/image-viewer'
+  import moment from 'moment'
+  export default {
+    data () {
+      return {
+        progressFlag: false,
+        loadProgress: 0,
+        fileList: [],
+        dataList: [],
+        dataListNew: [],
+        url: '',
+        showViewer: false,
+        ossService: null,
+        auth: '',
+        directory: 'public',
+        maxValue: 300,
+        tableKey: '',
+        fileLoading: true,
+        dividerName: '',
+        uploadFlag: false,
+        delFlag: false,
+        createBy: '',
+        showDivider: true,
+        fileType: '',
+        sealType: '',
+        remarks: ''
+      }
+    },
+    watch: {
+    },
+    created () {
+      this.ossService = new OSSSerivce()
+    },
+    components: {
+      // ElImageViewer,
+      fileTypeComponentA: {
+        render: function (h) {
+          return h('span', {
+            domProps: {
+              innerText: this.$dictUtils.getDictLabel('cw_project_report_file_type', this.value, '')
+            }
+          })
+        },
+        props: ['options', 'value']
+      },
+      fileTypeComponentB: {
+        data () {
+          return { fileType: '' }
+        },
+        props: ['options', 'value'],
+        mounted () {
+          this.fileType = this.value
+        },
+        render: function (h) {
+          return h(
+            'el-select',
+            {
+              attrs: {
+                placeholder: '请选择',
+                value: this.$dictUtils.getDictLabel('cw_project_report_file_type', this.fileType, ''),
+                size: 'small',
+                clearable: true
+              },
+              props: ['value'],
+              on: {
+                change: (value) => {
+                  this.fileType = value
+                  this.$emit('updateFileType', value)
+                }
+              }
+            },
+            [
+              this.options.map((item) => {
+                let { label, value } = item
+                return h('el-option', {
+                  props: {
+                    label,
+                    value: parseInt(value),
+                    key: value
+                  }
+                })
+              })
+            ]
+          )
+        }
+      },
+      sealTypeComponentA: {
+        render: function (h) {
+          return h('span', {
+            domProps: {
+              innerText: this.$dictUtils.getDictLabel('cw_seal_type', this.value, '')
+            }
+          })
+        },
+        props: ['options', 'value']
+      },
+      sealTypeComponentB: {
+        data () {
+          return { sealType: '' }
+        },
+        props: ['options', 'value', 'scope'],
+        mounted () {
+          this.sealType = this.value
+        },
+        render: function (h) {
+          return h(
+            'el-select',
+            {
+              attrs: {
+                placeholder: '请选择',
+                value: this.$dictUtils.getDictLabel('cw_seal_type', this.sealType, ''),
+                size: 'small',
+                clearable: true
+              },
+              props: ['value'],
+              on: {
+                change: (value) => {
+                  let suffix = this.scope.row.name.substring(this.scope.row.name.lastIndexOf('.') + 1)
+                  if (parseInt(value) === 1) {
+                    if (suffix === 'pdf' || suffix === 'doc' || suffix === 'docx') {
+                      this.sealType = value
+                      this.$emit('updateSealType', value)
+                    } else {
+                      this.$message.error('只有“pdf、doc、docx”格式文件的盖章类型可以是“电子章”')
+                      this.sealType = ''
+                      this.$emit('updateSealType', '')
+                    }
+                  } else {
+                    this.sealType = value
+                    this.$emit('updateSealType', value)
+                  }
+                }
+              }
+            },
+            [
+              this.options.map((item) => {
+                let { label, value } = item
+                return h('el-option', {
+                  props: {
+                    label,
+                    value: parseInt(value),
+                    key: value
+                  }
+                })
+              })
+            ]
+          )
+        }
+      },
+      remarksComponentA: {
+        render: function (h) {
+          return h('span', {
+            domProps: {
+              innerText: this.value
+            }
+          })
+        },
+        props: ['value']
+      },
+      remarksComponentB: {
+        data () {
+          return { remarks: '' }
+        },
+        props: ['value'],
+        mounted () {
+          this.remarks = this.value
+        },
+        render: function (h) {
+          return h(
+            'el-input',
+            {
+              attrs: {
+                placeholder: '请输入',
+                value: this.remarks,
+                size: 'small',
+                clearable: true
+              },
+              props: ['value'],
+              on: {
+                input: (value) => {
+                  this.remarks = value
+                  this.$emit('updateRemarks', value)
+                }
+              }
+            }
+          )
+        }
+      }
+    },
+    mounted () {
+      window.onPreview = this.onPreview
+    },
+    methods: {
+      /**
+       * dividerName: 组件中divider的名称赋值
+       * showDivider: ‘附件‘Divider是否展示
+       *     注:值为空时,默认值为true
+       *    showDivider=false时 ‘附件‘Divider隐藏
+       **/
+      setDividerName (dividerName, showDivider) {
+        if (this.commonJS.isNotEmpty(dividerName)) {
+          this.dividerName = dividerName
+        }
+        if (this.commonJS.isNotEmpty(showDivider)) {
+          if (showDivider === false) {
+            this.showDivider = false
+          } else {
+            this.showDivider = true
+          }
+        } else {
+          this.showDivider = true
+        }
+      },
+      /**
+       * 文件上传组件初始化
+       * @param auth
+       *    auth的值为"view"时,不可上传/编辑文件
+       *    auth为其他值时,可上传/编辑文件
+       * @param fileList  要显示到文件上传列表中的文件。
+       *    注:文件必须要有url属性并且文件的url属性值必须是在oss中的路径值
+       *    例:'/attachment-file/xxx/xxx/2022/9/08/xxx.jpg'
+       * @param directory  要存放到oss的哪个文件夹下。
+       *    注:值为空时,默认存放到"public"文件夹
+       * @param maxValue  上传文件允许的最大值,单位:MB
+       *    注:值为空时,默认值为300MB
+       * @param dividerName  组件中divider的名称
+       *    注:值为空时,默认值为‘附件’
+       * @param uploadFlag  ‘上传文件’按钮是否禁用
+       *    注:值为空时,默认值为false
+       *    auth=view&&uploadFlag=false时 ‘上传文件’按钮禁用
+       * @param delFlag  ‘删除’按钮是否禁用
+       *    注:值为空时,默认值为false
+       *    auth=view&&delFlag=false时 ‘删除’按钮禁用
+       * @param showDivider  ‘附件‘Divider是否展示
+       *    注:值为空时,默认值为true
+       *    showDivider=false时 ‘附件‘Divider隐藏
+       */
+      async newUpload (auth, fileList, directory, maxValue, dividerName, uploadFlag, delFlag, showDivider) {
+        await this.fileLoadingFalse()
+        if (this.commonJS.isEmpty(dividerName)) {
+          this.dividerName = '附件'
+        } else {
+          this.dividerName = dividerName
+        }
+        if (directory !== undefined && directory !== null && directory !== '' && directory !== {}) {
+          this.directory = directory
+        } else {
+          this.directory = 'public'
+        }
+        if (maxValue !== undefined && maxValue !== null && maxValue !== '' && maxValue !== 0) {
+          this.maxValue = maxValue
+        } else {
+          this.maxValue = 300
+        }
+        this.auth = auth
+        if (this.commonJS.isEmpty(uploadFlag)) {
+          this.uploadFlag = false
+        } else {
+          if (uploadFlag !== true && uploadFlag !== false) {
+            this.uploadFlag = false
+          } else {
+            this.uploadFlag = uploadFlag
+          }
+        }
+        if (this.commonJS.isEmpty(delFlag)) {
+          this.delFlag = false
+        } else {
+          if (delFlag !== true && delFlag !== false) {
+            this.delFlag = false
+            this.createBy = delFlag
+          } else {
+            this.delFlag = delFlag
+          }
+        }
+        if (this.commonJS.isEmpty(fileList)) {
+          this.fileLoading = true
+        }
+        for await (let item of fileList) {
+          await this.ossService.getFileSizeByUrl(item.url).then((data) => {
+            item.lsUrl = data.url
+            item.size = data.size
+            this.dataList.push(item)
+            this.dataListNew.push(item)
+            if (this.dataList.length === fileList.length) {
+              this.fileLoading = true
+            }
+          })
+        }
+        // this.dataList = JSON.parse(JSON.stringify(fileList))
+        // this.dataListNew = JSON.parse(JSON.stringify(fileList))
+        if (this.commonJS.isEmpty(showDivider)) {
+          this.showDivider = true
+        } else {
+          if (showDivider === false) {
+            this.showDivider = false
+          } else {
+            this.showDivider = true
+          }
+        }
+      },
+      async httpRequest (file) {
+        await httpRequest(file, fileName(file), this.directory, this.maxValue)
+      },
+      uploadVideoProcess (event, file, fileList) {
+        this.progressFlag = true // 显示进度条
+        this.loadProgress = parseInt(event.percent) // 动态获取文件上传进度
+        if (this.loadProgress >= 100) {
+          this.loadProgress = 100
+          setTimeout(() => {
+            this.progressFlag = false
+          }, 1000) // 一秒后关闭进度条
+        }
+      },
+      getSize (value) {
+        if (this.commonJS.isEmpty(value)) {
+          return '0 B'
+        } else {
+          let val = parseInt(value)
+          if (this.commonJS.isEmpty(val)) {
+            return '0 B'
+          }
+          if (isNaN(val)) {
+            return '0 B'
+          }
+          if (val === 0) {
+            return '0 B'
+          }
+          let k = 1024
+          let sizes = ['B', 'KB', 'MB', 'GB', 'PB', 'TB', 'EB', 'ZB', 'YB']
+          let i = Math.floor(Math.log(val) / Math.log(k))
+          return (val / Math.pow(k, i)).toPrecision(3) + '' + sizes[i]
+        }
+      },
+      async changes (file, fileList) {
+        // if (file.status !== 'ready') {
+        //   return
+        // }
+        if (!beforeAvatarUpload(file, fileList, this.maxValue)) {
+          this.$message.error('文件大小不能超过 ' + this.maxValue + ' MB!')
+          return
+        }
+        this.dataListNew = []
+        this.dataList.forEach((item) => {
+          this.dataListNew.push(item)
+        })
+        for (let item of fileList) {
+          item.createTime = moment(new Date()).format('YYYY-MM-DD HH:mm:ss')
+          item.createBy = {
+            id: '',
+            name: ''
+          }
+          item.createBy.id = this.$store.state.user.id
+          item.createBy.name = this.$store.state.user.name
+          this.dataListNew.push(item)
+        }
+        for  (let item of this.dataListNew) {
+          if (item.raw !== undefined && item.raw !== null && item.raw !== {}) {
+            item.url = item.raw.url
+            if (item.raw.url !== undefined && item.raw.url !== null && item.raw.url !== {}) {
+               this.ossService.getTemporaryUrl(item.raw.url).then((data) => {
+                item.lsUrl = data
+              })
+            }
+          }
+        }
+        this.tableKey = Math.random()
+      },
+      showFile (row) {
+        openWindowOnUrl(row)
+      },
+      onPreview (url) {
+        this.url = url
+        this.showViewer = true
+      },
+      // 关闭查看器
+      closeViewer () {
+        this.url = ''
+        this.showViewer = false
+      },
+      toHref (row) {
+        toHref(row)
+      },
+      deleteById (row, index) {
+        this.dataListNew.splice(index, 1)
+        if (row.id !== null && row.id !== '' && row.id !== undefined) {
+          this.dataList.splice(index, 1)
+          // this.ossService.deleteMsgById(row.id)
+        } else {
+          let num
+          if (this.dataList.length > 0) {
+            num = this.dataList.length - 1
+          } else {
+            num = 0
+          }
+          this.$refs.upload.uploadFiles.splice(index - num, 1)
+        }
+      },
+      /**
+       * 关闭dialog时使用  清除el-upload中上传的文件
+       */
+      clearUpload () {
+        this.$refs.upload.uploadFiles = []
+        this.dataList = []
+        this.dataListNew = []
+        this.createBy = ''
+      },
+      /**
+       * 获取当前文件列表中的文件数据
+       */
+      getDataList () {
+        let _this = this
+        const waitForEach = function () {
+          return new Promise(function (resolve, reject) {
+            _this.dataListNew.forEach((item, index) => {
+              if (item.btnType === 'save') {
+                _this.dataListNew[index].fileTypeComponent = 'fileTypeComponentA'
+                _this.dataListNew[index].sealTypeComponent = 'sealTypeComponentA'
+                _this.dataListNew[index].remarksComponent = 'remarksComponentA'
+                _this.dataListNew[index].btn = '修改'
+                _this.dataListNew[index].btnType = 'edit'
+                _this.dataListNew[index].fileType = _this.fileType
+                _this.dataListNew[index].sealType = _this.sealType
+                _this.dataListNew[index].remarks = _this.remarks
+              }
+            })
+            _this.tableKey = Math.random()
+            resolve(_this.dataListNew)
+          })
+        }
+        return waitForEach()
+      },
+      /**
+       * 判断进度条是否结束,附件是否加载完成
+       * @returns {boolean}
+       */
+      checkProgress () {
+        if (this.progressFlag === true) {
+          this.$message.warning('请等待附件上传完成再进行操作')
+          return true
+        }
+        if (this.fileLoading === false) {
+          this.$message.warning('请等待附件加载完成再进行操作')
+          return true
+        }
+        return false
+      },
+      ifName (row) {
+        if (this.commonJS.isEmpty(row.name)) {
+          row.name = '---'
+          return false
+        }
+        let suffix = row.name.substring(row.name.lastIndexOf('.') + 1)
+        if (suffix === 'jpg' || suffix === 'png' || suffix === 'gif' || suffix === 'bmp' || suffix === 'jpeg') {
+          return true
+        } else {
+          return false
+        }
+      },
+      fileLoadingFalse () {
+        this.fileLoading = false
+      },
+      /** 修改||保存按钮操作 */
+      handleUpdate: async function (row, rowIndex) {
+        if (row.btnType === 'edit' || this.commonJS.isEmpty(row.btnType)) {
+          let _this = this
+          const waitForEach = function () {
+            return new Promise(function (resolve, reject) {
+              _this.dataListNew.forEach((item, index) => {
+                if (item.btnType === 'save') {
+                  _this.dataListNew[index].fileTypeComponent = 'fileTypeComponentA'
+                  _this.dataListNew[index].sealTypeComponent = 'sealTypeComponentA'
+                  _this.dataListNew[index].remarksComponent = 'remarksComponentA'
+                  _this.dataListNew[index].btn = '修改'
+                  _this.dataListNew[index].btnType = 'edit'
+                  _this.dataListNew[index].fileType = _this.fileType
+                  _this.dataListNew[index].sealType = _this.sealType
+                  _this.dataListNew[index].remarks = _this.remarks
+                }
+              })
+              resolve()
+            })
+          }
+          waitForEach().then(() => {
+            this.dataListNew[rowIndex].fileTypeComponent = 'fileTypeComponentB'
+            this.dataListNew[rowIndex].sealTypeComponent = 'sealTypeComponentB'
+            this.dataListNew[rowIndex].remarksComponent = 'remarksComponentB'
+            this.dataListNew[rowIndex].btn = '保存'
+            this.dataListNew[rowIndex].btnType = 'save'
+          })
+        } else {
+          this.dataListNew[rowIndex].fileTypeComponent = 'fileTypeComponentA'
+          this.dataListNew[rowIndex].sealTypeComponent = 'sealTypeComponentA'
+          this.dataListNew[rowIndex].remarksComponent = 'remarksComponentA'
+          this.dataListNew[rowIndex].btn = '修改'
+          this.dataListNew[rowIndex].btnType = 'edit'
+          this.dataListNew[rowIndex].fileType = this.fileType
+          this.dataListNew[rowIndex].sealType = this.sealType
+          this.dataListNew[rowIndex].remarks = this.remarks
+        }
+        this.tableKey = Math.random()
+      },
+      updateFileType (fileType) {
+        this.fileType = fileType
+      },
+      updateSealType (sealType) {
+        this.sealType = sealType
+      },
+      updateRemarks (remarks) {
+        this.remarks = remarks
+      },
+      tableRowClassName ({ row, rowIndex }) {
+        row.index = rowIndex
+      },
+      // 行点击事件
+      tableRowClick (row, column) {
+        if (this.auth !== 'view') {
+          if (column.label !== '备注' && column.label !== '文件名称' && column.label !== '操作') {
+            let _this = this
+            const waitForEach = function () {
+              return new Promise(function (resolve, reject) {
+                _this.dataListNew.forEach((item, index) => {
+                  if (item.btnType === 'save') {
+                    _this.dataListNew[index].fileTypeComponent = 'fileTypeComponentA'
+                    _this.dataListNew[index].sealTypeComponent = 'sealTypeComponentA'
+                    _this.dataListNew[index].remarksComponent = 'remarksComponentA'
+                    _this.dataListNew[index].btn = '修改'
+                    _this.dataListNew[index].btnType = 'edit'
+                    _this.dataListNew[index].fileType = _this.fileType
+                    _this.dataListNew[index].sealType = _this.sealType
+                    _this.dataListNew[index].remarks = _this.remarks
+                  }
+                })
+                resolve()
+              })
+            }
+            waitForEach().then(() => {
+              this.fileType = this.dataListNew[row.index].fileType
+              this.sealType = this.dataListNew[row.index].sealType
+              this.remarks = this.dataListNew[row.index].remarks
+              this.dataListNew[row.index].fileTypeComponent = 'fileTypeComponentB'
+              this.dataListNew[row.index].sealTypeComponent = 'sealTypeComponentB'
+              this.dataListNew[row.index].remarksComponent = 'remarksComponentB'
+              this.dataListNew[row.index].btn = '保存'
+              this.dataListNew[row.index].btnType = 'save'
+            })
+            this.tableKey = Math.random()
+          }
+        }
+      },
+      // 点击上传文件按钮的时候,把未保存的文件保存一下
+      clickHandel () {
+        this.dataListNew.forEach((item, index) => {
+          if (item.btnType === 'save') {
+            this.dataListNew[index].fileTypeComponent = 'fileTypeComponentA'
+            this.dataListNew[index].sealTypeComponent = 'sealTypeComponentA'
+            this.dataListNew[index].remarksComponent = 'remarksComponentA'
+            this.dataListNew[index].btn = '修改'
+            this.dataListNew[index].btnType = 'edit'
+            this.dataListNew[index].fileType = this.fileType
+            this.dataListNew[index].sealType = this.sealType
+            this.dataListNew[index].remarks = this.remarks
+          }
+        })
+      }
+    }
+  }
+</script>

+ 758 - 0
src/views/psiManagement/foodPurchase/FoodPurchaseForm.vue

@@ -0,0 +1,758 @@
+<template>
+	<div>
+		<el-form
+			ref="inputForm"
+			:model="inputForm"
+			v-loading="loading"
+			:class="isViewMode ? 'readonly' : ''"
+			:disabled="isDisabled"
+			label-width="110px"
+			@submit.native.prevent
+		>
+			<el-divider content-position="left">
+				<i class="el-icon-document"></i> 基础信息
+			</el-divider>
+			<el-row :gutter="20">
+				<el-col :span="12">
+					<el-form-item label="采购编号" prop="purchaseNo">
+						<el-input
+							v-model="inputForm.purchaseNo"
+							disabled
+							placeholder="自动生成"
+						/>
+					</el-form-item>
+				</el-col>
+				<el-col :span="12">
+					<el-form-item label="采购人" prop="handledBy">
+						<el-input v-model="inputForm.handledBy" disabled />
+					</el-form-item>
+				</el-col>
+				<el-col :span="12">
+					<el-form-item label="采购部门" prop="handledByOffice">
+						<SelectTree
+							ref="officeTree"
+							:disabled="true"
+							:props="{
+								value: 'id',
+								label: 'name',
+								children: 'children',
+							}"
+							:url="`/system-server/sys/office/treeData?type=2`"
+							:value="inputForm.handledByOffice"
+							:accordion="true"
+							size="default"
+							@getValue="
+								(value) => (inputForm.handledByOffice = value)
+							"
+						/>
+					</el-form-item>
+				</el-col>
+				<el-col :span="12">
+					<el-form-item
+						label="采购时间"
+						prop="purchaseTime"
+						:rules="[
+							{
+								required: true,
+								message: '请选择采购时间',
+								trigger: 'blur',
+							},
+						]"
+					>
+						<el-date-picker
+							v-model="inputForm.purchaseTime"
+							type="datetime"
+							value-format="YYYY-MM-DD HH:mm:ss"
+							style="width: 100%"
+							placeholder="请选择采购时间"
+						/>
+					</el-form-item>
+				</el-col>
+				<el-col :span="24">
+					<el-form-item label="备注" prop="remarks">
+						<el-input
+							v-model="inputForm.remarks"
+							type="textarea"
+							:rows="4"
+							maxlength="500"
+							show-word-limit
+							placeholder="请输入备注信息"
+						/>
+					</el-form-item>
+				</el-col>
+			</el-row>
+
+			<el-divider content-position="left">
+				<i class="el-icon-document"></i> 采购明细
+				<el-button
+					style="margin-left: 20px"
+					type="primary"
+					plain
+					:disabled="isDisabled"
+					@click="insertEvent"
+				>
+					新增
+				</el-button>
+			</el-divider>
+
+			<el-row :gutter="15">
+				<el-col :span="24">
+					<vxe-table
+						ref="detailTable"
+						border
+						show-footer
+						show-overflow
+						class="vxe-table-element"
+						:data="inputForm.detailInfos"
+						style="margin-left: 5em"
+						:key="clientTableKey"
+						highlight-current-row
+						:footer-method="footerMethod"
+						:edit-config="{
+							trigger: 'click',
+							mode: 'row',
+							showStatus: false,
+							autoClear: true,
+							icon: '-',
+						}"
+						:edit-rules="validRules"
+					>
+						<vxe-table-column
+							field="goodsName"
+							title="采购食材名称"
+							min-width="170"
+							:edit-render="{}"
+							:rules="[
+								{
+									required: true,
+									message: '请填写采购食材名称',
+									trigger: 'blur',
+								},
+							]"
+						>
+							<template #edit="scope">
+								<el-input
+									v-model="scope.row.goodsName"
+									maxlength="100"
+								/>
+							</template>
+						</vxe-table-column>
+						<vxe-table-column
+							field="foodType"
+							title="食材分类"
+							min-width="140"
+							:edit-render="{}"
+						>
+							<template #edit="scope">
+								<el-select
+									v-model="scope.row.foodType"
+									clearable
+									placeholder="请选择"
+									style="width: 100%"
+								>
+									<el-option
+										v-for="item in $dictUtils.getDictList(
+											'food_type'
+										)"
+										:key="item.value"
+										:label="item.label"
+										:value="item.value"
+									/>
+								</el-select>
+							</template>
+						</vxe-table-column>
+						<vxe-table-column
+							field="purchaseNumber"
+							title="采购数量"
+							min-width="120"
+							:edit-render="{}"
+						>
+							<template #edit="scope">
+								<el-input
+									v-model="scope.row.purchaseNumber"
+									maxlength="10"
+									@blur="
+										handleNumberBlur(
+											scope.row,
+											'purchaseNumber'
+										)
+									"
+								/>
+							</template>
+						</vxe-table-column>
+						<vxe-table-column
+							field="unit"
+							title="单位"
+							min-width="100"
+							:edit-render="{}"
+						>
+							<template #edit="scope">
+								<el-input
+									v-model="scope.row.unit"
+									maxlength="20"
+								/>
+							</template>
+						</vxe-table-column>
+						<vxe-table-column
+							field="unitPrice"
+							title="单价"
+							min-width="120"
+							:edit-render="{}"
+						>
+							<template #edit="scope">
+								<el-input
+									v-model="scope.row.unitPrice"
+									maxlength="15"
+									@blur="
+										handleNumberBlur(scope.row, 'unitPrice')
+									"
+								/>
+							</template>
+						</vxe-table-column>
+						<vxe-table-column
+							field="totalPrice"
+							title="总价"
+							min-width="120"
+							:edit-render="{}"
+						>
+							<template #edit="scope">
+								<el-input
+									v-model="scope.row.totalPrice"
+									maxlength="15"
+									@blur="handleTotalPriceBlur(scope.row)"
+								/>
+							</template>
+						</vxe-table-column>
+						<vxe-table-column
+							field="storageArea"
+							title="存储区域"
+							min-width="140"
+							:edit-render="{}"
+						>
+							<template #edit="scope">
+								<el-input
+									v-model="scope.row.storageArea"
+									maxlength="100"
+								/>
+							</template>
+						</vxe-table-column>
+						<vxe-table-column
+							field="shelfLife"
+							title="保质期"
+							min-width="140"
+							:edit-render="{}"
+						>
+							<template #edit="scope">
+								<el-input
+									v-model="scope.row.shelfLife"
+									maxlength="100"
+									placeholder="如:3天/6个月"
+								/>
+							</template>
+						</vxe-table-column>
+						<vxe-table-column
+							field="expiryDate"
+							title="到期日期"
+							min-width="150"
+							:edit-render="{}"
+						>
+							<template #edit="scope">
+								<el-date-picker
+									v-model="scope.row.expiryDate"
+									type="date"
+									value-format="YYYY-MM-DD"
+									style="width: 100%"
+									placeholder="请选择日期"
+								/>
+							</template>
+						</vxe-table-column>
+						<vxe-table-column
+							field="remarks"
+							title="备注"
+							min-width="140"
+							:edit-render="{}"
+						>
+							<template #edit="scope">
+								<el-input
+									v-model="scope.row.remarks"
+									maxlength="255"
+								/>
+							</template>
+						</vxe-table-column>
+						<vxe-table-column
+							title="操作"
+							width="100"
+							align="center"
+						>
+							<template #default="scope">
+								<vxe-button
+									size="small"
+									status="danger"
+									:disabled="isDisabled"
+									@click="
+										removeEvent(scope.row, scope.$rowIndex)
+									"
+								>
+									删除
+								</vxe-button>
+							</template>
+						</vxe-table-column>
+					</vxe-table>
+				</el-col>
+			</el-row>
+		</el-form>
+	</div>
+</template>
+
+<script>
+import SelectTree from "@/components/treeSelect/treeSelect.vue";
+import FoodPurchaseService from "@/api/psi/FoodPurchaseService";
+
+export default {
+	components: {
+		SelectTree,
+	},
+	props: {
+		businessId: {
+			type: String,
+			default: "",
+		},
+		formReadOnly: {
+			type: Boolean,
+			default: false,
+		},
+		status: {
+			type: String,
+			default: "",
+		},
+	},
+	data() {
+		return {
+			method: "",
+			loading: false,
+			keyWatch: "",
+			clientTableKey: "",
+			validRules: {
+				goodsName: [
+					{ required: true, message: "采购食材名称不能为空" },
+				],
+			},
+			inputForm: this.createDefaultForm(),
+		};
+	},
+	created() {
+		this.foodPurchaseService = new FoodPurchaseService();
+	},
+	computed: {
+		bus: {
+			get() {
+				return this.businessId;
+			},
+			set(val) {
+				this.businessId = val;
+			},
+		},
+		isViewMode() {
+			return this.method === "view";
+		},
+		isDisabled() {
+			return (
+				this.method === "view" ||
+				this.status === "audit" ||
+				this.status === "taskFormDetail" ||
+				this.formReadOnly
+			);
+		},
+	},
+	watch: {
+		keyWatch() {
+			if (this.commonJS.isNotEmpty(this.bus)) {
+				this.init("", this.bus);
+			}
+		},
+		loading(newVal) {
+			this.$emit("changeLoading", newVal);
+		},
+	},
+	methods: {
+		getKeyWatch(keyWatch) {
+			this.keyWatch = keyWatch;
+		},
+		createDefaultForm() {
+			return {
+				id: "",
+				purchaseNo: "",
+				purchaseTime: this.moment(new Date()).format(
+					"YYYY-MM-DD HH:mm:ss"
+				),
+				totalPrice: "0.00",
+				handledBy: this.$store.state.user.name,
+				handledById: this.$store.state.user.id,
+				handledByOffice: this.$store.state.user.office.id,
+				remarks: "",
+				status: "",
+				detailInfos: [],
+			};
+		},
+		init(method, id) {
+			this.method = method;
+			this.inputForm = this.createDefaultForm();
+			this.inputForm.id = id;
+			this.$nextTick(() => {
+				if (this.$refs.inputForm) {
+					this.$refs.inputForm.resetFields();
+				}
+				if (id && id !== "false") {
+					this.loading = true;
+					this.foodPurchaseService
+						.findById(id)
+						.then((data) => {
+							this.inputForm = this.recover(
+								this.createDefaultForm(),
+								data
+							);
+							this.inputForm.id = data.id;
+							this.inputForm.handledById =
+								data.handledById || data.handledBy;
+							this.inputForm.detailInfos = (
+								data.detailInfos || []
+							).map((item) => ({
+								...item,
+								purchaseNumber: this.formatNumber(
+									item.purchaseNumber
+								),
+								unitPrice: this.formatNumber(item.unitPrice),
+								totalPrice: this.formatNumber(item.totalPrice),
+							}));
+							this.inputForm.totalPrice = this.formatNumber(
+								data.totalPrice
+							);
+							this.inputForm = JSON.parse(
+								JSON.stringify(this.inputForm)
+							);
+						})
+						.finally(() => {
+							this.loading = false;
+						});
+				}
+			});
+		},
+		insertEvent() {
+			this.$refs.detailTable.insert().then((row) => {
+				row.goodsName = "";
+				row.foodType = "";
+				row.purchaseNumber = "";
+				row.unit = "";
+				row.unitPrice = "";
+				row.totalPrice = "";
+				row.storageArea = "";
+				row.shelfLife = "";
+				row.expiryDate = "";
+				row.remarks = "";
+				this.inputForm.detailInfos.push(row);
+				this.clientTableKey = Math.random();
+			});
+		},
+		removeEvent(row, rowIndex) {
+			this.$refs.detailTable.remove(row);
+			this.inputForm.detailInfos.splice(rowIndex, 1);
+			this.updateBasicTotal();
+		},
+		handleNumberBlur(row, field) {
+			row[field] = this.normalizeNumber(row[field]);
+			this.calculateRowTotal(row);
+		},
+		handleTotalPriceBlur(row) {
+			row.totalPrice = this.normalizeNumber(row.totalPrice);
+			this.updateBasicTotal();
+		},
+		calculateRowTotal(row) {
+			if (
+				this.commonJS.isNotEmpty(row.purchaseNumber) &&
+				this.commonJS.isNotEmpty(row.unitPrice)
+			) {
+				row.totalPrice = (
+					parseFloat(row.purchaseNumber || 0) *
+					parseFloat(row.unitPrice || 0)
+				).toFixed(2);
+			}
+			this.updateBasicTotal();
+		},
+		updateBasicTotal() {
+			const total = (this.inputForm.detailInfos || []).reduce(
+				(sum, item) => {
+					return sum + Number(item.totalPrice || 0);
+				},
+				0
+			);
+			this.inputForm.totalPrice = Number.isNaN(total)
+				? "0.00"
+				: total.toFixed(2);
+			this.clientTableKey = Math.random();
+		},
+		footerMethod({ columns, data }) {
+			const total = data.reduce(
+				(sum, item) => sum + Number(item.totalPrice || 0),
+				0
+			);
+			this.inputForm.totalPrice = Number.isNaN(total)
+				? "0.00"
+				: total.toFixed(2);
+			return [
+				columns.map((column, columnIndex) => {
+					if (columnIndex === 0) {
+						return "采购金额";
+					}
+					if (column.property === "totalPrice") {
+						return this.inputForm.totalPrice;
+					}
+					return null;
+				}),
+			];
+		},
+		normalizeNumber(num) {
+			if (this.commonJS.isEmpty(num)) {
+				return "";
+			}
+			let str = String(num).trim();
+			const len1 = str.substr(0, 1);
+			const len2 = str.substr(1, 1);
+			if (str.length > 1 && len1 === "0" && len2 !== ".") {
+				str = str.substr(1, 1);
+			}
+			if (len1 === ".") {
+				str = "";
+			}
+			if (str.indexOf(".") !== -1) {
+				const decimals = str.substr(str.indexOf(".") + 1);
+				if (decimals.indexOf(".") !== -1) {
+					str = str.substr(
+						0,
+						str.indexOf(".") + decimals.indexOf(".") + 1
+					);
+				}
+				if (decimals.length > 2) {
+					this.$message.warning("数值小数点后只能输入两位");
+					return "";
+				}
+			}
+			return str.replace(/[^\d^.]+/g, "");
+		},
+		formatNumber(value) {
+			if (this.commonJS.isEmpty(value) && value !== 0) {
+				return "";
+			}
+			const num = Number(value);
+			if (Number.isNaN(num)) {
+				return "";
+			}
+			return num.toFixed(2);
+		},
+		validateForm() {
+			return new Promise((resolve) => {
+				this.$refs.inputForm.validate((valid) => {
+					if (!valid) {
+						resolve(false);
+						return;
+					}
+					if (this.commonJS.isEmpty(this.inputForm.detailInfos)) {
+						this.$message.error("请至少填写一条采购明细");
+						resolve(false);
+						return;
+					}
+					for (
+						let i = 0;
+						i < this.inputForm.detailInfos.length;
+						i++
+					) {
+						const row = this.inputForm.detailInfos[i];
+						if (this.commonJS.isEmpty(row.goodsName)) {
+							this.$message.error(
+								`采购明细第${i + 1}行请填写采购食材名称`
+							);
+							resolve(false);
+							return;
+						}
+					}
+					this.updateBasicTotal();
+					resolve(true);
+				});
+			});
+		},
+		doSubmit() {
+			this.validateForm().then((valid) => {
+				if (!valid) {
+					return;
+				}
+				this.loading = true;
+				this.foodPurchaseService
+					.save(this.inputForm)
+					.then(() => {
+						this.$message.success("操作成功");
+						this.$emit("refreshDataList");
+					})
+					.finally(() => {
+						this.loading = false;
+					});
+			});
+		},
+		saveForm(callback) {
+			this.validateForm().then((valid) => {
+				if (!valid) {
+					return;
+				}
+				this.loading = true;
+				this.inputForm.status = "1";
+				this.foodPurchaseService
+					.save(this.inputForm)
+					.then(() => {
+						callback();
+					})
+					.finally(() => {
+						this.loading = false;
+					});
+			});
+		},
+		startForm(callback) {
+			this.loading = true;
+			if (this.commonJS.isNotEmpty(this.inputForm.id)) {
+				this.foodPurchaseService
+					.findById(this.inputForm.id)
+					.then((data) => {
+						if (
+							this.commonJS.isNotEmpty(data.status) &&
+							!["0", "1", "3", "4", "5"].includes(data.status)
+						) {
+							this.loading = false;
+							this.$message.error(
+								"任务数据已发生变化,请刷新后重试"
+							);
+							throw new Error("status changed");
+						}
+						this.startFormTrue(callback);
+					});
+				return;
+			}
+			this.startFormTrue(callback);
+		},
+		startFormTrue(callback) {
+			this.validateForm().then((valid) => {
+				if (!valid) {
+					return;
+				}
+				this.loading = true;
+				this.inputForm.status = "2";
+				this.foodPurchaseService
+					.save(this.inputForm)
+					.then((data) => {
+						this.inputForm.id = data.businessId;
+						callback(
+							data.businessTable,
+							data.businessId,
+							this.inputForm
+						);
+					})
+					.finally(() => {
+						this.loading = false;
+					});
+			});
+		},
+		reapplyForm(callback) {
+			this.loading = true;
+			this.foodPurchaseService
+				.findById(this.inputForm.id)
+				.then((data) => {
+					if (data.status !== "4") {
+						this.loading = false;
+						this.$message.error(
+							"任务数据已发生变化,请在待办中确认"
+						);
+						throw new Error("status changed");
+					}
+					this.startFormTrue(callback);
+				});
+		},
+		agreeForm(callback) {
+			this.validateForm().then((valid) => {
+				if (!valid) {
+					return;
+				}
+				this.loading = true;
+				this.inputForm.status = "5";
+				this.foodPurchaseService
+					.save(this.inputForm)
+					.then((data) => {
+						callback(
+							data.businessTable,
+							data.businessId,
+							this.inputForm
+						);
+					})
+					.finally(() => {
+						this.loading = false;
+					});
+			});
+		},
+		updateStatusById(type, callback) {
+			this.loading = true;
+			if (type === "reject" || type === "reback") {
+				this.foodPurchaseService
+					.findById(this.inputForm.id)
+					.then((data) => {
+						if (data.status !== "2") {
+							this.loading = false;
+							this.$message.error(
+								"任务数据已发生变化,请刷新后重试"
+							);
+							throw new Error("status changed");
+						}
+						const status = type === "reject" ? "4" : "3";
+						this.foodPurchaseService
+							.updateStatusById({ status, id: this.inputForm.id })
+							.then(() => {
+								this.loading = false;
+								callback();
+							});
+					});
+				return;
+			}
+			if (type === "hold") {
+				this.foodPurchaseService
+					.findById(this.inputForm.id)
+					.then((data) => {
+						if (data.status !== "4") {
+							this.loading = false;
+							this.$message.error(
+								"任务数据已发生变化,请刷新后重试"
+							);
+							throw new Error("status changed");
+						}
+						this.foodPurchaseService
+							.updateStatusById({
+								status: "1",
+								id: this.inputForm.id,
+							})
+							.then(() => {
+								this.loading = false;
+								callback();
+							});
+					});
+			}
+		},
+		close() {
+			if (this.$refs.inputForm) {
+				this.$refs.inputForm.resetFields();
+			}
+			this.inputForm = this.createDefaultForm();
+			this.clientTableKey = Math.random();
+		},
+	},
+};
+</script>
+
+<style scoped>
+.el-divider__text {
+	font-size: 16px;
+	font-weight: bold;
+}
+</style>

+ 657 - 0
src/views/psiManagement/foodPurchase/FoodPurchaseList.vue

@@ -0,0 +1,657 @@
+<template>
+	<div class="page">
+		<el-form
+			v-if="searchVisible"
+			ref="searchForm"
+			:model="searchForm"
+			:inline="true"
+			class="query-form m-b-10"
+			@keyup.enter.native="refreshList"
+			@submit.native.prevent
+		>
+			<el-form-item label="采购编号" prop="purchaseNo">
+				<el-input
+					v-model="searchForm.purchaseNo"
+					clearable
+					placeholder="请输入采购编号"
+				/>
+			</el-form-item>
+			<el-form-item label="采购人" prop="handledBy">
+				<UserSelect
+					:limit="1"
+					:modelValue="searchForm.handledBy"
+					@update:modelValue="
+						(value) => (searchForm.handledBy = value)
+					"
+				/>
+			</el-form-item>
+			<el-form-item label="采购时间" prop="purchaseTimes">
+				<el-date-picker
+					v-model="searchForm.purchaseTimes"
+					type="datetimerange"
+					format="YYYY-MM-DD HH:mm:ss"
+					value-format="YYYY-MM-DD HH:mm:ss"
+					range-separator="至"
+					start-placeholder="开始时间"
+					end-placeholder="结束时间"
+					placement="bottom-start"
+				/>
+			</el-form-item>
+			<el-form-item
+				v-if="showHideItem"
+				label="采购部门"
+				prop="handledByOffice"
+			>
+				<SelectTree
+					ref="officeTree"
+					:props="{
+						value: 'id',
+						label: 'name',
+						children: 'children',
+					}"
+					:url="`/system-server/sys/office/treeData?type=2`"
+					:value="searchForm.handledByOffice"
+					size="default"
+					:accordion="true"
+					@getValue="(value) => (searchForm.handledByOffice = value)"
+				/>
+			</el-form-item>
+			<el-form-item v-if="showHideItem" label="修改状态" prop="status">
+				<el-select
+					v-model="searchForm.status"
+					clearable
+					placeholder="请选择状态"
+					style="width: 100%"
+				>
+					<el-option
+						v-for="item in $dictUtils.getDictList('cw_status')"
+						:key="item.value"
+						:label="item.label"
+						:value="item.value"
+					/>
+				</el-select>
+			</el-form-item>
+			<el-form-item>
+				<el-button
+					type="default"
+					:icon="showHideIcon"
+					@click="showHide"
+					>{{ showHideName }}</el-button
+				>
+				<el-button
+					type="primary"
+					icon="el-icon-search"
+					@click="refreshList"
+					>查询</el-button
+				>
+				<el-button icon="el-icon-refresh-right" @click="resetSearch"
+					>重置</el-button
+				>
+			</el-form-item>
+		</el-form>
+
+		<div class="statistics-panel">
+			<div class="statistics-card">
+				<div class="statistics-label">当前筛选范围采购金额</div>
+				<div class="statistics-value">{{ statisticTotalPrice }}</div>
+			</div>
+			<el-button type="primary" plain @click="refreshStatistics"
+				>刷新统计</el-button
+			>
+		</div>
+
+		<div class="jp-table top">
+			<vxe-toolbar :refresh="{ query: refreshList }" custom>
+				<template #buttons>
+					<el-button
+						v-if="hasPermission('psi:foodPurchase:add')"
+						type="primary"
+						icon="el-icon-plus"
+						@click="start"
+					>
+						新增
+					</el-button>
+				</template>
+				<template #tools>
+					<vxe-button
+						text
+						type="primary"
+						icon="vxe-icon-search"
+						class="tool-btn"
+						:title="searchVisible ? '收起搜索' : '展开搜索'"
+						@click="searchVisible = !searchVisible"
+					/>
+				</template>
+			</vxe-toolbar>
+
+			<div style="height: calc(100% - 90px)">
+				<vxe-table
+					ref="clientTable"
+					:key="tableKey"
+					border="inner"
+					auto-resize
+					resizable
+					height="auto"
+					:loading="loading"
+					show-header-overflow
+					show-overflow
+					highlight-hover-row
+					:menu-config="{}"
+					:sort-config="{ remote: true }"
+					:data="dataList"
+					:checkbox-config="{}"
+					@sort-change="sortChangeHandle"
+				>
+					<vxe-column type="seq" width="60" title="序号" />
+					<vxe-column
+						min-width="180"
+						align="center"
+						title="采购编号"
+						field="purchaseNo"
+					>
+						<template #default="scope">
+							<el-link
+								v-if="hasPermission('psi:foodPurchase:list')"
+								type="primary"
+								:underline="false"
+								@click="view(scope.row.id)"
+							>
+								{{ scope.row.purchaseNo }}
+							</el-link>
+							<span v-else>{{ scope.row.purchaseNo }}</span>
+						</template>
+					</vxe-column>
+					<vxe-column
+						min-width="180"
+						align="center"
+						title="采购时间"
+						field="purchaseTime"
+					/>
+					<vxe-column
+						min-width="160"
+						align="center"
+						title="采购金额"
+						field="totalPrice"
+					/>
+					<vxe-column
+						min-width="160"
+						align="center"
+						title="采购人"
+						field="handledByName"
+					/>
+					<vxe-column
+						min-width="140"
+						align="center"
+						title="修改状态"
+						field="status"
+					>
+						<template #default="scope">
+							<el-button
+								effect="dark"
+								:type="
+									$dictUtils.getDictLabel(
+										'cw_status_flag',
+										scope.row.status,
+										''
+									)
+								"
+								@click="detail(scope.row)"
+							>
+								{{
+									$dictUtils.getDictLabel(
+										"cw_status",
+										scope.row.status,
+										"未发起"
+									)
+								}}
+							</el-button>
+						</template>
+					</vxe-column>
+					<vxe-column
+						title="操作"
+						width="240"
+						fixed="right"
+						align="center"
+					>
+						<template #default="scope">
+							<el-button
+								v-if="
+									hasPermission('psi:foodPurchase:edit') &&
+									['0', '1', '3', '5'].includes(
+										scope.row.status || '0'
+									)
+								"
+								text
+								type="primary"
+								size="small"
+								@click="push(scope.row)"
+							>
+								修改
+							</el-button>
+							<el-button
+								v-if="
+									hasPermission('psi:foodPurchase:edit') &&
+									scope.row.status === '4'
+								"
+								text
+								type="primary"
+								size="small"
+								@click="adjust(scope.row)"
+							>
+								驳回调整
+							</el-button>
+							<el-button
+								v-if="
+									hasPermission('psi:foodPurchase:edit') &&
+									scope.row.status === '2'
+								"
+								text
+								type="primary"
+								size="small"
+								@click="reback(scope.row)"
+							>
+								撤回
+							</el-button>
+							<el-button
+								v-if="
+									hasPermission('psi:foodPurchase:del') &&
+									scope.row.status !== '2'
+								"
+								text
+								type="primary"
+								size="small"
+								@click="del(scope.row.id)"
+							>
+								删除
+							</el-button>
+							<el-button
+								v-if="
+									scope.row.status === '2' &&
+									checkIsAudit(scope.row)
+								"
+								text
+								type="primary"
+								size="small"
+								@click="examine(scope.row)"
+							>
+								审核
+							</el-button>
+						</template>
+					</vxe-column>
+				</vxe-table>
+
+				<vxe-pager
+					background
+					:current-page="tablePage.currentPage"
+					:page-size="tablePage.pageSize"
+					:total="tablePage.total"
+					:page-sizes="[
+						10,
+						20,
+						100,
+						1000,
+						{ label: '全量数据', value: 1000000 },
+					]"
+					:layouts="[
+						'PrevPage',
+						'JumpNumber',
+						'NextPage',
+						'FullJump',
+						'Sizes',
+						'Total',
+					]"
+					@page-change="currentChangeHandle"
+				/>
+
+				<UpdateFoodPurchaseForm
+					ref="updateFoodPurchaseForm"
+					@refreshList="refreshList"
+				/>
+			</div>
+		</div>
+	</div>
+</template>
+
+<script>
+import pick from "lodash.pick";
+import UserSelect from "@/components/userSelect";
+import SelectTree from "@/components/treeSelect/treeSelect.vue";
+import taskService from "@/api/flowable/taskService";
+import processService from "@/api/flowable/processService";
+import userService from "@/api/sys/userService";
+import FoodPurchaseService from "@/api/psi/FoodPurchaseService";
+import UpdateFoodPurchaseForm from "./UpdateFoodPurchaseForm";
+
+export default {
+	components: {
+		UserSelect,
+		SelectTree,
+		UpdateFoodPurchaseForm,
+	},
+	data() {
+		return {
+			searchVisible: true,
+			showHideItem: false,
+			showHideIcon: "el-icon-arrow-down",
+			showHideName: "展开",
+			searchForm: {
+				purchaseNo: "",
+				handledBy: "",
+				handledByOffice: "",
+				status: "",
+				purchaseTimes: [],
+			},
+			dataList: [],
+			tablePage: {
+				total: 0,
+				currentPage: 1,
+				pageSize: 10,
+				orders: [],
+			},
+			tableKey: "",
+			loading: false,
+			statisticTotalPrice: "0.00",
+			processDefinitionAuditId: "",
+			procDefAuditKey: "",
+			isAdmin: false,
+		};
+	},
+	created() {
+		this.foodPurchaseService = new FoodPurchaseService();
+	},
+	computed: {
+		userName() {
+			return this.$store.state.user.name;
+		},
+	},
+	mounted() {
+		this.refreshList();
+	},
+	activated() {
+		this.refreshList();
+	},
+	methods: {
+		showHide() {
+			this.showHideItem = !this.showHideItem;
+			this.showHideIcon = this.showHideItem
+				? "el-icon-arrow-up"
+				: "el-icon-arrow-down";
+			this.showHideName = this.showHideItem ? "隐藏" : "展开";
+		},
+		checkIsAdmin() {
+			userService.is().then((data) => {
+				this.isAdmin = data;
+			});
+		},
+		start() {
+			this.$refs.updateFoodPurchaseForm.init("add", "");
+		},
+		view(id) {
+			this.$refs.updateFoodPurchaseForm.init("view", id);
+		},
+		refreshList() {
+			this.loading = true;
+			this.foodPurchaseService
+				.list({
+					current: this.tablePage.currentPage,
+					size: this.tablePage.pageSize,
+					orders: this.tablePage.orders,
+					...this.searchForm,
+				})
+				.then((data) => {
+					this.dataList = data.records;
+					this.tablePage.total = data.total;
+					this.tableKey = Math.random();
+				})
+				.finally(() => {
+					this.loading = false;
+				});
+			this.refreshStatistics();
+			this.checkIsAdmin();
+			processService.getByName("进销存-食材采购修改").then((data) => {
+				if (!this.commonJS.isEmpty(data.id)) {
+					this.processDefinitionAuditId = data.id;
+					this.procDefAuditKey = data.key;
+				}
+			});
+		},
+		refreshStatistics() {
+			this.foodPurchaseService
+				.statistics({ ...this.searchForm })
+				.then((data) => {
+					this.statisticTotalPrice = data.totalPrice || "0.00";
+				});
+		},
+		currentChangeHandle({ currentPage, pageSize }) {
+			this.tablePage.currentPage = currentPage;
+			this.tablePage.pageSize = pageSize;
+			this.refreshList();
+		},
+		sortChangeHandle(column) {
+			this.tablePage.orders = [];
+			if (column.order != null) {
+				this.tablePage.orders.push({
+					column: this.$utils.toLine(column.property),
+					asc: column.order === "asc",
+				});
+			}
+			this.refreshList();
+		},
+		resetSearch() {
+			this.$refs.searchForm.resetFields();
+			this.refreshList();
+		},
+		del(id) {
+			this.$confirm("确定删除当前数据吗?", "提示", {
+				confirmButtonText: "确定",
+				cancelButtonText: "取消",
+				type: "warning",
+			}).then(() => {
+				this.loading = true;
+				this.foodPurchaseService
+					.remove(id)
+					.then((msg) => {
+						this.$message.success(msg);
+						this.refreshList();
+					})
+					.finally(() => {
+						this.loading = false;
+					});
+			});
+		},
+		push(row) {
+			const title = "发起流程【食材采购修改】";
+			const processTitle = `${this.userName} 在 ${this.moment(
+				new Date()
+			).format("YYYY-MM-DD HH:mm")} 发起了[食材采购修改]`;
+			let status = "startAndHold";
+			if (row.status === "3") {
+				status = "startAndClose";
+			} else if (row.status === "4") {
+				status = "reapplyFlag";
+			}
+			taskService
+				.getTaskDef({
+					procDefId: this.processDefinitionAuditId,
+					businessId: row.id,
+					businessTable: "psi_management_food_purchase_basic",
+				})
+				.then((data) => {
+					this.$router.push({
+						path: "/flowable/task/TaskForm",
+						query: {
+							...pick(
+								data,
+								"formType",
+								"formUrl",
+								"procDefKey",
+								"taskDefKey",
+								"procInsId",
+								"procDefId",
+								"taskId",
+								"status",
+								"title"
+							),
+							procDefId: this.processDefinitionAuditId,
+							procDefKey: this.procDefAuditKey,
+							title,
+							formType: data.formType,
+							formUrl: data.formUrl,
+							formTitle: processTitle,
+							businessTable: "psi_management_food_purchase_basic",
+							businessId: row.id,
+							isShow: "false",
+							status,
+							routePath:
+								"/psiManagement/foodPurchase/FoodPurchaseList",
+						},
+					});
+				});
+		},
+		detail(row) {
+			if (!row.procInsId || ["0", "1"].includes(row.status || "0")) {
+				return;
+			}
+			taskService
+				.getTaskDef({
+					procInsId: row.procInsId,
+					procDefId: this.processDefinitionAuditId,
+				})
+				.then((data) => {
+					this.$router.push({
+						path: "/flowable/task/TaskFormDetail",
+						query: {
+							...pick(
+								data,
+								"formType",
+								"formUrl",
+								"procDefKey",
+								"taskDefKey",
+								"procInsId",
+								"procDefId",
+								"taskId",
+								"status",
+								"title"
+							),
+							isShow: "false",
+							readOnly: true,
+							title: "食材采购修改流程详情",
+							formTitle: "食材采购修改流程详情",
+							businessId: row.id,
+							status: "reback",
+						},
+					});
+				});
+		},
+		reback(row) {
+			this.$confirm("确定撤回该修改申请吗?", "提示", {
+				confirmButtonText: "确定",
+				cancelButtonText: "取消",
+				type: "warning",
+			}).then(() => {
+				this.foodPurchaseService.findById(row.id).then((data) => {
+					if (data.status !== "2") {
+						this.$message.error("数据已发生变化,请刷新后重试");
+						this.refreshList();
+						return;
+					}
+					processService.revokeProcIns(row.procInsId).then((msg) => {
+						this.foodPurchaseService
+							.updateStatusById({ status: "3", id: row.id })
+							.then(() => {
+								this.$message.success(msg);
+								this.refreshList();
+							});
+					});
+				});
+			});
+		},
+		adjust(row) {
+			this.foodPurchaseService.findById(row.id).then((data) => {
+				if (data.status !== "4") {
+					this.$message.error("数据已发生变化,请刷新后重试");
+					this.refreshList();
+					return;
+				}
+				this.todo(row);
+			});
+		},
+		examine(row) {
+			this.foodPurchaseService.findById(row.id).then((data) => {
+				if (data.status !== "2") {
+					this.$message.error("数据已发生变化,请刷新后重试");
+					this.refreshList();
+					return;
+				}
+				this.todo(row);
+			});
+		},
+		todo(row) {
+			taskService.getTaskDefInfo({ taskId: row.taskId }).then((data) => {
+				this.$router.push({
+					path: "/flowable/task/TaskForm",
+					query: {
+						...pick(
+							data,
+							"formType",
+							"formUrl",
+							"procDefKey",
+							"taskDefKey",
+							"procInsId",
+							"procDefId",
+							"taskId",
+							"status",
+							"title",
+							"businessId"
+						),
+						isShow: false,
+						formReadOnly: true,
+						formTitle: `${data.taskName}`,
+						cUser: false,
+						title: `审批【${data.taskName || ""}】`,
+						routePath:
+							"/psiManagement/foodPurchase/FoodPurchaseList",
+					},
+				});
+			});
+		},
+		checkIsAudit(row) {
+			const loginUserId = this.$store.state.user.id;
+			if (this.commonJS.isNotEmpty(row.auditUserIds)) {
+				return row.auditUserIds.includes(loginUserId);
+			}
+			return false;
+		},
+	},
+};
+</script>
+
+<style scoped>
+.statistics-panel {
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	margin-bottom: 12px;
+	padding: 12px 16px;
+	background: linear-gradient(135deg, #f7fbff 0%, #eef7f2 100%);
+	border: 1px solid #dbe8dc;
+	border-radius: 10px;
+}
+
+.statistics-card {
+	display: flex;
+	flex-direction: column;
+	gap: 4px;
+}
+
+.statistics-label {
+	font-size: 13px;
+	color: #6b7280;
+}
+
+.statistics-value {
+	font-size: 28px;
+	font-weight: 700;
+	color: #14532d;
+}
+</style>

+ 76 - 0
src/views/psiManagement/foodPurchase/UpdateFoodPurchaseForm.vue

@@ -0,0 +1,76 @@
+<template>
+	<el-dialog
+		v-model="visible"
+		:title="title"
+		width="1500px"
+		draggable
+		:close-on-click-modal="false"
+		@close="close"
+	>
+		<FoodPurchaseForm
+			ref="foodPurchaseForm"
+			@refreshDataList="handleRefresh"
+		/>
+		<template #footer>
+			<span class="dialog-footer">
+				<el-button @click="close()" icon="el-icon-circle-close"
+					>关闭</el-button
+				>
+				<el-button
+					v-if="method !== 'view'"
+					type="primary"
+					icon="el-icon-circle-check"
+					v-noMoreClick
+					@click="submit"
+				>
+					确定
+				</el-button>
+			</span>
+		</template>
+	</el-dialog>
+</template>
+
+<script>
+import FoodPurchaseForm from "./FoodPurchaseForm";
+
+export default {
+	components: {
+		FoodPurchaseForm,
+	},
+	data() {
+		return {
+			visible: false,
+			method: "view",
+			title: "",
+		};
+	},
+	methods: {
+		init(method, id) {
+			this.method = method;
+			this.title =
+				method === "edit"
+					? "修改食材采购单"
+					: method === "view"
+					? "查看食材采购单"
+					: "新增食材采购单";
+			this.visible = true;
+			this.$nextTick(() => {
+				this.$refs.foodPurchaseForm.init(method, id);
+			});
+		},
+		submit() {
+			this.$refs.foodPurchaseForm.doSubmit();
+		},
+		handleRefresh() {
+			this.visible = false;
+			this.$emit("refreshList");
+		},
+		close() {
+			this.visible = false;
+			if (this.$refs.foodPurchaseForm) {
+				this.$refs.foodPurchaseForm.close();
+			}
+		},
+	},
+};
+</script>

+ 119 - 0
src/views/psiManagement/info/MaterialTypePullForm.vue

@@ -0,0 +1,119 @@
+<template>
+	<div>
+		<el-dialog title="类型选择" :close-on-click-modal="false" draggable width="1100px" height="500px" @close="close"
+			append-to-body v-model="visible">
+			<div style="height: calc(100% - 80px);">
+				<el-form :inline="true" class="query-form" ref="searchForm" :model="searchForm"
+					@keyup.enter.native="refreshList()" @submit.native.prevent>
+					<!-- 搜索框-->
+					<el-form-item label="类型名称" prop="name">
+						<el-input size="small" v-model="searchForm.name" placeholder="请输入类型名称" clearable></el-input>
+					</el-form-item>
+
+					<el-form-item>
+						<el-button type="primary" @click="list()" icon="el-icon-search">查询</el-button>
+						<el-button @click="resetSearch()" icon="el-icon-refresh-right">重置</el-button>
+					</el-form-item>
+				</el-form>
+				<vxe-table border="inner" auto-resize resizable height="500px" :loading="loading" ref="typeTable"
+					show-header-overflow show-overflow highlight-hover-row :menu-config="{}"
+					:sort-config="{ remote: true }" :data="dataList"
+					:tree-config="{ transform: true, rowField: 'id', parentField: 'parentId', expandAll: true }"
+					:checkbox-config="{}">
+					<vxe-column type="seq" width="60" title="序号"></vxe-column>
+					<!--          <vxe-column type="checkbox" width="40" ></vxe-column>-->
+					<vxe-column type="radio" width="60"></vxe-column>
+					<vxe-column title="内容名称" field="name" align="left" tree-node></vxe-column>
+					<vxe-column width="100" title="序号" field="sort"></vxe-column>
+				</vxe-table>
+			</div>
+			<template #footer>
+				<span class="dialog-footer">
+					<el-button @click="close()" icon="el-icon-circle-close">关闭</el-button>
+					<el-button type="primary" v-if="method != 'view'" @click="getProgramForType"
+						icon="el-icon-circle-check" v-noMoreClick>确定</el-button>
+				</span>
+			</template>
+		</el-dialog>
+	</div>
+</template>
+
+<script>
+import MaterialTypeService from '@/api/psi/MaterialTypeService'
+export default {
+	data() {
+		return {
+			searchForm: {
+				name: ''
+			},
+			dataList: [],
+			tablePage: {
+				total: 0,
+				currentPage: 1,
+				pageSize: 10,
+				orders: []
+			},
+			title: '',
+			method: '',
+			visible: false,
+			loading: false
+		}
+	},
+	materialTypeService: null,
+	created() {
+		this.materialTypeService = new MaterialTypeService()
+	},
+	components: {
+	},
+	methods: {
+		init() {
+			this.visible = true
+			this.list()
+		},
+		// 表单提交
+		getProgramForType() {
+			let rows
+			if (this.commonJS.isEmpty(this.$refs.typeTable.getRadioRecord())) {
+				this.$message.error('请选择一条数据')
+				return
+			}
+			rows = this.$refs.typeTable.getRadioRecord()
+			if (rows.children.length > 0) {
+				this.$message.error('请选择子集数据')
+				return
+			}
+			this.$emit('getProgramForType', rows)
+			this.close()
+		},
+		list() {
+			this.loading = true
+			this.materialTypeService.cgList({ ...this.searchForm }).then((data) => {
+				this.dataList = data
+				this.loading = false
+				this.$nextTick(() => {
+					this.$refs.typeTable.setAllTreeExpand(true)
+				})
+			})
+		},
+		// 当前页
+		currentChangeHandle({ currentPage, pageSize }) {
+			this.tablePage.currentPage = currentPage
+			this.tablePage.pageSize = pageSize
+			this.list()
+		},
+		resetSearch() {
+			this.$refs.searchForm.resetFields()
+			this.list()
+		},
+		close() {
+			this.detail = ''
+			this.visible = false
+		}
+	}
+}
+</script>
+<style>
+.messageZindex {
+	z-index: 9999 !important;
+}
+</style>

+ 88 - 0
src/views/psiManagement/info/MaterialTypePullFormByOption.vue

@@ -0,0 +1,88 @@
+<template>
+	<div>
+		<el-dialog title="类型选择" :close-on-click-modal="false" draggable width="1100px" height="500px" @close="close"
+			append-to-body v-model="visible">
+			<div style="height: calc(100% - 80px);">
+				<vxe-table border="inner" auto-resize resizable height="500px" :loading="loading" ref="typeTable"
+					show-header-overflow show-overflow highlight-hover-row :menu-config="{}"
+					:sort-config="{ remote: true }" :data="dataList"
+					:tree-config="{ transform: true, rowField: 'collectTypeId', parentField: 'parentId', expandAll: true }"
+					:checkbox-config="{}">
+					<vxe-column type="seq" width="60" title="序号"></vxe-column>
+					<!--          <vxe-column type="checkbox" width="40" ></vxe-column>-->
+					<vxe-column type="radio" width="180"></vxe-column>
+					<vxe-column title="类型" field="collectType" align="left" tree-node></vxe-column>
+				</vxe-table>
+			</div>
+			<template #footer>
+				<span class="dialog-footer">
+					<el-button @click="close()" icon="el-icon-circle-close">关闭</el-button>
+					<el-button type="primary" v-if="method != 'view'" @click="getProgramForType"
+						icon="el-icon-circle-check" v-noMoreClick>确定</el-button>
+				</span>
+			</template>
+		</el-dialog>
+	</div>
+</template>
+
+<script>
+import MaterialTypeService from '@/api/psi/MaterialTypeService'
+export default {
+	data() {
+		return {
+			searchForm: {
+				name: ''
+			},
+			dataList: [],
+			tablePage: {
+				total: 0,
+				currentPage: 1,
+				pageSize: 10,
+				orders: []
+			},
+			title: '',
+			method: '',
+			visible: false,
+			loading: false
+		}
+	},
+	materialTypeService: null,
+	created() {
+		this.materialTypeService = new MaterialTypeService()
+	},
+	components: {
+	},
+	methods: {
+		init(dataList) {
+			this.visible = true
+			this.dataList = dataList
+			// this.list()
+		},
+		// 表单提交
+		getProgramForType() {
+			let rows
+			if (this.commonJS.isEmpty(this.$refs.typeTable.getRadioRecord())) {
+				this.$message.error('请选择一条数据')
+				return
+			}
+			rows = this.$refs.typeTable.getRadioRecord()
+			if (rows.children.length > 0) {
+				this.$message.error('请选择子集数据')
+				return
+			}
+			this.$emit('getProgramForType', rows)
+			this.close()
+		},
+
+		close() {
+			this.detail = ''
+			this.visible = false
+		}
+	}
+}
+</script>
+<style>
+.messageZindex {
+	z-index: 9999 !important;
+}
+</style>

+ 724 - 0
src/views/psiManagement/info/UpdateInfoForm.vue

@@ -0,0 +1,724 @@
+<template xmlns:v-slot="http://www.w3.org/1999/XSL/Transform">
+	<div>
+		<el-dialog :title="title" :close-on-click-modal="false" draggable width="1500px" @close="close"
+			@keyup.enter.native="doSubmit" v-model="visible" append-to-body>
+			<el-form :model="inputForm" ref="inputForm" v-loading="loading" :class="method === 'view' ? 'readonly' : ''"
+				:disabled="method === 'view'" label-width="110px" @submit.native.prevent>
+
+				<el-divider content-position="left"><i class="el-icon-document"></i> 基础信息</el-divider>
+				<el-row :gutter="20">
+					<el-col :span="12">
+						<el-form-item label="采购编号" prop="purchaseNo">
+							<el-input placeholder="自动生成" v-model="inputForm.purchaseNo" :disabled="true"></el-input>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="采购名称" prop="purchaseSketch" :rules="[{ required: true, message: '采购名称不能为空', trigger: 'blur' }
+						]">
+							<el-input v-model="inputForm.purchaseSketch" placeholder="请填写采购名称"></el-input>
+						</el-form-item>
+					</el-col>
+				</el-row>
+				<el-row :gutter="20">
+					<el-col :span="12">
+						<el-form-item label="经办人" prop="handledBy">
+							<el-input v-model="inputForm.handledBy" :disabled="true"></el-input>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="经办人部门" prop="handledByOffice">
+							<SelectTree :disabled="true" ref="officeTree" :props="{
+								value: 'id',             // ID字段名
+								label: 'name',         // 显示名称
+								children: 'children'    // 子级字段名
+							}" :url="`/system-server/sys/office/treeData?type=2`" :value="inputForm.handledByOffice" :accordion="true"
+								size="default" @getValue="(value) => { inputForm.handledByOffice = value }" />
+							<!--            <el-input v-model="inputForm.handledByOffice" :disabled="true"></el-input>-->
+						</el-form-item>
+					</el-col>
+				</el-row>
+				<el-row :gutter="20">
+					<el-col :span="12">
+						<el-form-item label="采购时间" prop="purchaseDate"
+							:rules="[{ required: true, message: '请选择采购时间', trigger: 'blur' }]">
+							<el-date-picker v-model="inputForm.purchaseDate" type="date" value-format="YYYY-MM-DD"
+								placement="bottom-start" style="width: 100%" placeholder="选择日期">
+							</el-date-picker>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="采购方式" prop="purchaseMode" :rules="[]">
+							<el-select v-model="inputForm.purchaseMode" placeholder="请选择采购方式" style="width:100%;">
+								<el-option v-for="item in $dictUtils.getDictList('psi_purchase_mode')" :key="item.value"
+									:label="item.label" :value="item.value">
+								</el-option>
+							</el-select>
+						</el-form-item>
+					</el-col>
+				</el-row>
+				<el-row :gutter="20">
+					<el-col :span="24">
+						<el-form-item label="备注" prop="remarks">
+							<el-input v-model="inputForm.remarks" type="textarea" :rows="5" maxlength="500"
+								placeholder="请输入简介" show-word-limit>
+							</el-input>
+						</el-form-item>
+					</el-col>
+				</el-row>
+
+				<el-divider content-position="left"><i class="el-icon-document"></i>
+					采购详情
+					<el-button style="margin-left: 20px" type="primary" @click="insertEvent('detail')" plain>
+						新增
+					</el-button>
+				</el-divider>
+				<el-row :gutter="15">
+					<el-col :span="24">
+						<vxe-table border show-footer show-overflow :footer-method="footerMethod" ref="detailTable"
+							class="vxe-table-element" :data="inputForm.detailInfos" style="margin-left: 5em"
+							:key="clientTableKey" highlight-current-row
+							:edit-config="{ trigger: 'click', mode: 'row', showStatus: false, autoClear: true, icon: '-' }"
+							:edit-rules="validRules">
+							<vxe-table-column align="center" field="purchaserAgent" title="采购人" :edit-render="{}"
+								:rules="[{ required: true, message: '请选择采购人', trigger: 'blur' }]">
+								<template v-slot:edit="scope">
+									<el-input v-model="scope.row.purchaserAgent"
+										@focus="userPullListForm(scope.$rowIndex)"></el-input>
+								</template>
+							</vxe-table-column>
+							<vxe-table-column align="center" field="procurementOffice" title="采购部门" :edit-render="{}">
+								<template v-slot:edit="scope">
+									<el-input :disabled='true' v-model="scope.row.procurementOffice"></el-input>
+								</template>
+							</vxe-table-column>
+							<vxe-table-column align="center" field="procurementType" title="采购类型" :edit-render="{}"
+								:rules="[{ required: true, message: '请选择采购类型', trigger: 'blur' }]">
+								<template v-slot:edit="scope">
+									<el-input v-model="scope.row.procurementType"
+										@focus="typePullForm(scope.$rowIndex)"></el-input>
+								</template>
+							</vxe-table-column>
+							<vxe-table-column align="center" field="supplierName" title="供应商" :edit-render="{}"
+								:rules="[{ required: true, message: '请选择供应商', trigger: 'blur' }]">
+								<template v-slot:edit="scope">
+									<vxe-pulldown ref="xDown4" transfer>
+										<template #default>
+											<vxe-input v-model="scope.row.supplierName"
+												:readonly="commonJS.isNotEmpty(scope.row.isSupplier) && scope.row.isSupplier === '2'"
+												:disabled="method === 'view'" placeholder="请填写供应商"
+												@focus="focusEvent4(scope.$rowIndex)"></vxe-input>
+										</template>
+										<template #dropdown>
+											<div style="width: 600px;
+                              height: 300px;
+                              background-color: #fff;
+                              box-shadow: 0 0 6px 2px rgba(0, 0, 0, 0.1);">
+												<vxe-input v-model="suppName" type="search" @search-click="searchClick"
+													placeholder="请输入供应商名称搜索" style="width: 100%" clearable></vxe-input>
+												<vxe-grid border show-overflow auto-resize height="auto"
+													:row-config="{ isHover: true }" :loading="loading4"
+													:pager-config="tablePage4" :data="tableData4"
+													:columns="tableColumn4" @cell-click="cellClickEvent4"
+													@page-change="pageChangeEvent4">
+												</vxe-grid>
+											</div>
+										</template>
+									</vxe-pulldown>
+								</template>
+							</vxe-table-column>
+							<vxe-table-column align="center" field="tradeName" title="商品名称" :edit-render="{}"
+								:rules="[{ required: true, message: '请填写商品名称', trigger: 'blur' }]">
+								<template v-slot:edit="scope">
+									<el-input @change="ifSameValue" v-model="scope.row.tradeName"></el-input>
+								</template>
+							</vxe-table-column>
+							<vxe-table-column align="center" field="tradePrice" title="商品单价(元)" :edit-render="{}"
+								:rules="[{ required: true, message: '请输入商品单价', trigger: 'blur' }]">
+								<template v-slot:edit="scope">
+									<!--              <el-input @change="changeValue" maxlength="15" v-model="scope.row.tradePrice" @keyup.native="scope.row.tradePrice = twoDecimalPlaces(scope.row.tradePrice)"></el-input>-->
+									<el-input @change="changeValue" maxlength="15" v-model="scope.row.tradePrice"
+										@blur="scope.row.tradePrice = twoDecimalPlaces(scope.row.tradePrice)"></el-input>
+								</template>
+							</vxe-table-column>
+							<vxe-table-column align="center" field="tradeNumber" title="商品数量" :edit-render="{}">
+								<template v-slot:edit="scope">
+									<!--              <el-input @change="changeValue" v-model="scope.row.tradeNumber" oninput ="value=value.replace(/\D|^0/g,'')" maxlength="10"></el-input>-->
+									<el-input @change="changeValue" v-model="scope.row.tradeNumber"
+										@blur="scope.row.tradeNumber = twoDecimalPlaces2(scope.row.tradeNumber)"
+										maxlength="10"></el-input>
+								</template>
+							</vxe-table-column>
+							<vxe-table-column align="center" field="priceSum" title="商品总价" :edit-render="{}">
+								<template v-slot:edit="scope">
+									<el-input v-model="scope.row.priceSum"
+										@blur="scope.row.priceSum = twoDecimalPlaces(scope.row.priceSum)"
+										maxlength="15"></el-input>
+								</template>
+							</vxe-table-column>
+							<vxe-table-column align="center" field="company" title="单位" :edit-render="{}"
+								:rules="[{ required: true, message: '请填写单位', trigger: 'blur' }]">
+								<template v-slot:edit="scope">
+									<el-input v-model="scope.row.company"></el-input>
+								</template>
+							</vxe-table-column>
+							<vxe-table-column align="center" field="remarks" title="备注" :edit-render="{}">
+								<template v-slot:edit="scope">
+									<el-input v-model="scope.row.remarks"></el-input>
+								</template>
+							</vxe-table-column>
+							<vxe-table-column title="操作" width="180">
+								<template #default="scope">
+									<vxe-button status="danger" size="small" v-if="method !== 'view'"
+										@click="removeEvent(scope.row, scope.$rowIndex, 'detail')">删除</vxe-button>
+									<vxe-button status="primary" size="small" v-if="method !== 'view'"
+										@click="sss(scope.$rowIndex)">上传附件</vxe-button>
+									<vxe-button status="primary" size="small" v-if="method === 'view'" :disabled="false"
+										@click="seeFileInfo(scope.$rowIndex)">查看文件详情</vxe-button>
+									<!--              <el-button  v-if="formReadOnly" :disabled="false" type="primary" @click="seeFileInfo(scope.$rowIndex)">查看文件详情</el-button>-->
+								</template>
+							</vxe-table-column>
+						</vxe-table>
+					</el-col>
+				</el-row>
+
+				<!--<el-divider content-position="left"><i class="el-icon-document"></i>
+          专用发票信息
+          <el-button style="margin-left: 20px" type="primary" :disabled="method==='view'" @click="insertEvent('amount')" plain>
+            新增
+          </el-button>
+        </el-divider>
+        <el-row  :gutter="15" >
+          <vxe-table
+            border
+            show-overflow
+            ref="amountTable"
+            class="vxe-table-element"
+            :data="inputForm.amountInfos"
+            style="margin-left: 5em"
+            @cell-click=""
+            @edit-closed=""
+            highlight-current-row
+            :edit-config="{trigger: 'click', mode: 'cell', showStatus: true, autoClear: true}"
+          >
+            <vxe-table-column field="code" title="发票代码" :edit-render="{}">
+              <template v-slot:edit="scope">
+                <el-input v-model="scope.row.code" ></el-input>
+              </template>
+            </vxe-table-column>
+            <vxe-table-column field="number" title="发票号" :edit-render="{}">
+              <template v-slot:edit="scope">
+                <el-input v-model="scope.row.number" ></el-input>
+              </template>
+            </vxe-table-column>
+            <vxe-table-column field="amount" title="金额" :edit-render="{}">
+              <template v-slot:edit="scope">
+                <el-input v-model="scope.row.amount" ></el-input>
+              </template>
+            </vxe-table-column>
+            <vxe-table-column field="taxAmount" title="税额" :edit-render="{}">
+              <template v-slot:edit="scope">
+                <el-input v-model="scope.row.taxAmount" ></el-input>
+              </template>
+            </vxe-table-column>
+            <vxe-table-column field="count" title="价税合计" :edit-render="{}">
+              <template v-slot:edit="scope">
+                <el-input v-model="scope.row.count" ></el-input>
+              </template>
+            </vxe-table-column>
+            <vxe-table-column title="操作" width="100">
+              <template v-slot="scope">
+                <el-button  type="danger" @click="removeEvent(scope.row,scope.$rowIndex,'amount')">删除</el-button>
+              </template>
+            </vxe-table-column>
+          </vxe-table>
+        </el-row>-->
+
+			</el-form>
+			<!-- 附件 -->
+			<UpLoadComponent ref="uploadComponent"></UpLoadComponent>
+			<MaterialManagementDialog ref="materialManagementDialog" @getUpload="getUpload"></MaterialManagementDialog>
+			<CwProgramPageForm ref="cwProgramPageForm" @getProgram="getProgram"></CwProgramPageForm>
+			<MaterialTypePullForm ref="materialTypePullForm" @getProgramForType="getProgramForType">
+			</MaterialTypePullForm>
+			<UserPullForm ref="userPullForm" @getProgramForUser="getProgramForUser"></UserPullForm>
+			<template #footer>
+				<span class="dialog-footer">
+					<el-button @click="close()" icon="el-icon-circle-close">关闭</el-button>
+					<el-button type="primary" v-if="method != 'view'" @click="doSubmit()" icon="el-icon-circle-check"
+						v-noMoreClick>确定</el-button>
+				</span>
+			</template>
+		</el-dialog>
+	</div>
+</template>
+
+<script>
+import SelectTree from '@/components/treeSelect/treeSelect.vue'
+import MaterialManagementDialog from '../file/MaterialManagementDialog'
+import CwProgramPageForm from '@/views/cw/reimbursementApproval/info/CwProgramPageForm'
+import MaterialTypePullForm from './MaterialTypePullForm'
+import MaterialManagementService from '@/api/psi/MaterialManagementService'
+import UpLoadComponent from '@/views/common/UpLoadComponent'
+import UserPullForm from '@/views/finance/invoice/UserPullForm'
+import XEUtils from 'xe-utils'
+import SupplierService from '@/api/psi/SupplierService'
+export default {
+	data() {
+		return {
+			validRules: {
+				purchaserAgent: [
+					{ required: true, message: '采购人不能为空' }
+				],
+				procurementOffice: [
+					{ required: true, message: '采购部门不能为空' }
+				],
+				procurementType: [
+					{ required: true, message: '采购类型不能为空' }
+				],
+				tradeName: [
+					{ required: true, message: '商品名称不能为空' }
+				],
+				tradePrice: [
+					{ required: true, message: '商品单价不能为空' }
+				],
+				tradeNumber: [
+					{ required: true, message: '商品数量不能为空' }
+				],
+				priceSum: [
+					{ required: true, message: '商品总价不能为空' }
+				]
+			},
+			title: '',
+			method: '',
+			visible: false,
+			loading: false,
+			inputForm: {
+				tradeTotalPrice: '',  // 商品总价
+				fileInfoLost: [],
+				purchaseMode: '',
+				handledByOffice: '',
+				handledBy: '',
+				purchaseSketch: '',
+				purchaseNo: '', // 采购编号
+				userId: '',
+				purchaseDate: '',
+				remarks: '',
+				detailInfos: [],
+				// amountInfos: [],
+				files: [] // 附件信息
+			},
+			loading4: false,
+			tablePage4: {
+				total: 0,
+				currentPage: 1,
+				pageSize: 10
+			},
+			tableColumn4: [
+				{ field: 'name', title: '名称', align: 'center' },
+				{ field: 'address', title: '地址', align: 'center' },
+				{ field: 'telPhone', title: '联系电话', align: 'center' }
+			],
+			clientTableKey: '',
+			tableData4: [],
+			suppName: '',
+			suppIndex: ''
+		}
+	},
+	MaterialManagementService: null,
+	supplierService: null,
+	created() {
+		this.materialManagementService = new MaterialManagementService()
+		this.supplierService = new SupplierService()
+	},
+	components: {
+		SelectTree,
+		MaterialTypePullForm,
+		CwProgramPageForm,
+		MaterialManagementDialog,
+		UpLoadComponent,
+		UserPullForm
+	},
+	computed: {
+		name() {
+			return this.$store.state.user.name
+		},
+		officeName() {
+			return this.$store.state.user.office.name
+		},
+		purchaserAgentId() {
+			return this.$store.state.user.id
+		},
+		procurementTypeId() {
+			return ''
+		}
+	},
+	methods: {
+		init(method, id) {
+			console.log('method', method)
+			this.method = method
+			console.log('this.method', this.method)
+			this.inputForm = {
+				tradeTotalPrice: '',  // 商品总价
+				fileInfoLost: [],
+				purchaseMode: '',
+				handledByOffice: '',
+				handledBy: this.$store.state.user.name,
+				purchaseSketch: '',
+				purchaseNo: '', // 采购编号
+				userId: this.$store.state.user.id,
+				purchaseDate: new Date(),
+				remarks: '',
+				detailInfos: [],
+				// amountInfos: [],
+				files: [] // 附件信息
+			}
+			if (method === 'add') {
+				this.title = `新建采购类型`
+			} else if (method === 'edit') {
+				this.inputForm.id = id
+				this.title = '修改采购类型'
+			} else if (method === 'view') {
+				this.inputForm.id = id
+				this.title = '查看采购类型'
+			} else if (method === 'addChild') {
+				this.title = '添加下级结构'
+				this.inputForm.parentId = id
+			}
+			this.visible = true
+			this.loading = false
+			this.$nextTick(() => {
+				if (method === 'edit' || method === 'view') { // 修改或者查看
+					this.loading = true
+					this.$refs.inputForm.resetFields()
+					this.materialManagementService.findById(this.inputForm.id).then((data) => {
+						this.inputForm = this.recover(this.inputForm, data)
+						if (this.commonJS.isEmpty(this.inputForm.handledByOffice)) {
+							this.inputForm.handledByOffice = this.$store.state.user.office.id
+						}
+						if (this.commonJS.isNotEmpty(data.purchaserAgentId)) {
+							this.purchaserAgentId = data.purchaserAgentId
+						}
+						if (this.commonJS.isNotEmpty(data.purchaseDate)) {
+							this.inputForm.purchaseDate = data.purchaseDate
+						}
+						if (this.commonJS.isNotEmpty(data.procurementTypeId)) {
+							this.procurementTypeId = data.procurementTypeId
+						}
+						let i = this.inputForm.detailInfos.length
+						for (let j = 0; j < i; j++) {
+							if (this.commonJS.isNotEmpty(this.inputForm.detailInfos[j].tradePrice)) {
+								if (this.commonJS.isNotEmpty(this.inputForm.detailInfos[j].tradeNumber)) {
+									this.inputForm.detailInfos[j].priceSum = this.inputForm.detailInfos[j].tradePrice * this.inputForm.detailInfos[j].tradeNumber
+								}
+							}
+						}
+						this.$refs.uploadComponent.newUpload(method, this.inputForm.files, 'reimbursement')
+						this.inputForm = JSON.parse(JSON.stringify(this.inputForm))
+						this.loading = false
+					})
+				}
+			})
+		},
+		// 值改变事件
+		changeValue() {
+			let i = this.inputForm.detailInfos.length
+			for (let j = 0; j < i; j++) {
+				if (this.commonJS.isNotEmpty(this.inputForm.detailInfos[j].tradePrice)) {
+					if (this.commonJS.isNotEmpty(this.inputForm.detailInfos[j].tradeNumber)) {
+						// parseFloat(item.account).toFixed(2)
+						this.inputForm.detailInfos[j].priceSum = parseFloat(parseFloat(this.inputForm.detailInfos[j].tradePrice) * parseFloat(this.inputForm.detailInfos[j].tradeNumber)).toFixed(2)
+					}
+				}
+			}
+		},
+		getProgramForUser(rows) {
+			this.inputForm.detailInfos[this.indexRow].purchaserAgentId = rows[0].id
+			this.inputForm.detailInfos[this.indexRow].purchaserAgent = rows[0].name
+			this.inputForm.detailInfos[this.indexRow].deptId = rows[0].parentId
+			this.inputForm.detailInfos[this.indexRow].procurementOffice = rows[0].officeName
+			this.indexRow = ''
+			this.$forceUpdate()
+		},
+		getProgramForType(rows) {
+			this.inputForm.detailInfos[this.indexRow].procurementTypeId = rows.id
+			this.inputForm.detailInfos[this.indexRow].procurementType = rows.name
+			this.indexRow = ''
+			this.$forceUpdate()
+		},
+		getProgram(rows) {
+			this.inputForm.detailInfos[this.indexRow].projectId = rows[0].id
+			this.inputForm.detailInfos[this.indexRow].projectName = rows[0].name
+			this.inputForm.detailInfos[this.indexRow].reportNumber = rows[0].reportNo
+			this.indexRow = ''
+			this.$forceUpdate()
+		},
+		getUpload(p, index) {
+			p.then((list) => {
+				// list为返回数据
+				this.inputForm.detailInfos[index].fileInfoLost = list
+				this.inputForm.detailInfos[index].fileNumber = list.length
+				this.tableKeyClient = Math.random()
+			})
+		},
+		twoDecimalPlaces(num) {
+			let str = num.toString()
+			var len1 = str.substr(0, 1)
+			var len2 = str.substr(1, 1)
+			// eslint-disable-next-line eqeqeq
+			if (str.length > 1 && len1 == 0 && len2 != '.') {
+				str = str.substr(1, 1)
+			}
+			// eslint-disable-next-line eqeqeq
+			if (len1 == '.') {
+				str = ''
+			}
+			// eslint-disable-next-line eqeqeq
+			if (str.indexOf('.') != -1) {
+				var str_ = str.substr(str.indexOf('.') + 1)
+				// eslint-disable-next-line eqeqeq
+				if (str_.indexOf('.') != -1) {
+					str = str.substr(0, str.indexOf('.') + str_.indexOf('.') + 1)
+				}
+				if (str_.length > 2) {
+					this.$message.warning(`金额小数点后只能输入两位,请正确输入!`)
+					return (str = '')
+				}
+			}
+			// eslint-disable-next-line no-useless-escape
+			str = str.replace(/[^\d^\.]+/g, '') // 保留数字和小数点
+			return str
+		},
+		twoDecimalPlaces2(num) {
+			let str = num.toString()
+			var len1 = str.substr(0, 1)
+			var len2 = str.substr(1, 1)
+			// eslint-disable-next-line eqeqeq
+			if (str.length > 1 && len1 == 0 && len2 != '.') {
+				str = str.substr(1, 1)
+			}
+			// eslint-disable-next-line eqeqeq
+			if (len1 == '.') {
+				str = ''
+			}
+			// eslint-disable-next-line eqeqeq
+			if (str.indexOf('.') != -1) {
+				var str_ = str.substr(str.indexOf('.') + 1)
+				// eslint-disable-next-line eqeqeq
+				if (str_.indexOf('.') != -1) {
+					str = str.substr(0, str.indexOf('.') + str_.indexOf('.') + 1)
+				}
+				if (str_.length > 2) {
+					this.$message.warning(`商品数量小数点后只能输入两位,请正确输入!`)
+					return (str = '')
+				}
+			}
+			// eslint-disable-next-line no-useless-escape
+			str = str.replace(/[^\d^\.]+/g, '') // 保留数字和小数点
+			return str
+		},
+		// 采购人下拉弹窗
+		userPullListForm(rowIndex) {
+			this.indexRow = rowIndex
+			this.$refs.userPullForm.init()
+		},
+		footerMethod({ columns, data }) {
+			const footerData = [
+				columns.map((column, columnIndex) => {
+					if (columnIndex === 0) {
+						return '商品总价'
+					}
+					if (['priceSum'].includes(column.property)) {
+						// eslint-disable-next-line no-undef
+						this.inputForm.tradeTotalPrice = XEUtils.sum(data, column.property)
+						return XEUtils.sum(data, column.property)
+					}
+					return null
+				})
+			]
+			return footerData
+		},
+		seeFileInfo(index) {
+			if (this.commonJS.isEmpty(this.inputForm.detailInfos[index].fileInfoLost)) {
+				this.inputForm.detailInfos[index].fileInfoLost = []
+			}
+			this.$refs.materialManagementDialog.newUpload('view', this.inputForm.detailInfos[index].fileInfoLost, null, null, null, null, null, false, index)
+		},
+		sss(index) {
+			if (this.commonJS.isEmpty(this.inputForm.detailInfos[index].fileInfoLost)) {
+				this.inputForm.detailInfos[index].fileInfoLost = []
+			}
+			this.$refs.materialManagementDialog.newUpload(null, this.inputForm.detailInfos[index].fileInfoLost, null, null, null, null, null, false, index)
+		},
+		// 采购类型下拉弹窗
+		typePullForm(rowIndex) {
+			this.indexRow = rowIndex
+			// this.$refs.reimbursementTypePullForm.init()
+			// this.$refs.cwReimbursementTypePullForm.init()
+			this.$refs.materialTypePullForm.init()
+		},
+		// 表单提交
+		doSubmit() {
+			this.$refs['inputForm'].validate((valid) => {
+				if (valid) {
+					this.loading = true
+					if (this.$refs.uploadComponent.checkProgress()) {
+						this.loading = false
+						return
+					}
+					if (this.commonJS.isEmpty(this.inputForm.files)) {
+						this.loading = false
+						this.inputForm.files = []
+					}
+					if (this.commonJS.isEmpty(this.inputForm.detailInfos)) {
+						this.$message.error('至少填写一条采购详情信息')
+						this.loading = false
+						return
+					} else {
+						let i = this.inputForm.detailInfos.length
+						for (let j = 0; j < i; j++) {
+							let k = j + 1
+							if (this.commonJS.isEmpty(this.inputForm.detailInfos[j].purchaserAgent)) {
+								this.$message.error('采购详情第' + k + '行请选择采购人')
+								this.loading = false
+								return
+							}
+							if (this.commonJS.isEmpty(this.inputForm.detailInfos[j].procurementType)) {
+								this.$message.error('采购详情第' + k + '行请选择采购类型')
+								this.loading = false
+								return
+							}
+							if (this.commonJS.isEmpty(this.inputForm.detailInfos[j].tradeName)) {
+								this.$message.error('采购详情第' + k + '行请输入商品名称')
+								this.loading = false
+								return
+							}
+							if (this.commonJS.isEmpty(this.inputForm.detailInfos[j].tradePrice)) {
+								this.$message.error('采购详情第' + k + '行请输入商品单价')
+								this.loading = false
+								return
+							}
+							if (this.commonJS.isEmpty(this.inputForm.detailInfos[j].tradeNumber)) {
+								this.$message.error('采购详情第' + k + '行请输入商品数量')
+								this.loading = false
+								return
+							}
+						}
+					}
+					this.inputForm.files = this.$refs.uploadComponent.getDataList()
+					this.materialManagementService.save(this.inputForm).then((data) => {
+						// eslint-disable-next-line no-undef
+						// callback(data.businessTable, data.businessId, this.inputForm)
+						// this.$refs.inputForm.resetFields()
+						this.$emit('refreshList')
+						this.loading = false
+						this.close()
+					}).catch(() => {
+						this.$refs.inputForm.resetFields()
+						this.loading = false
+					})
+				}
+			})
+		},
+		close() {
+			this.$refs.inputForm.resetFields()
+			this.inputForm.detailInfos = []
+			this.inputForm.amountInfos = []
+			this.$refs.uploadComponent.clearUpload()
+			this.visible = false
+		},
+		// 删除
+		removeEvent(row, rowIndex, type) {
+			if (type === 'detail') {
+				this.$refs.detailTable.remove(row)
+				this.inputForm.detailInfos.splice(rowIndex, 1)
+			}
+			if (type === 'amount') {
+				this.$refs.amountTable.remove(row)
+				this.inputForm.amountInfos.splice(rowIndex, 1)
+			}
+		},
+		// 新增
+		async insertEvent(type) {
+			if (type === 'detail') {
+				await this.$refs.detailTable.insert().then((data) => {
+					data.purchaserAgentId = this.purchaserAgentId
+					data.purchaserAgent = this.name
+					data.procurementOffice = this.officeName
+					this.inputForm.detailInfos.push(data)
+					this.clientTableKey = Math.random()
+				})
+			}
+			if (type === 'amount') {
+				await this.$refs.amountTable.insert().then((data) => {
+					this.inputForm.amountInfos.push(data)
+				})
+			}
+		},
+		ifSameValue() {
+			let i = this.inputForm.detailInfos.length
+			for (let j = 0; j < i; j++) {
+				if (j + 1 < i) {
+					if (this.inputForm.detailInfos[j].procurementTypeId === this.inputForm.detailInfos[j + 1].procurementTypeId) {
+						if (this.commonJS.isNotEmpty(this.inputForm.detailInfos[j].tradeName) &&
+							this.commonJS.isNotEmpty(this.inputForm.detailInfos[j + 1].tradeName) && this.inputForm.detailInfos[j].tradeName === this.inputForm.detailInfos[j + 1].tradeName) {
+							// parseFloat(item.account).toFixed(2)
+							this.inputForm.detailInfos.splice(j + 1, 1)
+							this.$message.warning(`同采购类型的商品名称只能输入一条信息!`)
+						}
+					}
+				}
+			}
+		},
+		focusEvent4(rowIndex) {
+			this.$refs.xDown4.showPanel()
+			this.loading4 = true
+			this.suppName = '' // 搜索框的值 清空
+			this.suppIndex = rowIndex // 获取当前行下标
+			this.tablePage4.currentPage = 1
+			this.tablePage4.pageSize = 10
+			this.refreshSupplierList()
+		},
+		suffixClick4() {
+			this.$refs.xDown4.togglePanel()
+		},
+		searchClick() {
+			this.refreshSupplierList()
+		},
+		cellClickEvent4({ row }) {
+			this.inputForm.detailInfos[this.suppIndex].supplierName = row.name
+			this.inputForm.detailInfos[this.suppIndex].supplierId = row.id
+			this.inputForm.detailInfos[this.suppIndex].isSupplier = '2' // isSupplier:手动填写 ‘1’ 选择填写 ‘2’
+			this.suppIndex = ''
+			this.$refs.xDown4.hidePanel()
+		},
+		pageChangeEvent4({ currentPage, pageSize }) {
+			this.tablePage4.currentPage = currentPage
+			this.tablePage4.pageSize = pageSize
+			this.refreshSupplierList()
+		},
+		// 刷新供应商
+		refreshSupplierList() {
+			this.supplierService.list({
+				'current': this.tablePage4.currentPage,
+				'size': this.tablePage4.pageSize,
+				'name': this.suppName
+			}).then((data) => {
+				this.tableData4 = data.records
+				this.tablePage4.total = data.total
+				this.loading4 = false
+			})
+		}
+	}
+}
+</script>
+
+<style>
+.el-divider__text {
+	font-size: 16px;
+	font-weight: bold;
+}
+
+.vxe-pulldown--panel {
+	z-index: 9997 !important
+}
+</style>

+ 651 - 0
src/views/psiManagement/loss/LossForm.vue

@@ -0,0 +1,651 @@
+<template>
+	<div>
+		<el-form ref="inputForm" :model="inputForm" v-loading="loading" :class="method === 'view' ? 'readonly' : ''"
+			:disabled="status === 'audit' || status === 'taskFormDetail'" label-width="100px" @submit.native.prevent>
+			<el-divider content-position="left">
+				<i class="el-icon-document"></i> 基础信息
+			</el-divider>
+			<el-row :gutter="26">
+				<el-col :span="12">
+					<el-form-item label="报损编号" prop="lossNo">
+						<el-input v-model="inputForm.lossNo" placeholder="自动生成" disabled />
+					</el-form-item>
+				</el-col>
+				<el-col :span="12">
+					<el-form-item label="经办人" prop="handledBy">
+						<el-input v-model="inputForm.handledBy" disabled />
+					</el-form-item>
+				</el-col>
+				<el-col :span="12">
+					<el-form-item label="经办部门" prop="handledByOffice">
+						<SelectTree ref="officeTree" :disabled="true"
+							:props="{ value: 'id', label: 'name', children: 'children' }"
+							:url="`/system-server/sys/office/treeData?type=2`" :value="inputForm.handledByOffice"
+							:accordion="true" size="default" @getValue="value => (inputForm.handledByOffice = value)" />
+					</el-form-item>
+				</el-col>
+				<el-col :span="12">
+					<el-form-item label="报损时间" prop="lossDate"
+						:rules="[{ required: true, message: '请选择报损时间', trigger: 'blur' }]">
+						<el-date-picker v-model="inputForm.lossDate" type="date" value-format="YYYY-MM-DD"
+							style="width: 100%" placeholder="选择日期" />
+					</el-form-item>
+				</el-col>
+				<el-col :span="24">
+					<el-form-item label="备注" prop="remarks">
+						<el-input v-model="inputForm.remarks" type="textarea" :rows="4" maxlength="500" show-word-limit
+							placeholder="请输入备注信息" />
+					</el-form-item>
+				</el-col>
+			</el-row>
+
+			<el-divider content-position="left">
+				<i class="el-icon-document"></i> 报损明细
+				<el-button style="margin-left: 20px" type="primary" plain
+					:disabled="method === 'view' || formReadOnly || inputForm.detailInfos.length > 0"
+					@click="insertEvent()">
+					新增
+				</el-button>
+			</el-divider>
+
+			<el-row :gutter="15">
+				<el-col :span="24">
+					<vxe-table ref="detailTable" border show-overflow class="vxe-table-element"
+						:data="inputForm.detailInfos" style="margin-left: 5em" :key="clientTableKey"
+						highlight-current-row
+						:edit-config="{ trigger: 'click', mode: 'row', showStatus: false, autoClear: true, icon: '-' }"
+						:edit-rules="validRules">
+						<vxe-table-column field="recipientAgent" title="报损人" :edit-render="{}"
+							:rules="[{ required: true, message: '请选择报损人', trigger: 'blur' }]">
+							<template #edit="scope">
+								<el-input v-model="scope.row.recipientAgent" :disabled="formReadOnly"
+									@focus="userPullListForm(scope.$rowIndex)" />
+							</template>
+						</vxe-table-column>
+						<vxe-table-column field="recipientOffice" title="报损人部门" :edit-render="{}">
+							<template #edit="scope">
+								<el-input v-model="scope.row.recipientOffice" disabled />
+							</template>
+						</vxe-table-column>
+						<vxe-table-column field="collectType" title="物品类型" :edit-render="{}"
+							:rules="[{ required: true, message: '请选择物品类型', trigger: 'blur' }]">
+							<template #edit="scope">
+								<el-input v-model="scope.row.collectType" :disabled="formReadOnly"
+									@focus="typePullForm(scope.$rowIndex)" />
+							</template>
+						</vxe-table-column>
+						<vxe-table-column field="goodsName" title="物品名称" :edit-render="{}"
+							:rules="[{ required: true, message: '请选择物品名称', trigger: 'blur' }]">
+							<template #edit="scope">
+								<el-input v-model="scope.row.goodsName" :disabled="formReadOnly"
+									@focus="openPurchasePageForm(scope.$rowIndex, scope.row)" />
+							</template>
+						</vxe-table-column>
+						<vxe-table-column field="spec" title="包装规格" :edit-render="{}">
+							<template #edit="scope">
+								<el-input v-model="scope.row.spec" disabled />
+							</template>
+						</vxe-table-column>
+						<vxe-table-column field="produceDate" title="生产日期" :edit-render="{}">
+							<template #edit="scope">
+								<el-date-picker v-model="scope.row.produceDate" type="date" value-format="YYYY-MM-DD"
+									style="width: 100%" disabled />
+							</template>
+						</vxe-table-column>
+						<vxe-table-column field="lossNumber" title="报损数量" :title-suffix="numberTitleSuffix"
+							:edit-render="{}" :rules="[{ required: true, message: '请输入报损数量', trigger: 'blur' }]">
+							<template #edit="scope">
+								<el-input v-model="scope.row.lossNumber" maxlength="10" :disabled="formReadOnly"
+									@blur="handleLossNumberBlur(scope.row)" />
+							</template>
+						</vxe-table-column>
+						<vxe-table-column field="currentInventory" title="当前库存" :edit-render="{}">
+							<template #edit="scope">
+								<el-input v-model="scope.row.currentInventory" disabled />
+							</template>
+						</vxe-table-column>
+						<vxe-table-column field="company" title="单位" :edit-render="{}"
+							:rules="[{ required: true, message: '请输入单位', trigger: 'blur' }]">
+							<template #edit="scope">
+								<el-input v-model="scope.row.company" disabled />
+							</template>
+						</vxe-table-column>
+						<vxe-table-column title="操作" width="220">
+							<template #default="scope">
+								<vxe-button size="small" status="danger" :disabled="formReadOnly"
+									@click="removeEvent(scope.row, scope.$rowIndex)">
+									删除
+								</vxe-button>
+								<vxe-button size="small" status="primary" :disabled="formReadOnly"
+									@click="openUpload(scope.$rowIndex)">
+									上传附件
+								</vxe-button>
+								<vxe-button v-if="formReadOnly" size="small" status="primary"
+									@click="seeFileInfo(scope.$rowIndex)">
+									查看附件
+								</vxe-button>
+							</template>
+						</vxe-table-column>
+					</vxe-table>
+				</el-col>
+			</el-row>
+		</el-form>
+
+		<PurchasePageForm ref="purchasePageForm" @getProject="getContract" />
+		<MaterialManagementDialog ref="materialManagementDialog" @getUpload="getUpload" />
+		<UpLoadComponent ref="uploadComponent" />
+		<MaterialTypePullForm ref="materialTypePullForm" @getProgramForType="getProgramForType" />
+		<UserPullForm ref="userPullForm" @getProgramForUser="getProgramForUser" />
+	</div>
+</template>
+
+<script>
+import LossService from "@/api/psi/LossService";
+import WareHouseService from "@/api/psi/WareHouseService";
+import UpLoadComponent from "@/views/common/UpLoadComponent";
+import SelectTree from "@/components/treeSelect/treeSelect.vue";
+import UserPullForm from "@/views/finance/invoice/UserPullForm";
+import MaterialManagementDialog from "../file/MaterialManagementDialog";
+import MaterialTypePullForm from "../info/MaterialTypePullForm";
+import PurchasePageForm from "./PurchasePageForm";
+
+export default {
+	components: {
+		UpLoadComponent,
+		SelectTree,
+		UserPullForm,
+		MaterialManagementDialog,
+		MaterialTypePullForm,
+		PurchasePageForm,
+	},
+	props: {
+		businessId: {
+			type: String,
+			default: "",
+		},
+		formReadOnly: {
+			type: Boolean,
+			default: false,
+		},
+		status: {
+			type: String,
+			default: "",
+		},
+	},
+	data() {
+		return {
+			numberTitleSuffix: {
+				content: "报损数量按最小单位填写",
+			},
+			validRules: {
+				recipientAgent: [{ required: true, message: "报损人不能为空" }],
+				collectType: [{ required: true, message: "物品类型不能为空" }],
+				goodsName: [{ required: true, message: "物品名称不能为空" }],
+				lossNumber: [{ required: true, message: "报损数量不能为空" }],
+			},
+			method: "",
+			loading: false,
+			indexRow: "",
+			clientTableKey: "",
+			keyWatch: "",
+			inputForm: {
+				handledByOffice: "",
+				handledBy: "",
+				handledById: "",
+				lossNo: "",
+				lossDate: "",
+				remarks: "",
+				detailInfos: [],
+				files: [],
+				procInsId: "",
+				status: "",
+			},
+		};
+	},
+	created() {
+		this.lossService = new LossService();
+		this.wareHouseService = new WareHouseService();
+	},
+	computed: {
+		bus: {
+			get() {
+				return this.businessId;
+			},
+			set(val) {
+				this.businessId = val;
+			},
+		},
+		officeName() {
+			return this.$store.state.user.office.name;
+		},
+	},
+	watch: {
+		keyWatch() {
+			if (this.commonJS.isNotEmpty(this.bus)) {
+				this.init("", this.bus);
+			}
+		},
+		loading(newVal) {
+			this.$emit("changeLoading", newVal);
+			if (this.$refs.uploadComponent) {
+				this.$refs.uploadComponent.changeLoading(newVal);
+			}
+		},
+	},
+	methods: {
+		getKeyWatch(keyWatch) {
+			this.keyWatch = keyWatch;
+		},
+		createDefaultForm() {
+			return {
+				handledByOffice: this.$store.state.user.office.id,
+				handledBy: this.$store.state.user.name,
+				handledById: this.$store.state.user.id,
+				lossNo: "",
+				lossDate: new Date(),
+				remarks: "",
+				detailInfos: [],
+				files: [],
+				procInsId: "",
+				status: "",
+			};
+		},
+		init(method, id) {
+			this.method = method;
+			this.inputForm = this.createDefaultForm();
+			this.inputForm.id = id;
+			if (this.$refs.uploadComponent) {
+				this.$refs.uploadComponent.clearUpload();
+			}
+			this.$nextTick(() => {
+				if (this.$refs.inputForm) {
+					this.$refs.inputForm.resetFields();
+				}
+				if (id && id !== "false") {
+					this.loading = true;
+					this.lossService
+						.findById(id)
+						.then(data => {
+							this.inputForm = this.recover(this.createDefaultForm(), data);
+							this.inputForm.id = data.id;
+							this.inputForm.detailInfos = this.inputForm.detailInfos || [];
+							this.$refs.uploadComponent.newUpload(method, this.inputForm.files || [], "psi");
+							this.inputForm = JSON.parse(JSON.stringify(this.inputForm));
+						})
+						.finally(() => {
+							this.loading = false;
+						});
+				} else {
+					this.$refs.uploadComponent.newUpload(method, [], "psi");
+				}
+			});
+		},
+		insertEvent() {
+			if (this.inputForm.detailInfos.length > 0) {
+				this.$message.warning("报损明细只能保留一条");
+				return;
+			}
+			this.$refs.detailTable.insert().then(row => {
+				row.recipientAgent = this.$store.state.user.name;
+				row.recipientAgentId = this.$store.state.user.id;
+				row.recipientOffice = this.officeName;
+				row.fileInfoLost = [];
+				this.inputForm.detailInfos.push(row);
+				this.clientTableKey = Math.random();
+			});
+		},
+		removeEvent(row, rowIndex) {
+			this.$refs.detailTable.remove(row);
+			this.inputForm.detailInfos.splice(rowIndex, 1);
+		},
+		openUpload(index) {
+			if (this.commonJS.isEmpty(this.inputForm.detailInfos[index].fileInfoLost)) {
+				this.inputForm.detailInfos[index].fileInfoLost = [];
+			}
+			this.$refs.materialManagementDialog.newUpload(
+				null,
+				this.inputForm.detailInfos[index].fileInfoLost,
+				null,
+				null,
+				null,
+				null,
+				null,
+				false,
+				index
+			);
+		},
+		seeFileInfo(index) {
+			if (this.commonJS.isEmpty(this.inputForm.detailInfos[index].fileInfoLost)) {
+				this.inputForm.detailInfos[index].fileInfoLost = [];
+			}
+			this.$refs.materialManagementDialog.newUpload(
+				"view",
+				this.inputForm.detailInfos[index].fileInfoLost,
+				null,
+				null,
+				null,
+				null,
+				null,
+				false,
+				index
+			);
+		},
+		getUpload(promise, index) {
+			promise.then(list => {
+				this.inputForm.detailInfos[index].fileInfoLost = list;
+				this.clientTableKey = Math.random();
+			});
+		},
+		doSubmit() {
+			this.validateForm().then(valid => {
+				if (!valid) {
+					return;
+				}
+				this.loading = true;
+				this.inputForm.files = this.$refs.uploadComponent.getDataList();
+				this.lossService
+					.save(this.inputForm)
+					.then(() => {
+						this.$message.success("操作成功");
+						this.$emit("refreshDataList");
+					})
+					.finally(() => {
+						this.loading = false;
+					});
+			});
+		},
+		close() {
+			if (this.$refs.inputForm) {
+				this.$refs.inputForm.resetFields();
+			}
+			this.inputForm = this.createDefaultForm();
+			if (this.$refs.uploadComponent) {
+				this.$refs.uploadComponent.clearUpload();
+			}
+		},
+		reapplyForm(callback) {
+			this.loading = true;
+			this.lossService.findById(this.inputForm.id).then(data => {
+				if (data.status !== "4") {
+					this.loading = false;
+					this.$message.error("任务数据已发生变化,请在待办中确认");
+					throw new Error("status changed");
+				}
+				this.startFormTrue(callback);
+			});
+		},
+		startForm(callback) {
+			this.loading = true;
+			if (this.commonJS.isNotEmpty(this.inputForm.id)) {
+				this.lossService.findById(this.inputForm.id).then(data => {
+					if (this.commonJS.isNotEmpty(data.status) && !["0", "1", "3"].includes(data.status)) {
+						this.loading = false;
+						this.$message.error("任务数据已发生变化,请在待办中确认");
+						throw new Error("status changed");
+					}
+					this.startFormTrue(callback);
+				});
+				return;
+			}
+			this.startFormTrue(callback);
+		},
+		saveForm(callback) {
+			this.loading = true;
+			if (this.$refs.uploadComponent.checkProgress()) {
+				this.loading = false;
+				return;
+			}
+			this.inputForm.files = this.$refs.uploadComponent.getDataList();
+			this.inputForm.status = "1";
+			this.lossService
+				.save(this.inputForm)
+				.then(() => {
+					callback();
+					this.$refs.inputForm.resetFields();
+				})
+				.finally(() => {
+					this.loading = false;
+				});
+		},
+		startFormTrue(callback) {
+			this.validateForm().then(valid => {
+				if (!valid) {
+					return;
+				}
+				this.loading = true;
+				this.inputForm.files = this.$refs.uploadComponent.getDataList();
+				this.inputForm.status = "2";
+				this.lossService
+					.save(this.inputForm)
+					.then(data => {
+						this.inputForm.id = data.businessId;
+						callback(data.businessTable, data.businessId, this.inputForm);
+						this.$refs.inputForm.resetFields();
+					})
+					.finally(() => {
+						this.loading = false;
+					});
+			});
+		},
+		agreeForm(callback) {
+			this.validateForm(false).then(valid => {
+				if (!valid) {
+					return;
+				}
+				this.loading = true;
+				this.inputForm.files = this.$refs.uploadComponent.getDataList();
+				this.inputForm.status = "5";
+				this.lossService
+					.save(this.inputForm)
+					.then(data => {
+						callback(data.businessTable, data.businessId, this.inputForm);
+					})
+					.finally(() => {
+						this.loading = false;
+					});
+			});
+		},
+		updateStatusById(type, callback) {
+			this.loading = true;
+			if (this.$refs.uploadComponent.checkProgress()) {
+				this.loading = false;
+				throw new Error("uploading");
+			}
+			if (type === "reject" || type === "reback") {
+				this.lossService.findById(this.inputForm.id).then(data => {
+					if (data.status !== "2") {
+						this.loading = false;
+						this.$message.error("任务数据已发生变化,请在待办中确认");
+						throw new Error("status changed");
+					}
+					const status = type === "reject" ? "4" : "3";
+					this.lossService.updateStatusById({ status, id: this.inputForm.id }).then(() => {
+						this.loading = false;
+						callback();
+					});
+				});
+				return;
+			}
+			if (type === "hold") {
+				this.lossService.findById(this.inputForm.id).then(data => {
+					if (data.status !== "4") {
+						this.loading = false;
+						this.$message.error("任务数据已发生变化,请在待办中确认");
+						throw new Error("status changed");
+					}
+					this.lossService.updateStatusById({ status: "1", id: this.inputForm.id }).then(() => {
+						this.loading = false;
+						callback();
+					});
+				});
+			}
+		},
+		typePullForm(rowIndex) {
+			this.indexRow = rowIndex;
+			this.$refs.materialTypePullForm.init();
+		},
+		getProgramForType(row) {
+			const detail = this.inputForm.detailInfos[this.indexRow];
+			detail.collectTypeId = row.id;
+			detail.collectType = row.name;
+			detail.goodsName = "";
+			detail.spec = "";
+			detail.produceDate = "";
+			detail.surplusNumber = "";
+			this.indexRow = "";
+			this.$forceUpdate();
+		},
+		userPullListForm(rowIndex) {
+			this.indexRow = rowIndex;
+			this.$refs.userPullForm.init();
+		},
+		getProgramForUser(rows) {
+			const detail = this.inputForm.detailInfos[this.indexRow];
+			detail.recipientAgentId = rows[0].id;
+			detail.recipientAgent = rows[0].name;
+			detail.recipientOffice = rows[0].officeName;
+			this.indexRow = "";
+			this.$forceUpdate();
+		},
+		openPurchasePageForm(rowIndex, row) {
+			if (this.commonJS.isEmpty(row.collectTypeId)) {
+				this.$message.error("请先选择物品类型");
+				return;
+			}
+			this.indexRow = rowIndex;
+			this.$refs.purchasePageForm.init(row.collectTypeId);
+		},
+		getContract(row) {
+			const detail = this.inputForm.detailInfos[this.indexRow];
+			detail.goodsName = row.tradeName;
+			detail.company = row.company || detail.company;
+			detail.produceDate = row.produceDate || "";
+			detail.shelfLife = row.shelfLife || "";
+			detail.shelfLifeUnit = row.shelfLifeUnit || "";
+			detail.currentInventory = row.currentInventory || "";
+			detail.spec = row.spec || "";
+			detail.company = row.company || "";
+
+			// this.loadInventorySummary(detail);
+			this.indexRow = "";
+			this.$forceUpdate();
+		},
+		loadInventorySummary(detail) {
+			this.wareHouseService
+				.getByProduceDateNotMerge({
+					current: 1,
+					size: 1000,
+					tradeName: detail.goodsName,
+					wareHouseType: detail.collectTypeId,
+				})
+				.then(data => {
+					const records = data.records || [];
+					let total = 0;
+					if (records.length > 0) {
+						detail.spec = records[0].spec || detail.spec;
+						detail.company = records[0].company || detail.company;
+					}
+					records.forEach(item => {
+						const current = Number(item.currentInventory || 0);
+						const spec = Number(item.spec || 1);
+						total += current * spec;
+					});
+					detail.surplusNumber = this.formatNumber(total);
+				});
+		},
+		handleLossNumberBlur(row) {
+			row.lossNumber = this.normalizeNumber(row.lossNumber);
+			if (
+				this.commonJS.isNotEmpty(row.surplusNumber) &&
+				this.commonJS.isNotEmpty(row.lossNumber) &&
+				Number(row.lossNumber) > Number(row.surplusNumber)
+			) {
+				this.$message.error("报损数量不能大于当前库存");
+				row.lossNumber = "";
+			}
+		},
+		normalizeNumber(num) {
+			if (this.commonJS.isEmpty(num)) {
+				return "";
+			}
+			let str = num.toString();
+			const len1 = str.substr(0, 1);
+			const len2 = str.substr(1, 1);
+			if (str.length > 1 && len1 === "0" && len2 !== ".") {
+				str = str.substr(1, 1);
+			}
+			if (len1 === ".") {
+				str = "";
+			}
+			if (str.indexOf(".") !== -1) {
+				const str2 = str.substr(str.indexOf(".") + 1);
+				if (str2.indexOf(".") !== -1) {
+					str = str.substr(0, str.indexOf(".") + str2.indexOf(".") + 1);
+				}
+				if (str2.length > 2) {
+					this.$message.warning("数量小数点后只能输入两位");
+					return "";
+				}
+			}
+			return str.replace(/[^\d^.]+/g, "");
+		},
+		formatNumber(value) {
+			const num = Number(value || 0);
+			if (Number.isNaN(num)) {
+				return "0";
+			}
+			return num % 1 === 0 ? String(num) : num.toFixed(2).replace(/\.?0+$/, "");
+		},
+		validateForm(checkStock = true) {
+			return new Promise(resolve => {
+				this.$refs.inputForm.validate(valid => {
+					if (!valid) {
+						resolve(false);
+						return;
+					}
+					if (this.$refs.uploadComponent.checkProgress()) {
+						resolve(false);
+						return;
+					}
+					if (this.commonJS.isEmpty(this.inputForm.detailInfos)) {
+						this.$message.error("请填写报损明细");
+						resolve(false);
+						return;
+					}
+					const detail = this.inputForm.detailInfos[0];
+					if (this.commonJS.isEmpty(detail.recipientAgent)) {
+						this.$message.error("请选择报损人");
+						resolve(false);
+						return;
+					}
+					if (this.commonJS.isEmpty(detail.collectType)) {
+						this.$message.error("请选择物品类型");
+						resolve(false);
+						return;
+					}
+					if (this.commonJS.isEmpty(detail.goodsName)) {
+						this.$message.error("请选择物品名称");
+						resolve(false);
+						return;
+					}
+					if (this.commonJS.isEmpty(detail.lossNumber)) {
+						this.$message.error("请输入报损数量");
+						resolve(false);
+						return;
+					}
+					if (
+						checkStock &&
+						this.commonJS.isNotEmpty(detail.surplusNumber) &&
+						Number(detail.lossNumber) > Number(detail.surplusNumber)
+					) {
+						this.$message.error("报损数量不能大于当前库存");
+						resolve(false);
+						return;
+					}
+					resolve(true);
+				});
+			});
+		},
+	},
+};
+</script>

+ 436 - 0
src/views/psiManagement/loss/LossList.vue

@@ -0,0 +1,436 @@
+<template>
+	<div class="page">
+		<el-form v-if="searchVisible" ref="searchForm" :model="searchForm" :inline="true" class="query-form m-b-10"
+			@keyup.enter.native="refreshList()" @submit.native.prevent>
+			<el-form-item label="报损编号" prop="lossNo">
+				<el-input v-model="searchForm.lossNo" clearable placeholder="请输入报损编号" />
+			</el-form-item>
+			<el-form-item label="物品名称" prop="goodsName">
+				<el-input v-model="searchForm.goodsName" clearable placeholder="请输入物品名称" />
+			</el-form-item>
+			<el-form-item v-if="showHideItem" label="经办人" prop="handledBy">
+				<UserSelect :limit="1" :modelValue="searchForm.handledBy"
+					@update:modelValue="value => (searchForm.handledBy = value)" />
+			</el-form-item>
+			<el-form-item v-if="showHideItem" label="经办部门" prop="handledByOffice">
+				<SelectTree ref="officeTree" :props="{ value: 'id', label: 'name', children: 'children' }"
+					:url="`/system-server/sys/office/treeData?type=2`" :value="searchForm.handledByOffice"
+					size="default" :accordion="true" @getValue="value => (searchForm.handledByOffice = value)" />
+			</el-form-item>
+			<el-form-item v-if="showHideItem" label="报损时间" prop="lossDates">
+				<el-date-picker v-model="searchForm.lossDates" type="datetimerange" format="YYYY-MM-DD HH:mm:ss"
+					value-format="YYYY-MM-DD HH:mm:ss" range-separator="至" start-placeholder="开始日期"
+					end-placeholder="结束日期" placement="bottom-start" />
+			</el-form-item>
+			<el-form-item>
+				<el-button type="default" :icon="showHideIcon" @click="showHide">{{ showHideName }}</el-button>
+				<el-button type="primary" icon="el-icon-search" @click="refreshList()">查询</el-button>
+				<el-button icon="el-icon-refresh-right" @click="resetSearch()">重置</el-button>
+			</el-form-item>
+		</el-form>
+
+		<div class="jp-table top">
+			<vxe-toolbar :refresh="{ query: refreshList }" custom>
+				<template #buttons>
+					<el-button v-if="hasPermission('psi:loss:add')" type="primary" icon="el-icon-plus" @click="start()">
+						新建
+					</el-button>
+					<el-button v-if="hasPermission('psi:loss:edit')" type="warning" icon="el-icon-plus"
+						@click="exportFile()">
+						导出
+					</el-button>
+				</template>
+				<template #tools>
+					<vxe-button text type="primary" icon="vxe-icon-search" class="tool-btn"
+						:title="searchVisible ? '收起搜索' : '展开搜索'" @click="searchVisible = !searchVisible" />
+				</template>
+			</vxe-toolbar>
+
+			<div style="height: calc(100% - 90px)">
+				<vxe-table ref="clientTable" :key="tableKey" border="inner" auto-resize resizable height="auto"
+					:loading="loading" show-header-overflow show-overflow highlight-hover-row :menu-config="{}"
+					:sort-config="{ remote: true }" :data="dataList" :checkbox-config="{}"
+					@sort-change="sortChangeHandle">
+					<vxe-column type="seq" width="60" title="序号" />
+					<vxe-column min-width="180" align="center" title="报损编号" field="lossNo">
+						<template #default="scope">
+							<el-link v-if="hasPermission('psi:loss:list')" type="primary" :underline="false"
+								@click="view(scope.row.id)">
+								{{ scope.row.lossNo }}
+							</el-link>
+							<span v-else>{{ scope.row.lossNo }}</span>
+						</template>
+					</vxe-column>
+					<vxe-column min-width="180" align="center" title="物品名称" field="goodsName" />
+					<vxe-column min-width="160" align="center" title="经办人" field="handledByName" />
+					<vxe-column min-width="180" align="center" title="经办部门" field="handledByOfficeName" />
+					<vxe-column min-width="160" align="center" title="报损时间" field="lossDate" />
+					<vxe-column min-width="120" align="center" fixed="right" title="状态" field="status">
+						<template #default="scope">
+							<el-button effect="dark"
+								:type="$dictUtils.getDictLabel('cw_status_flag', scope.row.status, '')"
+								@click="detail(scope.row)">
+								{{ $dictUtils.getDictLabel('cw_status', scope.row.status, '') }}
+							</el-button>
+						</template>
+					</vxe-column>
+					<vxe-column title="操作" width="220" fixed="right" align="center">
+						<template #default="scope">
+							<el-button
+								v-if="hasPermission('psi:loss:edit') && scope.row.createBy === $store.state.user.id && (scope.row.status === '1' || scope.row.status === '3')"
+								text type="primary" size="small" @click="push(scope.row)">
+								修改
+							</el-button>
+							<el-button
+								v-else-if="hasPermission('psi:loss:edit') && isAdmin && ['1', '3', '4', '5'].includes(scope.row.status)"
+								text type="primary" size="small" @click="edit(scope.row.id)">
+								修改
+							</el-button>
+							<el-button
+								v-if="hasPermission('psi:loss:edit') && scope.row.createBy === $store.state.user.id && scope.row.status === '2'"
+								text type="primary" size="small" @click="reback(scope.row)">
+								撤回
+							</el-button>
+							<el-button
+								v-if="hasPermission('psi:loss:del') && scope.row.createBy === $store.state.user.id && (scope.row.status === '1' || scope.row.status === '3')"
+								text type="primary" size="small" @click="del(scope.row.id)">
+								删除
+							</el-button>
+							<el-button
+								v-else-if="hasPermission('psi:loss:del') && isAdmin && ['1', '3', '4', '5'].includes(scope.row.status)"
+								text type="primary" size="small" @click="del(scope.row.id)">
+								删除
+							</el-button>
+							<el-button v-if="scope.row.status === '2' && checkIsAudit(scope.row)" text type="primary"
+								size="small" @click="examine(scope.row)">
+								审核
+							</el-button>
+							<el-button
+								v-if="hasPermission('psi:loss:edit') && scope.row.status === '4' && scope.row.createBy === $store.state.user.id"
+								text type="primary" size="small" @click="adjust(scope.row)">
+								驳回调整
+							</el-button>
+						</template>
+					</vxe-column>
+				</vxe-table>
+
+				<vxe-pager background :current-page="tablePage.currentPage" :page-size="tablePage.pageSize"
+					:total="tablePage.total" :page-sizes="[10, 20, 100, 1000, { label: '全量数据', value: 1000000 }]"
+					:layouts="['PrevPage', 'JumpNumber', 'NextPage', 'FullJump', 'Sizes', 'Total']"
+					@page-change="currentChangeHandle" />
+
+				<UpdateLossInfoForm ref="updateLossInfoForm" @refreshList="refreshList" />
+			</div>
+		</div>
+	</div>
+</template>
+
+<script>
+import UserSelect from "@/components/userSelect";
+import SelectTree from "@/components/treeSelect/treeSelect.vue";
+import LossService from "@/api/psi/LossService";
+import UpdateLossInfoForm from "./UpdateLossInfoForm";
+import taskService from "@/api/flowable/taskService";
+import processService from "@/api/flowable/processService";
+import userService from "@/api/sys/userService";
+import pick from "lodash.pick";
+
+export default {
+	components: {
+		UserSelect,
+		SelectTree,
+		UpdateLossInfoForm,
+	},
+	data() {
+		return {
+			searchVisible: true,
+			showHideItem: false,
+			showHideIcon: "el-icon-arrow-down",
+			showHideName: "展示",
+			searchForm: {
+				handledBy: "",
+				handledByOffice: "",
+				lossNo: "",
+				goodsName: "",
+				lossDates: [],
+			},
+			dataList: [],
+			tablePage: {
+				total: 0,
+				currentPage: 1,
+				pageSize: 10,
+				orders: [],
+			},
+			tableKey: "",
+			loading: false,
+			processDefinitionAuditId: "",
+			procDefAuditKey: "",
+			isAdmin: false,
+		};
+	},
+	created() {
+		this.lossService = new LossService();
+	},
+	computed: {
+		userName() {
+			return this.$store.state.user.name;
+		},
+	},
+	mounted() {
+		this.refreshList();
+	},
+	activated() {
+		this.refreshList();
+	},
+	methods: {
+		showHide() {
+			this.showHideItem = !this.showHideItem;
+			this.showHideIcon = this.showHideItem ? "el-icon-arrow-up" : "el-icon-arrow-down";
+			this.showHideName = this.showHideItem ? "隐藏" : "展示";
+		},
+		edit(id) {
+			this.$refs.updateLossInfoForm.init("edit", id);
+		},
+		view(id) {
+			this.$refs.updateLossInfoForm.init("view", id);
+		},
+		checkIsAdmin() {
+			userService.is().then(data => {
+				this.isAdmin = data;
+			});
+		},
+		refreshList() {
+			this.loading = true;
+			this.lossService
+				.list({
+					current: this.tablePage.currentPage,
+					size: this.tablePage.pageSize,
+					orders: this.tablePage.orders,
+					...this.searchForm,
+				})
+				.then(data => {
+					this.dataList = data.records;
+					this.tablePage.total = data.total;
+					this.tableKey = Math.random();
+				})
+				.finally(() => {
+					this.loading = false;
+				});
+			this.checkIsAdmin();
+			processService.getByName("进销存-报损申请").then(data => {
+				if (!this.commonJS.isEmpty(data.id)) {
+					this.processDefinitionAuditId = data.id;
+					this.procDefAuditKey = data.key;
+				}
+			});
+		},
+		currentChangeHandle({ currentPage, pageSize }) {
+			this.tablePage.currentPage = currentPage;
+			this.tablePage.pageSize = pageSize;
+			this.refreshList();
+		},
+		sortChangeHandle(column) {
+			this.tablePage.orders = [];
+			if (column.order != null) {
+				this.tablePage.orders.push({
+					column: this.$utils.toLine(column.property),
+					asc: column.order === "asc",
+				});
+			}
+			this.refreshList();
+		},
+		del(id) {
+			this.$confirm("确定删除当前数据吗?", "提示", {
+				confirmButtonText: "确定",
+				cancelButtonText: "取消",
+				type: "warning",
+			}).then(() => {
+				this.loading = true;
+				this.lossService
+					.remove(id)
+					.then(msg => {
+						this.$message.success(msg);
+						this.refreshList();
+					})
+					.finally(() => {
+						this.loading = false;
+					});
+			});
+		},
+		resetSearch() {
+			this.$refs.searchForm.resetFields();
+			this.refreshList();
+		},
+		start() {
+			const tabTitle = "发起流程【报损申请】";
+			const processTitle = `${this.userName} 在${this.moment(new Date()).format("YYYY-MM-DD HH:mm")}发起了[报损申请]`;
+			taskService
+				.getTaskDef({
+					procDefId: this.processDefinitionAuditId,
+					status: "startAndHold",
+				})
+				.then(data => {
+					this.$router.push({
+						path: "/flowable/task/TaskForm",
+						query: {
+							...pick(data, "formType", "formUrl", "procDefKey", "taskDefKey", "procInsId", "procDefId", "taskId", "status", "title"),
+							procDefId: this.processDefinitionAuditId,
+							procDefKey: this.procDefAuditKey,
+							status: "startAndHold",
+							title: tabTitle,
+							formType: data.formType,
+							formUrl: data.formUrl,
+							formTitle: processTitle,
+							businessId: "false",
+							isShow: false,
+							routePath: "/psiManagement/loss/LossList",
+						},
+					});
+				});
+		},
+		push(row) {
+			const title = "发起流程【报损申请】";
+			const processTitle = `${this.userName} 在${this.moment(new Date()).format("YYYY-MM-DD HH:mm")}发起了[报损申请]`;
+			let status = "startAndHold";
+			if (row.status === "3") {
+				status = "startAndClose";
+			} else if (row.status === "4") {
+				status = "reapplyFlag";
+			}
+			taskService
+				.getTaskDef({
+					procDefId: this.processDefinitionAuditId,
+					businessId: row.id,
+					businessTable: "psi_management_loss_basics",
+				})
+				.then(data => {
+					this.$router.push({
+						path: "/flowable/task/TaskForm",
+						query: {
+							...pick(data, "formType", "formUrl", "procDefKey", "taskDefKey", "procInsId", "procDefId", "taskId", "status", "title"),
+							procDefId: this.processDefinitionAuditId,
+							procDefKey: this.procDefAuditKey,
+							title,
+							formType: data.formType,
+							formUrl: data.formUrl,
+							formTitle: processTitle,
+							businessTable: "psi_management_loss_basics",
+							businessId: row.id,
+							isShow: "false",
+							status,
+							routePath: "/psiManagement/loss/LossList",
+						},
+					});
+				});
+		},
+		detail(row) {
+			if (row.status !== "0" && row.status !== "1") {
+				taskService
+					.getTaskDef({
+						procInsId: row.procInsId,
+						procDefId: this.processDefinitionAuditId,
+					})
+					.then(data => {
+						this.$router.push({
+							path: "/flowable/task/TaskFormDetail",
+							query: {
+								...pick(data, "formType", "formUrl", "procDefKey", "taskDefKey", "procInsId", "procDefId", "taskId", "status", "title"),
+								isShow: "false",
+								readOnly: true,
+								title: "报损申请流程详情",
+								formTitle: "报损申请流程详情",
+								businessId: row.id,
+								status: "reback",
+							},
+						});
+					});
+			}
+		},
+		reback(row) {
+			this.$confirm("确定要撤回该申请吗?", "提示", {
+				confirmButtonText: "确定",
+				cancelButtonText: "取消",
+				type: "warning",
+			}).then(() => {
+				this.lossService.findById(row.id).then(data => {
+					if (data.status !== "2") {
+						this.$message.error("数据已发生变化,请刷新后重试");
+						this.refreshList();
+						return;
+					}
+					processService.revokeProcIns(row.procInsId).then(msg => {
+						this.lossService.updateStatusById({ status: "3", id: row.id }).then(() => {
+							this.$message.success(msg);
+							this.refreshList();
+						});
+					});
+				});
+			});
+		},
+		adjust(row) {
+			this.lossService.findById(row.id).then(data => {
+				if (data.status !== "4") {
+					this.$message.error("数据已发生变化,请刷新后重试");
+					this.refreshList();
+					return;
+				}
+				this.todo(row);
+			});
+		},
+		examine(row) {
+			this.lossService.findById(row.id).then(data => {
+				if (data.status !== "2") {
+					this.$message.error("数据已发生变化,请刷新后重试");
+					this.refreshList();
+					return;
+				}
+				this.todo(row);
+			});
+		},
+		todo(row) {
+			taskService.getTaskDefInfo({ taskId: row.taskId }).then(data => {
+				this.$router.push({
+					path: "/flowable/task/TaskForm",
+					query: {
+						...pick(data, "formType", "formUrl", "procDefKey", "taskDefKey", "procInsId", "procDefId", "taskId", "status", "title", "businessId"),
+						isShow: false,
+						formReadOnly: true,
+						formTitle: `${data.taskName}`,
+						cUser: false,
+						title: `审批【${data.taskName || ""}】`,
+						routePath: "/psiManagement/loss/LossList",
+					},
+				});
+			});
+		},
+		checkIsAudit(row) {
+			const loginUserId = this.$store.state.user.id;
+			if (this.commonJS.isNotEmpty(row.auditUserIds)) {
+				return row.auditUserIds.includes(loginUserId);
+			}
+			return false;
+		},
+		// 导出
+		exportFile() {
+			const options = {
+				filename: `${this.moment(new Date()).format('YYYY-MM-DD')}报损数据导出`,
+				sheetName: '报损数据导出',
+				mode: 'all'
+			}
+			this.loading = true
+			this.lossService.exportFile({
+				current: this.tablePage.currentPage,
+				size: this.tablePage.pageSize,
+				orders: this.tablePage.orders,
+				...options,
+				...this.searchForm
+			}).then((res) => {
+				this.$utils.downloadExcel(res, options.filename)
+				this.loading = false
+			}).catch(() => {
+				this.loading = false
+			})
+		}
+	},
+};
+</script>

+ 151 - 0
src/views/psiManagement/loss/PurchasePageForm.vue

@@ -0,0 +1,151 @@
+<template>
+	<div>
+		<el-dialog title="选择商品" :close-on-click-modal="false" draggable width="1100px" height="500px" @close="close"
+			append-to-body v-model="visible">
+			<div style="height: calc(100% - 80px);">
+				<el-form :inline="true" class="query-form" ref="searchForm" :model="searchForm" @submit.native.prevent>
+					<!-- 搜索框-->
+					<el-form-item label="商品名称" prop="tradeName">
+						<el-input v-model="searchForm.tradeName" placeholder="请输入商品名称" clearable></el-input>
+					</el-form-item>
+
+					<el-form-item>
+						<el-button type="primary" @click="list()" icon="el-icon-search">查询</el-button>
+						<el-button @click="resetSearch()" icon="el-icon-refresh-right">重置</el-button>
+					</el-form-item>
+				</el-form>
+
+				<vxe-table border="inner" auto-resize resizable height="400px" :loading="loading" ref="projectTable"
+					show-header-overflow show-overflow highlight-hover-row :menu-config="{}" :print-config="{}"
+					:sort-config="{ remote: true }" :data="dataList" :row-config="{ isCurrent: true }"
+					:radio-config="{ trigger: 'row' }">
+					<vxe-column type="seq" width="60" title="序号"></vxe-column>
+					<vxe-column type="radio" width="60px"></vxe-column>
+					<vxe-column min-width="230" align="center" title="商品名称" field="tradeName"></vxe-column>
+					<vxe-column min-width="230" align="center" title="生产日期" field="produceDate"></vxe-column>
+					<vxe-column min-width="230" align="center" title="库存量" field="currentInventory"></vxe-column>
+					<!--          <vxe-column min-width="230" align="center" title="商品数量" field="tradeNumber"></vxe-column>-->
+
+				</vxe-table>
+				<vxe-pager background :current-page="tablePage.currentPage" :page-size="tablePage.pageSize"
+					:total="tablePage.total" :page-sizes="[10, 20, 100, 1000, { label: '全量数据', value: 1000000 }]"
+					:layouts="['PrevPage', 'JumpNumber', 'NextPage', 'FullJump', 'Sizes', 'Total']"
+					@page-change="currentChangeHandle">
+				</vxe-pager>
+			</div>
+			<template #footer>
+				<span class="dialog-footer">
+					<el-button @click="close()" icon="el-icon-circle-close">关闭</el-button>
+					<el-button type="primary" v-if="method != 'view'" @click="getProject()" icon="el-icon-circle-check"
+						v-noMoreClick>确定</el-button>
+				</span>
+			</template>
+		</el-dialog>
+	</div>
+</template>
+
+<script>
+// import CollectService from '@/api/materialManagement/CollectService'
+import WareHouseService from '@/api/psi/WareHouseService'
+import Template from '../../../assets/icons/template.vue'
+export default {
+	data() {
+		return {
+			title: '',
+			method: '',
+			visible: false,
+			loading: false,
+			tablePage: {
+				total: 0,
+				currentPage: 1,
+				pageSize: 10,
+				orders: []
+			},
+			dataList: [],
+			searchForm: {
+				wareHouseType: '',
+				tradeName: ''
+			},
+			typeTest: ''
+		}
+	},
+	// collectService: null,
+	wareHouseService: null,
+	created() {
+		// this.collectService = new CollectService()
+		this.wareHouseService = new WareHouseService()
+	},
+	components: {
+		Template
+	},
+	methods: {
+		init(collectType) {
+			this.visible = true
+			this.typeTest = collectType
+			this.list()
+		},
+		// 表单提交
+		getProject() {
+			let row = this.$refs.projectTable.getRadioRecord()
+			if (this.commonJS.isEmpty(row)) {
+				this.$message.error('请选择一条数据')
+				return
+			}
+			if (row.tradeNumber == "0") {
+				this.$message.error('暂无库存,请选择其他商品')
+				return
+			}
+			this.close()
+			this.$emit('getProject', row)
+		},
+		list() {
+			this.loading = true
+			// this.searchForm.createId = this.$store.state.user.id
+			// this.searchForm.status = '5'
+			this.searchForm.wareHouseType = this.typeTest
+			// this.collectService.wareHouseList({
+			//   'current': this.tablePage.currentPage,
+			//   'size': this.tablePage.pageSize,
+			//   'orders': this.tablePage.orders,
+			//   ...this.searchForm
+			// }).then((data) => {
+			//   this.dataList = data.records
+			//   this.tablePage.total = data.total
+			//   this.loading = false
+			// })
+			this.wareHouseService.getByProduceDateNotMerge({
+				'current': this.tablePage.currentPage,
+				'size': this.tablePage.pageSize,
+				'orders': this.tablePage.orders,
+				...this.searchForm
+			}).then((data) => {
+				this.dataList = data.records
+				this.tablePage.total = data.total
+				this.tableKey = Math.random()
+				this.loading = false
+			})
+		},
+		// 当前页
+		currentChangeHandle({ currentPage, pageSize }) {
+			this.tablePage.currentPage = currentPage
+			this.tablePage.pageSize = pageSize
+			this.list()
+		},
+		resetSearch() {
+			this.$refs.searchForm.resetFields()
+			this.list()
+		},
+		close() {
+			this.$refs.searchForm.resetFields()
+			this.visible = false
+			this.typeTest = ''
+		}
+	}
+}
+</script>
+<style scoped>
+/deep/ .el-dialog__body {
+	padding-top: 0px;
+	padding-bottom: 15px;
+}
+</style>

+ 67 - 0
src/views/psiManagement/loss/UpdateLossInfoForm.vue

@@ -0,0 +1,67 @@
+<template>
+	<el-dialog
+		v-model="visible"
+		:title="title"
+		width="1500px"
+		draggable
+		:close-on-click-modal="false"
+		@close="close"
+	>
+		<LossForm ref="lossForm" @refreshDataList="handleRefresh" />
+		<template #footer>
+			<span class="dialog-footer">
+				<el-button @click="close()" icon="el-icon-circle-close">关闭</el-button>
+				<el-button
+					v-if="method !== 'view'"
+					type="primary"
+					icon="el-icon-circle-check"
+					v-noMoreClick
+					@click="submit"
+				>
+					确定
+				</el-button>
+			</span>
+		</template>
+	</el-dialog>
+</template>
+
+<script>
+import LossForm from "./LossForm";
+
+export default {
+	components: {
+		LossForm,
+	},
+	data() {
+		return {
+			visible: false,
+			method: "view",
+			title: "",
+		};
+	},
+	methods: {
+		init(method, id) {
+			this.method = method;
+			this.title =
+				method === "edit" ? "修改报损申请" : method === "view" ? "查看报损申请" : "新建报损申请";
+			this.visible = true;
+			this.$nextTick(() => {
+				this.$refs.lossForm.init(method, id);
+			});
+		},
+		submit() {
+			this.$refs.lossForm.doSubmit();
+		},
+		handleRefresh() {
+			this.visible = false;
+			this.$emit("refreshList");
+		},
+		close() {
+			this.visible = false;
+			if (this.$refs.lossForm) {
+				this.$refs.lossForm.close();
+			}
+		},
+	},
+};
+</script>

+ 157 - 0
src/views/psiManagement/materialType/TypeForm.vue

@@ -0,0 +1,157 @@
+<template>
+	<div>
+		<el-dialog :title="title" :close-on-click-modal="false" draggable width="500px" @close="close"
+			@keyup.enter.native="doSubmit" v-model="visible">
+			<el-form :model="inputForm" ref="inputForm" v-loading="loading" :class="method === 'view' ? 'readonly' : ''"
+				:disabled="method === 'view'" label-width="100px" @submit.native.prevent>
+				<el-row :gutter="15">
+					<el-col :span="21">
+						<el-form-item label="上级节点" prop="parentId">
+							<SelectTree ref="areaTree" v-if="visible" :props="{
+								value: 'id',             // ID字段名
+								label: 'name',         // 显示名称
+								children: 'children'    // 子级字段名
+							}" url="/psi-management-server/psi/materialType/treeData?type=5" :value="inputForm.parentId" :clearable="true"
+								:accordion="true" size="default"
+								@getValue="(value) => { inputForm.parentId = value }" />
+						</el-form-item>
+					</el-col>
+					<el-col :span="21">
+						<el-form-item label="物资名称" prop="name" :rules="[
+							{ required: true, message: '物资名称不能为空', trigger: 'blur' }
+						]">
+							<el-input v-model="inputForm.name" placeholder="请填写物资名称"></el-input>
+						</el-form-item>
+					</el-col>
+					<el-col :span="21">
+						<el-form-item label="序号" prop="sort">
+							<el-input v-model="inputForm.sort" :disabled="true" show-word-limit></el-input>
+						</el-form-item>
+					</el-col>
+				</el-row>
+			</el-form>
+			<template #footer>
+				<span class="dialog-footer">
+					<el-button @click="close()" icon="el-icon-circle-close">关闭</el-button>
+					<el-button type="primary" v-if="method != 'view'" @click="doSubmit()" icon="el-icon-circle-check"
+						v-noMoreClick>确定</el-button>
+				</span>
+			</template>
+		</el-dialog>
+	</div>
+</template>
+
+<script>
+// import ReimbursementTypeService from '@/api/sys/ReimbursementTypeService'
+import ReimbursementApprovalTypeService from '@/api/cw/reimbursementApproval/ReimbursementApprovalTypeService'
+import MaterialTypeService from '@/api/psi/MaterialTypeService'
+import SelectTree from '@/components/treeSelect/treeSelect.vue'
+// import OfficeService from '@/api/sys/OfficeService'
+export default {
+	data() {
+		return {
+			disabled: false,
+			title: '',
+			method: '',
+			visible: false,
+			loading: false,
+			inputForm: {
+				businessType: '',
+				name: '',
+				sort: '',
+				parentId: ''
+			}
+		}
+	},
+	// reimbursementTypeService: null,
+	reimbursementApprovalTypeService: null,
+	materialTypeService: null,
+	// OfficeService: null,
+	created() {
+		// this.reimbursementTypeService = new ReimbursementTypeService()
+		this.reimbursementApprovalTypeService = new ReimbursementApprovalTypeService()
+		this.materialTypeService = new MaterialTypeService()
+		// this.officeService = new OfficeService()
+	},
+	components: {
+		SelectTree
+	},
+	methods: {
+		init(method, id, businessType) {
+			this.method = method
+			this.inputForm = {
+				businessType: '',
+				name: '',
+				sort: '',
+				parentId: ''
+			}
+			if (method === 'add') {
+				this.title = `新建报销类型`
+			} else if (method === 'edit') {
+				this.inputForm.id = id
+				this.title = '修改报销类型'
+			} else if (method === 'view') {
+				this.inputForm.id = id
+				this.title = '查看报销类型'
+			} else if (method === 'addChild') {
+				this.title = '添加下级结构'
+				this.inputForm.parentId = id
+				this.inputForm.businessType = businessType
+			}
+			this.visible = true
+			this.loading = false
+			this.$nextTick(() => {
+				if (method === 'edit' || method === 'view') { // 修改或者查看
+					this.loading = true
+					this.$refs.inputForm.resetFields()
+					this.materialTypeService.findById(this.inputForm.id).then(({ data }) => {
+						this.inputForm = this.recover(this.inputForm, data)
+						this.inputForm = JSON.parse(JSON.stringify(this.inputForm))
+						this.loading = false
+					})
+					// this.reimbursementTypeService.findById(this.inputForm.id).then(({data}) => {
+					//   this.inputForm = this.recover(this.inputForm, data)
+					//   this.inputForm = JSON.parse(JSON.stringify(this.inputForm))
+					//   this.loading = false
+					// })
+				}
+			})
+		},
+		// 表单提交
+		doSubmit() {
+			this.$refs['inputForm'].validate((valid) => {
+				if (valid) {
+					this.loading = true
+					this.materialTypeService.save(this.inputForm).then(({ data }) => {
+						if (data === false) {
+							this.close()
+							this.$message.error('物资名称重复,请重新填写')
+							this.$emit('refreshDataList')
+							this.loading = false
+						} else {
+							this.close()
+							this.$message.success(data)
+							this.$emit('refreshDataList')
+							this.loading = false
+						}
+					}).catch(() => {
+						this.loading = false
+					})
+					// this.reimbursementTypeService.save(this.inputForm).then(({data}) => {
+					//   this.close()
+					//   this.$message.success(data)
+					//   this.$emit('refreshDataList')
+					//   this.loading = false
+					// }).catch(() => {
+					//   this.loading = false
+					// })
+				}
+			})
+		},
+		close() {
+			this.$refs.inputForm.resetFields()
+			this.visible = false
+		}
+	}
+}
+</script>

+ 145 - 0
src/views/psiManagement/materialType/TypeList.vue

@@ -0,0 +1,145 @@
+<template>
+	<div class="page">
+		<el-form :inline="true" class="query-form" ref="searchForm" :model="searchForm"
+			@keyup.enter.native="refreshList()" @submit.native.prevent>
+			<!-- 搜索框-->
+			<el-form-item label="物资名称" prop="name">
+				<el-input v-model="searchForm.name" placeholder="请输入物资名称" clearable></el-input>
+			</el-form-item>
+			<!--      <el-form-item label="序号" prop="sort">-->
+			<!--        <el-input v-model="searchForm.sort" placeholder="请输入序号" clearable></el-input>-->
+			<!--      </el-form-item>-->
+
+			<el-form-item>
+				<el-button type="primary" @click="refreshList()" icon="el-icon-search">查询</el-button>
+				<el-button @click="resetSearch()" icon="el-icon-refresh-right">重置</el-button>
+			</el-form-item>
+		</el-form>
+
+		<div class="jp-table top" style="">
+			<vxe-toolbar :refresh="{ query: refreshList }" custom>
+				<template #buttons>
+					<el-button v-if="hasPermission('psi:type:add')" type="primary" icon="el-icon-plus"
+						@click="add()">新建</el-button>
+					<!--          <el-button v-if="hasPermission('program:configuration:type:del')" type="danger"  icon="el-icon-delete" @click="del()" :disabled="$refs.typeTable && $refs.typeTable.getCheckboxRecords().length === 0" plain>删除</el-button>-->
+				</template>
+			</vxe-toolbar>
+			<div style="height: calc(100% - 50px)">
+				<vxe-table border="inner" auto-resize resizable height="auto" :loading="loading" ref="typeTable"
+					show-header-overflow show-overflow highlight-hover-row :menu-config="{}"
+					:sort-config="{ remote: true }" :data="dataList"
+					:tree-config="{ transform: true, rowField: 'id', parentField: 'parentId', expandAll: true }"
+					:checkbox-config="{}">
+					<vxe-column type="seq" width="60" title="序号"></vxe-column>
+					<vxe-column type="checkbox" width="60"></vxe-column>
+					<vxe-column title="物资名称" field="name" align="left" tree-node></vxe-column>
+					<vxe-column width="100" title="序号" field="sort"></vxe-column>
+
+					<vxe-column title="操作" width="230px" fixed="right" align="center">
+						<template #default="scope">
+							<el-button
+								v-if="hasPermission('psi:type:edit') && (scope.row.level === '1' || scope.row.level === '2' || scope.row.level === '3' || scope.row.level === '4')"
+								text type="primary"
+								@click="addChild(scope.row.id, scope.row.businessType)">添加下级结构</el-button>
+							<el-button v-if="hasPermission('psi:type:edit')" text type="primary"
+								@click="edit(scope.row.id)">修改</el-button>
+							<el-button v-if="hasPermission('psi:type:remove')" text type="primary"
+								@click="del(scope.row.id)">删除</el-button>
+						</template>
+					</vxe-column>
+				</vxe-table>
+
+			</div>
+		</div>
+		<TypeForm ref="typeForm" @refreshDataList="refreshList"></TypeForm>
+	</div>
+</template>
+
+<script>
+import MaterialTypeService from '@/api/psi/MaterialTypeService'
+import TypeForm from './TypeForm'
+export default {
+	data() {
+		return {
+			searchForm: {
+				name: '',
+				no: ''
+			},
+			dataList: [],
+			tablePage: {
+				total: 0,
+				currentPage: 1,
+				pageSize: 10,
+				orders: []
+			},
+			loading: false
+		}
+	},
+	materialTypeService: null,
+	created() {
+		this.materialTypeService = new MaterialTypeService()
+	},
+	components: {
+		TypeForm
+	},
+	mounted() {
+		this.refreshList()
+	},
+	activated() {
+		this.refreshList()
+	},
+	methods: {
+		// 新增
+		add() {
+			this.$refs.typeForm.init('add', '')
+		},
+		addChild(id, businessType) {
+			this.$refs.typeForm.init('addChild', id, businessType)
+		},
+		// 修改
+		edit(id) {
+			id = id || this.$refs.typeTable.getCheckboxRecords().map(item => {
+				return item.id
+			})[0]
+			this.$refs.typeForm.init('edit', id)
+		},
+		// 查看
+		view(id) {
+			this.$refs.typeForm.init('view', id)
+		},
+		// 获取数据列表
+		refreshList() {
+			this.loading = true
+			this.materialTypeService.list({ ...this.searchForm }).then((data) => {
+				this.dataList = data
+				this.loading = false
+				this.$nextTick(() => {
+					this.$refs.typeTable.setAllTreeExpand(true)
+				})
+			})
+		},
+		// 删除
+		del(id) {
+			let ids = id || this.$refs.typeTable.getCheckboxRecords().map(item => {
+				return item.id
+			}).join(',')
+			this.$confirm(`确定删除所选项吗?`, '提示', {
+				confirmButtonText: '确定',
+				cancelButtonText: '取消',
+				type: 'warning'
+			}).then(() => {
+				this.loading = true
+				this.materialTypeService.remove(ids).then((data) => {
+					this.$message.success(data)
+					this.refreshList()
+					this.loading = false
+				})
+			})
+		},
+		resetSearch() {
+			this.$refs.searchForm.resetFields()
+			this.refreshList()
+		}
+	}
+}
+</script>

+ 967 - 0
src/views/psiManagement/purchase/PurchaseForm.vue

@@ -0,0 +1,967 @@
+<template xmlns:v-slot="http://www.w3.org/1999/XSL/Transform">
+	<div>
+		<el-form :model="inputForm" ref="inputForm" v-loading="loading" :class="method === 'view' ? 'readonly' : ''"
+			:disabled="status === 'audit' || status === 'taskFormDetail'" label-width="110px" @submit.native.prevent>
+
+			<el-divider content-position="left"><i class="el-icon-document"></i> 基础信息</el-divider>
+			<el-row :gutter="20">
+				<el-col :span="12">
+					<el-form-item label="采购编号" prop="purchaseNo">
+						<el-input placeholder="自动生成" v-model="inputForm.purchaseNo" :disabled="true"></el-input>
+					</el-form-item>
+				</el-col>
+				<el-col :span="12">
+					<el-form-item label="采购名称" prop="purchaseSketch" :rules="[{ required: true, message: '采购名称不能为空', trigger: 'blur' }
+					]">
+						<el-input v-model="inputForm.purchaseSketch" placeholder="请填写采购名称"></el-input>
+					</el-form-item>
+				</el-col>
+			</el-row>
+			<el-row :gutter="20">
+				<el-col :span="12">
+					<el-form-item label="经办人" prop="handledBy">
+						<el-input v-model="inputForm.handledBy" :disabled="true"></el-input>
+					</el-form-item>
+				</el-col>
+				<el-col :span="12">
+					<el-form-item label="经办人部门" prop="handledByOffice">
+						<SelectTree :disabled="true" ref="officeTree" :props="{
+							value: 'id',             // ID字段名
+							label: 'name',         // 显示名称
+							children: 'children'    // 子级字段名
+						}" :url="`/system-server/sys/office/treeData?type=2`" :value="inputForm.handledByOffice" :accordion="true"
+							size="default" @getValue="(value) => { inputForm.handledByOffice = value }" />
+						<!--            <el-input v-model="inputForm.handledByOffice" :disabled="true"></el-input>-->
+					</el-form-item>
+				</el-col>
+			</el-row>
+			<el-row :gutter="20">
+				<el-col :span="12">
+					<el-form-item label="采购申请时间" prop="purchaseDate"
+						:rules="[{ required: true, message: '请选择采购申请时间', trigger: 'blur' }]">
+						<el-date-picker v-model="inputForm.purchaseDate" type="date" value-format="YYYY-MM-DD"
+							placement="bottom-start" style="width: 100%" placeholder="选择日期">
+						</el-date-picker>
+					</el-form-item>
+				</el-col>
+				<el-col :span="12">
+					<el-form-item label="采购方式" prop="purchaseMode" :rules="[
+						{ required: true, message: '采购方式不能为空', trigger: 'blur' },
+					]">
+						<el-select v-model="inputForm.purchaseMode" placeholder="请选择采购方式" style="width:100%;">
+							<el-option v-for="item in $dictUtils.getDictList('psi_purchase_mode')" :key="item.value"
+								:label="item.label" :value="item.value">
+							</el-option>
+						</el-select>
+					</el-form-item>
+				</el-col>
+			</el-row>
+			<el-row :gutter="20">
+				<el-col :span="24">
+					<el-form-item label="备注" prop="remarks">
+						<el-input v-model="inputForm.remarks" type="textarea" :rows="5" maxlength="500"
+							placeholder="请填写备注信息" show-word-limit>
+						</el-input>
+					</el-form-item>
+				</el-col>
+			</el-row>
+
+			<el-divider content-position="left"><i class="el-icon-document"></i>
+				采购详情
+				<el-button style="margin-left: 20px" type="primary"
+					:disabled="method === 'view' || status === 'audit' || status === 'taskFormDetail'"
+					@click="insertEvent('detail')" plain>
+					新增
+				</el-button>
+			</el-divider>
+			<el-row :gutter="15">
+				<el-col :span="24">
+					<vxe-table border show-footer show-overflow :footer-method="footerMethod" ref="detailTable"
+						class="vxe-table-element" :data="inputForm.detailInfos" :key="clientTableKey"
+						style="margin-left: 5em" highlight-current-row
+						:edit-config="{ trigger: 'click', mode: 'row', showStatus: false, autoClear: true, icon: '-' }"
+						:edit-rules="validRules">
+						<vxe-table-column align="center" field="purchaserAgent" title="采购人" :edit-render="{}"
+							:rules="[{ required: true, message: '请选择采购人', trigger: 'blur' }]">
+							<template #edit="scope">
+								<el-input v-model="scope.row.purchaserAgent"
+									@focus="userPullListForm(scope.$rowIndex)"></el-input>
+							</template>
+						</vxe-table-column>
+						<vxe-table-column align="center" field="procurementOffice" title="采购部门" :edit-render="{}">
+							<template #edit="scope">
+								<el-input :disabled='true' v-model="scope.row.procurementOffice"></el-input>
+							</template>
+						</vxe-table-column>
+						<vxe-table-column align="center" field="procurementType" title="采购类型" :edit-render="{}"
+							:rules="[{ required: true, message: '请选择采购类型', trigger: 'blur' }]">
+							<template v-slot:edit="scope">
+								<el-input v-model="scope.row.procurementType"
+									@focus="typePullForm(scope.$rowIndex)"></el-input>
+							</template>
+						</vxe-table-column>
+						<vxe-table-column align="center" field="tradeName" title="商品名称" :edit-render="{}" :rules="[]">
+							<template v-slot:edit="scope">
+								<!--              <el-input @change="ifSameValue" v-model="scope.row.tradeName"></el-input>-->
+								<vxe-pulldown ref="xDown1" transfer>
+									<template #default>
+										<vxe-input v-model="scope.row.tradeName" placeholder="请输入商品名称" maxlength="64"
+											@focus="focusEvent1(scope.row)" @input="keyupEvent1(scope.row)"></vxe-input>
+									</template>
+									<template #dropdown>
+										<div class="my-dropdown1">
+											<div class="list-item1" v-for="item in scope.row.tradeNameData"
+												:key="item.id" @click="selectEvent1(scope.row, item)">
+												<span>{{ item.tradeName }}</span>
+											</div>
+										</div>
+									</template>
+								</vxe-pulldown>
+							</template>
+						</vxe-table-column>
+						<vxe-table-column align="center" field="supplierName" title="供应商" :edit-render="{}"
+							:rules="[{ required: true, message: '请选择供应商', trigger: 'blur' }]">
+							<template v-slot:edit="scope">
+								<vxe-pulldown ref="xDown4" transfer>
+									<template #default>
+										<vxe-input v-model="scope.row.supplierName"
+											:readonly="scope.row.isSupplier === '2'"
+											:disabled="status === 'audit' || status === 'taskFormDetail'"
+											placeholder="请填写供应商" @focus="focusEvent4(scope.$rowIndex)"></vxe-input>
+									</template>
+									<template #dropdown>
+										<div style="width: 600px;
+                              height: 300px;
+                              background-color: #fff;
+                              box-shadow: 0 0 6px 2px rgba(0, 0, 0, 0.1);">
+											<vxe-input v-model="suppName" type="search" @search-click="searchClick"
+												placeholder="请输入供应商名称搜索" style="width: 100%" clearable></vxe-input>
+											<vxe-grid border show-overflow auto-resize height="auto"
+												:row-config="{ isHover: true }" :loading="loading4"
+												:pager-config="tablePage4" :data="tableData4" :columns="tableColumn4"
+												@cell-click="cellClickEvent4" @page-change="pageChangeEvent4">
+											</vxe-grid>
+										</div>
+									</template>
+								</vxe-pulldown>
+							</template>
+						</vxe-table-column>
+						<vxe-table-column align="center" field="tradePrice" title="商品单价(元)" :edit-render="{}"
+							:rules="[]">
+							<template v-slot:edit="scope">
+								<!--              <el-input @change="changeValue" maxlength="15" v-model="scope.row.tradePrice" @keyup.native="scope.row.tradePrice = twoDecimalPlaces(scope.row.tradePrice)"></el-input>-->
+								<el-input @change="changeValue" maxlength="15" v-model="scope.row.tradePrice"
+									@blur="scope.row.tradePrice = twoDecimalPlaces2(scope.row.tradePrice)"></el-input>
+							</template>
+						</vxe-table-column>
+						<vxe-table-column align="center" field="tradeNumber" title="商品数量" :edit-render="{}">
+							<template v-slot:edit="scope">
+								<!--              <el-input @change="changeValue" v-model="scope.row.tradeNumber" oninput ="value=value.replace(/\D|^0/g,'')" maxlength="10"></el-input>-->
+								<el-input @change="changeValue" v-model="scope.row.tradeNumber"
+									@blur="scope.row.tradeNumber = twoDecimalPlaces2(scope.row.tradeNumber)"
+									maxlength="10"></el-input>
+							</template>
+						</vxe-table-column>
+						<vxe-table-column align="center" field="priceSum" title="商品总价" :edit-render="{}">
+							<template v-slot:edit="scope">
+								<el-input v-model="scope.row.priceSum" :readonly="true" maxlength="15"></el-input>
+								<!--              <el-input v-model="scope.row.priceSum" @blur="scope.row.priceSum = twoDecimalPlaces(scope.row.priceSum, scope.$rowIndex)" maxlength="15"></el-input>-->
+							</template>
+						</vxe-table-column>
+						<vxe-table-column align="center" field="company" title="单位" :edit-render="{}"
+							:rules="[{ required: true, message: '请填写单位', trigger: 'blur' }]">
+							<template v-slot:edit="scope">
+								<el-input v-model="scope.row.company"></el-input>
+							</template>
+						</vxe-table-column>
+						<vxe-table-column align="center" field="remarks" title="备注" :edit-render="{}">
+							<template v-slot:edit="scope">
+								<el-input v-model="scope.row.remarks"></el-input>
+							</template>
+						</vxe-table-column>
+						<vxe-table-column align="center" title="操作" width="300">
+							<template v-slot="scope">
+								<vxe-button size="small" :disabled="status === 'audit' || status === 'taskFormDetail'"
+									status="danger"
+									@click="removeEvent(scope.row, scope.$rowIndex, 'detail')">删除</vxe-button>
+								<vxe-button size="small" status="primary"
+									:disabled="status === 'audit' || status === 'taskFormDetail'"
+									@click="sss(scope.$rowIndex)">上传附件</vxe-button>
+								<vxe-button size="small" status="primary"
+									v-if="status === 'audit' || status === 'taskFormDetail'" :disabled="false"
+									@click="seeFileInfo(scope.$rowIndex)">查看文件详情</vxe-button>
+							</template>
+						</vxe-table-column>
+					</vxe-table>
+				</el-col>
+			</el-row>
+
+
+		</el-form>
+		<!-- 附件 -->
+		<MaterialManagementDialog ref="materialManagementDialog" @getUpload="getUpload"></MaterialManagementDialog>
+		<UpLoadComponent ref="uploadComponent"></UpLoadComponent>
+		<CwProgramPageForm ref="cwProgramPageForm" @getProgram="getProgram"></CwProgramPageForm>
+		<MaterialTypePullForm ref="materialTypePullForm" @getProgramForType="getProgramForType"></MaterialTypePullForm>
+		<!--      <CwReimbursementTypePullForm ref="cwReimbursementTypePullForm" @getProgramForType="getProgramForType"></CwReimbursementTypePullForm>-->
+		<UserPullForm ref="userPullForm" @getProgramForUser="getProgramForUser"></UserPullForm>
+	</div>
+</template>
+
+<script>
+import CommonApi from '@/api/cw/common/CommonApi'
+import MaterialManagementDialog from '../file/MaterialManagementDialog'
+import MaterialManagementService from '@/api/psi/MaterialManagementService'
+import UpLoadComponent from '@/views/common/UpLoadComponent'
+import SelectTree from '@/components/treeSelect/treeSelect.vue'
+import XEUtils from 'xe-utils'
+import CwProgramPageForm from '@/views/cw/reimbursementApproval/info/CwProgramPageForm'
+import MaterialTypePullForm from '../info/MaterialTypePullForm'
+import UserPullForm from '@/views/finance/invoice/UserPullForm'
+import SupplierService from '@/api/psi/SupplierService'
+import WareHouseService from '@/api/psi/WareHouseService'
+export default {
+	data() {
+		return {
+			validRules: {
+				purchaserAgent: [
+					{ required: true, message: '采购人不能为空' }
+				],
+				procurementOffice: [
+					{ required: true, message: '采购部门不能为空' }
+				],
+				procurementType: [
+					{ required: true, message: '采购类型不能为空' }
+				],
+				tradeName: [
+					{ required: true, message: '商品名称不能为空' }
+				]
+			},
+			title: '',
+			method: '',
+			visible: false,
+			loading: false,
+			indexRow: '',
+			inputForm: {
+				tradeTotalPrice: '',  // 商品总价
+				fileInfoLost: [],
+				purchaseMode: '',
+				handledByOffice: '',
+				handledBy: '',
+				handledById: '',
+				purchaseSketch: '',
+				purchaseNo: '', // 采购编号
+				userId: '',
+				purchaseDate: '',
+				remarks: '',
+				detailInfos: [],
+				procInsId: '',
+				// amountInfos: [],
+				files: [] // 附件信息
+			},
+			keyWatch: '',
+			clientTableKey: '',
+			loading4: false,
+			tablePage4: {
+				total: 0,
+				currentPage: 1,
+				pageSize: 10
+			},
+			tableColumn4: [
+				{ field: 'name', title: '名称', align: 'center' },
+				{ field: 'address', title: '地址', align: 'center' },
+				{ field: 'telPhone', title: '联系电话', align: 'center' }
+			],
+			tableData4: [],
+			suppName: '',
+			suppIndex: ''
+		}
+	},
+	MaterialManagementService: null,
+	commonApi: null,
+	supplierService: null,
+	wareHouseService: null,
+	created() {
+		this.materialManagementService = new MaterialManagementService()
+		this.commonApi = new CommonApi()
+		this.supplierService = new SupplierService()
+		this.wareHouseService = new WareHouseService()
+	},
+	props: {
+		businessId: {
+			type: String,
+			default: ''
+		},
+		formReadOnly: {
+			type: Boolean,
+			default: false
+		},
+		status: {
+			type: String,
+			default: ''
+		}
+	},
+	components: {
+		MaterialManagementDialog,
+		UpLoadComponent,
+		SelectTree,
+		CwProgramPageForm,
+		MaterialTypePullForm,
+		UserPullForm
+	},
+	computed: {
+		bus: {
+			get() {
+				return this.businessId
+			},
+			set(val) {
+				this.businessId = val
+			}
+		},
+		name() {
+			return this.$store.state.user.name
+		},
+		officeName() {
+			return this.$store.state.user.office.name
+		},
+		purchaserAgentId() {
+			return this.$store.state.user.id
+		},
+		procurementTypeId() {
+			return ''
+		}
+	},
+	watch: {
+		'keyWatch': {
+			handler(newVal) {
+				if (this.commonJS.isNotEmpty(this.bus)) {
+					this.init('', this.bus)
+				} else {
+					this.$nextTick(() => {
+						this.$refs.inputForm.resetFields()
+					})
+				}
+			}
+		},
+		'loading': {
+			handler(newVal) {
+				this.$emit('changeLoading', newVal)
+				this.$refs.uploadComponent.changeLoading(newVal)
+			}
+		}
+	},
+	methods: {
+		getKeyWatch(keyWatch) {
+			this.keyWatch = keyWatch
+		},
+		init(method, id) {
+			this.method = method
+			this.inputForm = {
+				tradeTotalPrice: '',  // 商品总价
+				fileInfoLost: [],
+				purchaseMode: '',
+				handledByOffice: '',
+				handledBy: this.$store.state.user.name,
+				handledById: this.$store.state.user.id,
+				purchaseSketch: '',
+				purchaseNo: '', // 采购编号
+				userId: this.$store.state.user.id,
+				purchaseDate: this.moment(new Date()).format('YYYY-MM-DD'),
+				remarks: '',
+				detailInfos: [],
+				procInsId: '',
+				// amountInfos: [],
+				files: [] // 附件信息
+			}
+			if (method === 'add') {
+				this.title = `新建采购申请`
+			} else if (method === 'edit') {
+				this.title = '修改采购申请'
+			}
+			this.inputForm.id = id
+			this.visible = true
+			this.loading = false
+			this.$refs.uploadComponent.clearUpload()
+			this.$nextTick(() => {
+				if ((this.status === 'audit' || this.status === 'taskFormDetail') && this.businessId !== 'false') {
+					method = 'view'
+				}
+				if (this.commonJS.isEmpty(this.inputForm.handledByOffice)) {
+					this.inputForm.handledByOffice = this.$store.state.user.office.id
+				}
+				if (this.status === 'audit' || this.status === 'taskFormDetail') {
+					method = 'view'
+				}
+				console.log('method', method)
+				this.loading = true
+				this.$refs.inputForm.resetFields()
+				this.materialManagementService.findById(this.inputForm.id).then((data) => {
+					if (this.inputForm.id !== 'false') {
+						this.inputForm = this.recover(this.inputForm, data)
+						if (this.commonJS.isEmpty(this.inputForm.handledByOffice)) {
+							this.inputForm.handledByOffice = this.$store.state.user.office.id
+						}
+						if (this.commonJS.isNotEmpty(data.purchaserAgentId)) {
+							this.purchaserAgentId = data.purchaserAgentId
+						}
+						// if (this.commonJS.isNotEmpty(data.procurementTypeId)) {
+						//   this.procurementTypeId = data.procurementTypeId
+						// }
+						let i = this.inputForm.detailInfos.length
+						for (let j = 0; j < i; j++) {
+							if (this.commonJS.isNotEmpty(this.inputForm.detailInfos[j].tradePrice)) {
+								if (this.commonJS.isNotEmpty(this.inputForm.detailInfos[j].tradeNumber)) {
+									this.inputForm.detailInfos[j].priceSum = this.inputForm.detailInfos[j].tradePrice * this.inputForm.detailInfos[j].tradeNumber
+								}
+							}
+						}
+						this.$refs.uploadComponent.newUpload(method, this.inputForm.files, 'reimbursement')
+						this.inputForm = JSON.parse(JSON.stringify(this.inputForm))
+						this.loading = false
+					} else {
+						if (this.commonJS.isEmpty(this.inputForm.handledByOffice)) {
+							this.inputForm.handledByOffice = this.$store.state.user.office.id
+						}
+						if (this.commonJS.isEmpty(this.inputForm.handledBy)) {
+							this.inputForm.handledBy = this.$store.state.user.name
+						}
+						if (this.commonJS.isEmpty(this.inputForm.handledById)) {
+							this.inputForm.handledById = this.$store.state.user.id
+						}
+						if (this.commonJS.isEmpty(this.inputForm.purchaseDate)) {
+							this.inputForm.purchaseDate = this.moment(new Date()).format('YYYY-MM-DD')
+						}
+						this.inputForm.detailInfos = []
+						this.loading = false
+					}
+				})
+				if (method !== 'edit' && method !== 'view') {
+					this.$refs.uploadComponent.newUpload(method, [], 'psi')
+				}
+			})
+		},
+		getUpload(p, index) {
+			p.then((list) => {
+				// list为返回数据
+				this.inputForm.detailInfos[index].fileInfoLost = list
+				this.inputForm.detailInfos[index].fileNumber = list.length
+				this.tableKeyClient = Math.random()
+			})
+		},
+		seeFileInfo(index) {
+			if (this.commonJS.isEmpty(this.inputForm.detailInfos[index].fileInfoLost)) {
+				this.inputForm.detailInfos[index].fileInfoLost = []
+			}
+			this.$refs.materialManagementDialog.newUpload('view', this.inputForm.detailInfos[index].fileInfoLost, null, null, null, null, null, false, index)
+		},
+		sss(index) {
+			if (this.commonJS.isEmpty(this.inputForm.detailInfos[index].fileInfoLost)) {
+				this.inputForm.detailInfos[index].fileInfoLost = []
+			}
+			this.$refs.materialManagementDialog.newUpload(null, this.inputForm.detailInfos[index].fileInfoLost, null, null, null, null, null, false, index)
+		},
+		// 表单提交
+		doSubmit() {
+			this.$refs['inputForm'].validate((valid) => {
+				if (valid) {
+					this.loading = true
+					if (this.$refs.uploadComponent.checkProgress()) {
+						this.loading = false
+						return
+					}
+					if (this.commonJS.isEmpty(this.inputForm.files)) {
+						this.inputForm.files = []
+					}
+					this.inputForm.id = this.businessId
+					this.inputForm.files = this.$refs.uploadComponent.getDataList()
+					this.materialManagementService.save(this.inputForm).then((data) => {
+						this.close()
+						this.$message.success(data)
+						this.$emit('refreshDataList')
+						this.loading = false
+					}).catch(() => {
+						this.loading = false
+					})
+				}
+			})
+		},
+		close() {
+			this.$refs.inputForm.resetFields()
+			this.inputForm.detailInfos = []
+			// this.inputForm.amountInfos = []
+			this.$refs.uploadComponent.clearUpload()
+			this.visible = false
+		},
+		// 删除
+		removeEvent(row, rowIndex, type) {
+			if (type === 'detail') {
+				this.$refs.detailTable.remove(row)
+				this.inputForm.detailInfos.splice(rowIndex, 1)
+			}
+			if (type === 'amount') {
+				this.$refs.amountTable.remove(row)
+			}
+		},
+		// 新增
+		async insertEvent(type) {
+			if (type === 'detail') {
+				await this.$refs.detailTable.insert().then((data) => {
+					data.purchaserAgentId = this.purchaserAgentId
+					data.purchaserAgent = this.name
+					data.procurementOffice = this.officeName
+					this.inputForm.detailInfos.push(data)
+					console.log('this.inputForm.detailInfos', this.inputForm.detailInfos)
+					this.clientTableKey = Math.random()
+				})
+			}
+			if (type === 'amount') {
+				await this.$refs.amountTable.insert().then((data) => {
+					// this.inputForm.amountInfos.push(data)
+				})
+			}
+		},
+		reapplyForm(callback) {
+			this.loading = true
+			this.materialManagementService.findById(this.inputForm.id).then((data) => {
+				if (data.status !== '4') { // 审核状态不是“驳回”,就弹出提示
+					this.loading = false
+					this.$message.error('任务数据已发生改变或不存在,请在待办任务中确认此任务是否存在')
+					throw new Error('任务数据已发生改变或不存在,请在待办任务中确认此任务是否存在')
+				} else {
+					this.startFormTrue(callback)
+				}
+			})
+		},
+		// 暂存
+		async saveForm(callback) {
+			this.loading = true
+			if (this.$refs.uploadComponent.checkProgress()) {
+				this.loading = false
+				return
+			}
+			if (this.commonJS.isEmpty(this.inputForm.files)) {
+				this.inputForm.files = []
+			}
+			this.inputForm.files = this.$refs.uploadComponent.getDataList()
+			this.inputForm.status = '1'
+			this.materialManagementService.save(this.inputForm).then((data) => {
+				callback()
+				this.$refs.inputForm.resetFields()
+				this.loading = false
+			}).catch(() => {
+				this.$refs.inputForm.resetFields()
+				this.loading = false
+			})
+		},
+		startForm(callback) {
+			this.loading = true
+			if (this.commonJS.isNotEmpty(this.inputForm.id)) {
+				this.materialManagementService.findById(this.inputForm.id).then((data) => {
+					// 审核状态不是“未发起”或“暂存”或“撤回”,就弹出提示
+					if (this.commonJS.isNotEmpty(data.status) && data.status !== '0' && data.status !== '1' && data.status !== '3') {
+						this.loading = false
+						this.$message.error('任务数据已发生改变或不存在,请在待办任务中确认此任务是否存在')
+						throw new Error('任务数据已发生改变或不存在,请在待办任务中确认此任务是否存在')
+					} else {
+						this.startFormTrue(callback)
+					}
+				})
+			} else {
+				this.startFormTrue(callback)
+			}
+		},
+		// 送审
+		async startFormTrue(callback) {
+			this.loading = true
+			this.$refs['inputForm'].validate(async (valid) => {
+				if (valid) {
+					this.loading = true
+					if (this.$refs.uploadComponent.checkProgress()) {
+						this.loading = false
+						return
+					}
+					if (this.commonJS.isEmpty(this.inputForm.files)) {
+						this.inputForm.files = []
+					}
+					if (this.commonJS.isEmpty(this.inputForm.detailInfos)) {
+						this.$message.error('至少填写一条采购详情信息')
+						this.loading = false
+						return
+					} else {
+						let i = this.inputForm.detailInfos.length
+						for (let j = 0; j < i; j++) {
+							let k = j + 1
+							if (this.commonJS.isEmpty(this.inputForm.detailInfos[j].purchaserAgent)) {
+								this.$message.error('采购详情第' + k + '行请选择采购人')
+								this.loading = false
+								return
+							}
+							if (this.commonJS.isEmpty(this.inputForm.detailInfos[j].procurementType)) {
+								this.$message.error('采购详情第' + k + '行请选择采购类型')
+								this.loading = false
+								return
+							}
+							if (this.commonJS.isEmpty(this.inputForm.detailInfos[j].tradeName)) {
+								this.$message.error('采购详情第' + k + '行请填写商品名称')
+								this.loading = false
+								return
+							}
+						}
+						for (let j = 0; j < i; j++) {
+							for (let k = j + 1; k < i; k++) {
+								if (this.inputForm.detailInfos[j].procurementType === this.inputForm.detailInfos[k].procurementType) { // 如果采购类型相同
+									if (this.inputForm.detailInfos[j].tradeName === this.inputForm.detailInfos[k].tradeName) { // 如果商品名称相同
+										if (this.inputForm.detailInfos[j].supplierName === this.inputForm.detailInfos[k].supplierName) {
+											this.$message.warning(`采购详情中,同种采购类型、同一供应商的商品名称只能输入一条`)
+											this.loading = false
+											throw new Error('采购详情中,同种采购类型、同一供应商的商品名称只能输入一条')
+										}
+									}
+								}
+							}
+						}
+					}
+					this.inputForm.files = this.$refs.uploadComponent.getDataList()
+					this.inputForm.status = '2'
+					this.materialManagementService.save(this.inputForm).then((data) => {
+						this.inputForm.id = data.businessId
+						callback(data.businessTable, data.businessId, this.inputForm)
+						this.$refs.inputForm.resetFields()
+						this.loading = false
+					}).catch(() => {
+						this.$refs.inputForm.resetFields()
+						this.loading = false
+					})
+				} else {
+					this.loading = false
+				}
+			})
+		},
+		// 通过
+		async agreeForm(callback) {
+			this.loading = true
+			this.$refs['inputForm'].validate(async (valid) => {
+				if (valid) {
+					this.loading = true
+					if (this.$refs.uploadComponent.checkProgress()) {
+						this.loading = false
+						return
+					}
+					if (this.commonJS.isEmpty(this.inputForm.files)) {
+						this.inputForm.files = []
+					}
+					this.inputForm.files = this.$refs.uploadComponent.getDataList()
+					console.log('this.inputForm.procInsId', this.inputForm.procInsId)
+					this.commonApi.getTaskNameByProcInsId(this.inputForm.procInsId).then((data) => {
+						if (this.commonJS.isNotEmpty(data)) {
+							console.log('进来了', data)
+							if (data === '领导审批') {
+								this.inputForm.status = '5'
+							}
+						}
+						this.materialManagementService.save(this.inputForm).then((data) => {
+							callback(data.businessTable, data.businessId, this.inputForm)
+							this.loading = false
+						}).catch(() => {
+							this.loading = false
+						})
+					})
+				} else {
+					this.loading = false
+				}
+			})
+		},
+		async updateStatusById(type, callback) {
+			this.loading = true
+			if (await this.$refs.uploadComponent.checkProgress()) {
+				this.loading = false
+				throw new Error()
+			} else {
+				if (type === 'reject' || type === 'reback') {
+					this.materialManagementService.findById(this.inputForm.id).then((data) => {
+						if (data.status !== '2') { // status的值不等于“审核中”,就弹出提示
+							this.loading = false
+							this.$message.error('任务数据已发生改变或不存在,请在待办任务中确认此任务是否存在')
+							throw new Error()
+						} else {
+							if (type === 'reject') {
+								// 驳回
+								this.inputForm.status = '4'
+							}
+							if (type === 'reback') {
+								// 撤回
+								this.inputForm.status = '3'
+							}
+							if (type === 'reject' || type === 'reback') {
+								let param = { status: this.inputForm.status, id: this.inputForm.id }
+								this.materialManagementService.updateStatusById(param).then(() => {
+									this.loading = false
+									callback()
+								})
+							}
+						}
+					})
+				} else if (type === 'hold') {
+					this.materialManagementService.findById(this.inputForm.id).then((data) => {
+						if (data.status !== '4') { // status的值不等于“驳回”就弹出提示
+							this.loading = false
+							this.$message.error('任务数据已发生改变或不存在,请在待办任务中确认此任务是否存在')
+							throw new Error()
+						} else {
+							// 终止
+							let param = { status: '1', id: this.inputForm.id }
+							this.materialManagementService.updateStatusById(param).then(() => {
+								this.loading = false
+								callback()
+							})
+						}
+					})
+				}
+			}
+		},
+		// 修改状态
+		// updateStatusById (type) {
+		//   if (type === 'reject') {
+		//     this.inputForm.status = '4'
+		//     // this.reimbursementApprovalService.updateStatusById(this.inputForm)
+		//     this.materialManagementService.updateStatusById(this.inputForm)
+		//   }
+		// },
+		footerMethod({ columns, data }) {
+			const footerData = [
+				columns.map((column, columnIndex) => {
+					if (columnIndex === 0) {
+						return '商品总价'
+					}
+					if (['priceSum'].includes(column.property)) {
+						// eslint-disable-next-line no-undef
+						this.inputForm.tradeTotalPrice = XEUtils.sum(data, column.property)
+						return XEUtils.sum(data, column.property)
+					}
+					return null
+				})
+			]
+			return footerData
+		},
+		twoDecimalPlaces(num, index) {
+			let str = num.toString()
+			var len1 = str.substr(0, 1)
+			var len2 = str.substr(1, 1)
+			// eslint-disable-next-line eqeqeq
+			if (str.length > 1 && len1 == 0 && len2 != '.') {
+				str = str.substr(1, 1)
+			}
+			// eslint-disable-next-line eqeqeq
+			if (len1 == '.') {
+				str = ''
+			}
+			// eslint-disable-next-line eqeqeq
+			if (str.indexOf('.') != -1) {
+				var str_ = str.substr(str.indexOf('.') + 1)
+				// eslint-disable-next-line eqeqeq
+				if (str_.indexOf('.') != -1) {
+					str = str.substr(0, str.indexOf('.') + str_.indexOf('.') + 1)
+				}
+				if (str_.length > 2) {
+					this.$message.warning(`金额小数点后只能输入两位,请正确输入!`)
+					return (str = '')
+				}
+			}
+			// eslint-disable-next-line no-useless-escape
+			this.inputForm.detailInfos[index].priceSum = str.replace(/[^\d^\.]+/g, '') // 保留数字和小数点
+		},
+		twoDecimalPlaces2(num) {
+			let str = num.toString()
+			var len1 = str.substr(0, 1)
+			var len2 = str.substr(1, 1)
+			// eslint-disable-next-line eqeqeq
+			if (str.length > 1 && len1 == 0 && len2 != '.') {
+				str = str.substr(1, 1)
+			}
+			// eslint-disable-next-line eqeqeq
+			if (len1 == '.') {
+				str = ''
+			}
+			// eslint-disable-next-line eqeqeq
+			if (str.indexOf('.') != -1) {
+				var str_ = str.substr(str.indexOf('.') + 1)
+				// eslint-disable-next-line eqeqeq
+				if (str_.indexOf('.') != -1) {
+					str = str.substr(0, str.indexOf('.') + str_.indexOf('.') + 1)
+				}
+				if (str_.length > 2) {
+					this.$message.warning(`商品数量小数点后只能输入两位,请正确输入!`)
+					return (str = '')
+				}
+			}
+			// eslint-disable-next-line no-useless-escape
+			str = str.replace(/[^\d^\.]+/g, '') // 保留数字和小数点
+			return str
+		},
+		countAmount(row) {
+			let amount
+			let taxAmount
+			let count = 0
+			if (!this.commonJS.isEmpty(row.amount)) {
+				amount = parseFloat(row.amount)
+				count = count + amount
+			}
+			if (!this.commonJS.isEmpty(row.taxAmount)) {
+				taxAmount = parseFloat(row.taxAmount)
+				count = count + taxAmount
+			}
+			row.count = parseFloat(count).toFixed(2)
+		},
+		getProgram(rows) {
+			this.inputForm.detailInfos[this.indexRow].projectId = rows[0].id
+			this.inputForm.detailInfos[this.indexRow].projectName = rows[0].name
+			this.inputForm.detailInfos[this.indexRow].reportNumber = rows[0].reportNo
+			this.indexRow = ''
+			this.$forceUpdate()
+		},
+		// 采购类型下拉弹窗
+		typePullForm(rowIndex) {
+			this.indexRow = rowIndex
+			// this.$refs.reimbursementTypePullForm.init()
+			// this.$refs.cwReimbursementTypePullForm.init()
+			this.$refs.materialTypePullForm.init()
+		},
+		getProgramForType(rows) {
+			this.inputForm.detailInfos[this.indexRow].procurementTypeId = rows.id
+			this.inputForm.detailInfos[this.indexRow].procurementType = rows.name
+			this.indexRow = ''
+			this.$forceUpdate()
+		},
+		// 采购人下拉弹窗
+		userPullListForm(rowIndex) {
+			this.indexRow = rowIndex
+			this.$refs.userPullForm.init()
+		},
+		getProgramForUser(rows) {
+			console.log('rows', rows)
+			this.inputForm.detailInfos[this.indexRow].purchaserAgentId = rows[0].id
+			this.inputForm.detailInfos[this.indexRow].purchaserAgent = rows[0].name
+			this.inputForm.detailInfos[this.indexRow].deptId = rows[0].parentId
+			this.inputForm.detailInfos[this.indexRow].procurementOffice = rows[0].officeName
+			this.indexRow = ''
+			this.$forceUpdate()
+		},
+		getUserInfo(rows) {
+			console.log('rows', rows)
+		},
+		// 值改变事件
+		changeValue() {
+			let i = this.inputForm.detailInfos.length
+			for (let j = 0; j < i; j++) {
+				if (this.commonJS.isNotEmpty(this.inputForm.detailInfos[j].tradePrice)) {
+					if (this.commonJS.isNotEmpty(this.inputForm.detailInfos[j].tradeNumber)) {
+						// parseFloat(item.account).toFixed(2)
+						this.inputForm.detailInfos[j].priceSum = parseFloat(parseFloat(this.inputForm.detailInfos[j].tradePrice) * parseFloat(this.inputForm.detailInfos[j].tradeNumber)).toFixed(2)
+					}
+				}
+			}
+		},
+		ifSameValue() {
+			let i = this.inputForm.detailInfos.length
+			for (let j = 0; j < i; j++) {
+				for (let k = j + 1; k < i; k++) {
+					if (this.inputForm.detailInfos[j].procurementTypeId === this.inputForm.detailInfos[k].procurementTypeId) {
+						if (this.commonJS.isNotEmpty(this.inputForm.detailInfos[j].tradeName) &&
+							this.commonJS.isNotEmpty(this.inputForm.detailInfos[k].tradeName) && this.inputForm.detailInfos[j].tradeName === this.inputForm.detailInfos[k].tradeName) {
+							// parseFloat(item.account).toFixed(2)
+							this.inputForm.detailInfos.splice(k, 1)
+							this.$message.warning(`同种采购类型的商品名称只能输入一条信息!`)
+						}
+					}
+				}
+			}
+		},
+		focusEvent4(rowIndex) {
+			this.$refs.xDown4.showPanel()
+			this.loading4 = true
+			this.suppName = '' // 搜索框的值 清空
+			this.suppIndex = rowIndex // 获取当前行下标
+			this.tablePage4.currentPage = 1
+			this.tablePage4.pageSize = 10
+			this.refreshSupplierList()
+		},
+		suffixClick4() {
+			this.$refs.xDown4.togglePanel()
+		},
+		searchClick() {
+			this.refreshSupplierList()
+		},
+		cellClickEvent4({ row }) {
+			this.inputForm.detailInfos[this.suppIndex].supplierName = row.name
+			this.inputForm.detailInfos[this.suppIndex].supplierId = row.id
+			this.inputForm.detailInfos[this.suppIndex].isSupplier = '2' // isSupplier:手动填写 ‘1’ 选择填写 ‘2’
+			this.suppIndex = ''
+			this.$refs.xDown4.hidePanel()
+		},
+		pageChangeEvent4({ currentPage, pageSize }) {
+			this.tablePage4.currentPage = currentPage
+			this.tablePage4.pageSize = pageSize
+			this.refreshSupplierList()
+		},
+		// 刷新供应商
+		refreshSupplierList() {
+			this.supplierService.list({
+				'current': this.tablePage4.currentPage,
+				'size': this.tablePage4.pageSize,
+				'name': this.suppName
+			}).then((data) => {
+				this.tableData4 = data.records
+				this.tablePage4.total = data.total
+				this.loading4 = false
+			})
+		},
+		focusEvent1(row) {
+			row.tradeNameList = []
+			row.tradeNameData = []
+			if (this.commonJS.isNotEmpty(row.procurementTypeId)) {
+				this.materialManagementService.findTradeByTypeId(row.procurementTypeId).then((data) => {
+					row.tradeNameList = JSON.parse(JSON.stringify(data))
+					row.tradeNameData = JSON.parse(JSON.stringify(data))
+					this.$refs.xDown1.showPanel()
+				}).catch(() => {
+					this.$refs.xDown1.showPanel()
+				})
+			} else {
+				this.$refs.xDown1.showPanel()
+			}
+		},
+		keyupEvent1(row) {
+			row.tradeNameData = this.commonJS.isNotEmpty(row.tradeName) ? row.tradeNameList.filter(item => item.tradeName.indexOf(row.tradeName) > -1) : row.tradeNameList
+		},
+		selectEvent1(row, item) {
+			row.tradeName = item.tradeName
+			this.$refs.xDown1.hidePanel()
+		}
+	}
+}
+</script>
+<style scoped>
+.el-divider__text {
+	font-size: 16px;
+	font-weight: bold;
+}
+
+/*.my-dropdown1、.list-item1、.list-item1:hover  为商品名称下拉选择框样式*/
+.my-dropdown1 {
+	height: 155px;
+	overflow: auto;
+	border-radius: 4px;
+	border: 1px solid #dcdfe6;
+	background-color: #fff;
+}
+
+.list-item1 {
+	line-height: 30px;
+	text-align: center;
+	border-bottom: #c4c7cc73 1px solid;
+}
+
+.list-item1:hover {
+	background-color: #f5f7fa;
+}
+</style>

+ 507 - 0
src/views/psiManagement/purchase/PurchaseList.vue

@@ -0,0 +1,507 @@
+<template>
+	<div class="page">
+		<el-form :inline="true" v-if="searchVisible" class="query-form m-b-10" ref="searchForm" :model="searchForm"
+			@keyup.enter.native="refreshList()" @submit.native.prevent>
+			<!-- 搜索框-->
+			<el-form-item label="采购名称" prop="purchaseSketch">
+				<el-input v-model="searchForm.purchaseSketch" placeholder="请输入采购名称" clearable></el-input>
+			</el-form-item>
+			<el-form-item label="经办人" prop="handledBy">
+				<UserSelect :limit='1' :modelValue="searchForm.handledBy"
+					@update:modelValue='(value, label) => { searchForm.handledBy = value }'></UserSelect>
+			</el-form-item>
+			<el-form-item v-if="showHideItem" prop="handledByOffice" label="经办人部门">
+				<SelectTree ref="officeTree" :props="{
+					value: 'id',             // ID字段名
+					label: 'name',         // 显示名称
+					children: 'children'    // 子级字段名
+				}" :url="`/system-server/sys/office/treeData?type=1`" :value="searchForm.handledByOffice" size="default"
+					:accordion="true" @getValue="(value) => { searchForm.handledByOffice = value }" />
+			</el-form-item>
+			<el-form-item v-if="showHideItem" label="状态" prop="status">
+				<el-select v-model="searchForm.status" placeholder="请选择" style="width:100%;" clearable>
+					<el-option v-for="item in $dictUtils.getDictList('cw_status')" :key="item.value" :label="item.label"
+						:value="item.value">
+					</el-option>
+				</el-select>
+			</el-form-item>
+			<el-form-item v-if="showHideItem" label="采购金额(元)" prop="contractAmounts">
+				<InputNumber :disabled="false" :precision="num" :value="searchForm.contractAmounts"
+					@changefrom="(val) => { searchForm.contractAmounts[0] = val }"
+					@changeto="(val) => { searchForm.contractAmounts[1] = val }"></InputNumber>
+			</el-form-item>
+			<el-form-item v-if="showHideItem" label="申请时间" prop="contractDates">
+				<el-date-picker placement="bottom-start" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
+					v-model="searchForm.contractDates" type="datetimerange" range-separator="至" start-placeholder="开始日期"
+					end-placeholder="结束日期">
+				</el-date-picker>
+			</el-form-item>
+
+			<el-form-item v-if="showHideItem" label="供应商" prop="supplierName">
+				<el-input v-model="searchForm.supplierName" :readonly="true" placeholder="请选择供应商"
+					@focus="openSupplierChoose"></el-input>
+			</el-form-item>
+
+			<el-form-item>
+				<el-button type="default" @click="showHide" :icon="showHideIcon">{{ showHideName }}</el-button>
+				<el-button type="primary" @click="refreshList()" icon="el-icon-search">查询</el-button>
+				<el-button @click="resetSearch()" icon="el-icon-refresh-right">重置</el-button>
+			</el-form-item>
+		</el-form>
+		<div class="jp-table top" style="">
+			<vxe-toolbar :refresh="{ query: refreshList }" custom>
+				<template #buttons>
+					<el-button v-if="hasPermission('psi:add')" type="primary" icon="el-icon-plus"
+						@click="start()">新建</el-button>
+					<el-button v-if="hasPermission('psi:list')" type="warning" icon="el-icon-download" plain
+						@click="exportFile()">导出</el-button>
+				</template>
+				<template #tools>
+					<vxe-button text type="primary" :title="searchVisible ? '收起检索' : '展开检索'" icon="vxe-icon-search"
+						class="tool-btn" @click="searchVisible = !searchVisible"></vxe-button>
+				</template>
+			</vxe-toolbar>
+			<div style="height: calc(100% - 90px)">
+				<vxe-table :key="tableKey" border="inner" auto-resize resizable height="auto" :loading="loading"
+					ref="clientTable" show-header-overflow show-overflow highlight-hover-row :menu-config="{}"
+					@sort-change="sortChangeHandle" :sort-config="{ remote: true }" :data="dataList"
+					:checkbox-config="{}">
+					<vxe-column type="seq" width="60" title="序号"></vxe-column>
+					<vxe-column min-width="160" align="center" title="采购申请编号" field="purchaseNo"></vxe-column>
+					<vxe-column min-width="160" align="center" title="采购名称" field="purchaseSketch">
+						<template #default="scope">
+							<el-link type="primary" :underline="false" v-if="hasPermission('psi:list')"
+								@click="view(scope.row.id)">{{ scope.row.purchaseSketch }}</el-link>
+							<el-link type="primary" :underline="false" v-else-if="hasPermission('psi:list')"
+								@click="view(scope.row.id,)">{{ scope.row.purchaseSketch }}</el-link>
+							<span v-else>{{ scope.row.purchaseSketch }}</span>
+						</template>
+					</vxe-column>
+					<vxe-column min-width="160" align="center" title="采购方式" field="purchaseMode"></vxe-column>
+					<vxe-column min-width="160" align="center" title="采购金额(元)" field="tradeTotalPrice"></vxe-column>
+					<vxe-column min-width="160" align="center" title="经办人" field="handledByName"></vxe-column>
+					<vxe-column min-width="160" align="center" title="经办人部门" field="handledByOfficeName"></vxe-column>
+					<vxe-column min-width="160" align="center" title="申请时间" field="createDate"></vxe-column>
+					<vxe-column min-width="150px" align="center" fixed="right" title="状态" field="status">
+						<template #default="scope">
+							<el-button @click="detail(scope.row)" effect="dark"
+								:type="$dictUtils.getDictLabel('cw_status_flag', scope.row.status, '-')">
+								{{ $dictUtils.getDictLabel("cw_status", scope.row.status, '-') }}
+							</el-button>
+						</template>
+					</vxe-column>
+
+					<vxe-column title="操作" width="150px" fixed="right" align="center">
+						<template #default="scope">
+							<el-button
+								v-if="hasPermission('psi:edit') && scope.row.createBy === $store.state.user.id && (scope.row.status === '1' || scope.row.status === '3')"
+								text type="primary" size="small" @click="push(scope.row)">修改</el-button>
+							<el-button
+								v-else-if="hasPermission('psi:edit') && isAdmin && (scope.row.status === '1' || scope.row.status === '3' || scope.row.status === '4' || scope.row.status === '5')"
+								text type="primary" size="small" @click="edit(scope.row.id)">修改</el-button>
+							<el-button
+								v-if="hasPermission('psi:edit') && scope.row.createBy === $store.state.user.id && scope.row.status === '2'"
+								text type="primary" size="small" @click="reback(scope.row)">撤回</el-button>
+							<el-button v-if="scope.row.status === '2' && checkIsAudit(scope.row)" text type="primary"
+								size="small" @click="examine(scope.row)">审核</el-button>
+							<el-button
+								v-if="hasPermission('psi:edit') && scope.row.status === '4' && scope.row.createBy === $store.state.user.id"
+								text type="primary" @click="adjust(scope.row)">驳回调整</el-button>
+							<el-button
+								v-if="hasPermission('psi:del') && scope.row.createBy === $store.state.user.id && (scope.row.status === '1' || scope.row.status === '3')"
+								size="small" text type="primary" @click="del(scope.row.id)">删除</el-button>
+							<el-button
+								v-else-if="hasPermission('psi:del') && isAdmin && (scope.row.status === '1' || scope.row.status === '3' || scope.row.status === '4' || scope.row.status === '5')"
+								size="small" text type="primary" @click="del(scope.row.id)">删除</el-button>
+							<el-button
+								v-if="hasPermission('psi:wareHouseRecord:list') && scope.row.status === '5' && scope.row.purchaseModeType === '1'"
+								text type="primary" size="small" @click="seeWareHouse(scope.row.id)">入库记录</el-button>
+							<el-button
+								v-if="hasPermission('psi:wareHouse:add') && scope.row.status === '5' && scope.row.purchaseModeType === '1'"
+								text type="primary" size="small" @click="wareHouse(scope.row.id)">入库</el-button>
+						</template>
+					</vxe-column>
+				</vxe-table>
+				<vxe-pager background :current-page="tablePage.currentPage" :page-size="tablePage.pageSize"
+					:total="tablePage.total" :page-sizes="[10, 20, 100, 1000, { label: '全量数据', value: 1000000 }]"
+					:layouts="['PrevPage', 'JumpNumber', 'NextPage', 'FullJump', 'Sizes', 'Total']"
+					@page-change="currentChangeHandle">
+				</vxe-pager>
+				<UpdateInfoForm ref="updateInfoForm" @refreshList="refreshList"></UpdateInfoForm>
+				<SeeWareHouseList ref="seeWareHouseList"></SeeWareHouseList>
+				<WareHouseAddForm ref="wareHouseAddForm"></WareHouseAddForm>
+				<SupplierChooseForm ref="supplierChooseForm" @getSupplier="getSupplier"></SupplierChooseForm>
+
+			</div>
+		</div>
+	</div>
+</template>
+
+<script>
+import WareHouseAddForm from '../wareHouse/WareHouseAddForm'
+import SeeWareHouseList from './SeeWareHouseList'
+import UserSelect from '@/components/userSelect'
+import UpdateInfoForm from '../info/UpdateInfoForm'
+import InputNumber from '@/views/cw/workContract/InputNumber.vue'
+import SelectTree from '@/components/treeSelect/treeSelect.vue'
+import MaterialManagementService from '@/api/psi/MaterialManagementService'
+import taskService from '@/api/flowable/taskService'
+import processService from '@/api/flowable/processService'
+import pick from 'lodash.pick'
+import userService from '@/api/sys/userService'
+import SupplierChooseForm from '@/views/psiManagement/supplier/SupplierChooseForm'
+export default {
+	data() {
+		return {
+			searchVisible: true,
+			showHideItem: false,
+			showHideIcon: 'el-icon-arrow-down',
+			showHideName: '展示',
+			num: 0,
+			searchForm: {
+				contractAmounts: [],
+				purchaseSketch: '',
+				handledBy: '',
+				handledByOffice: '',
+				status: '',
+				contractDates: [],
+				procurementType: '',
+				createBy: '',
+				supplierId: '',
+				supplierName: ''
+			},
+			dataList: [],
+			tablePage: {
+				total: 0,
+				currentPage: 1,
+				pageSize: 10,
+				orders: []
+			},
+			tableKey: '',
+			loading: false,
+			processDefinitionAuditId: '',
+			procDefAuditKey: '',
+			isAdmin: false,
+			createName: '',
+			create: ''
+		}
+	},
+	materialManagementService: null,
+	created() {
+		this.materialManagementService = new MaterialManagementService()
+	},
+	components: {
+		InputNumber,
+		SelectTree,
+		UpdateInfoForm,
+		SeeWareHouseList,
+		WareHouseAddForm,
+		UserSelect,
+		SupplierChooseForm
+	},
+	computed: {
+		userName() {
+			return this.$store.state.user.name
+		},
+		user() {
+			this.createName = this.$store.state.user.name
+			return this.$store.state.user
+		}
+	},
+	mounted() {
+		this.refreshList()
+	},
+	activated() {
+		this.refreshList()
+	},
+	methods: {
+		showHide() {
+			if (this.showHideItem === false) {
+				this.showHideItem = true
+				this.showHideIcon = 'el-icon-arrow-up'
+				this.showHideName = '隐藏'
+			} else {
+				this.showHideItem = false
+				this.showHideIcon = 'el-icon-arrow-down'
+				this.showHideName = '展示'
+			}
+		},
+		// 入库
+		wareHouse(id) {
+			// this.$refs.reportManagementForm.init('add', '')
+			this.$refs.wareHouseAddForm.init('purchaseAdd', id)
+		},
+		seeWareHouse(id) {
+			this.$refs.seeWareHouseList.init(id)
+		},
+		// 新增
+		add() {
+			// this.$refs.reportManagementForm.init('add', '')
+		},
+		// 修改
+		edit(id) {
+			id = id || this.$refs.clientTable.getCheckboxRecords().map(item => {
+				return item.id
+			})[0]
+			this.$refs.updateInfoForm.init('edit', id)
+		},
+		// 查看
+		view(id) {
+			this.$refs.updateInfoForm.init('view', id)
+		},
+		// 查询当前用户是否是管理员用户
+		checkIsAdmin() {
+			userService.is().then((data) => {
+				this.isAdmin = data
+			})
+		},
+		// 获取数据列表
+		refreshList() {
+			this.loading = true
+			this.materialManagementService.list({
+				'current': this.tablePage.currentPage,
+				'size': this.tablePage.pageSize,
+				'orders': this.tablePage.orders,
+				...this.searchForm
+			}).then((data) => {
+				this.dataList = data.records
+				this.tablePage.total = data.total
+				this.tableKey = Math.random()
+				this.loading = false
+			})
+			this.checkIsAdmin()
+			processService.getByName('进销存-采购申请').then((data) => {
+				if (!this.commonJS.isEmpty(data.id)) {
+					this.processDefinitionAuditId = data.id
+					this.procDefAuditKey = data.key
+				}
+			})
+		},
+		// 当前页
+		currentChangeHandle({ currentPage, pageSize }) {
+			this.tablePage.currentPage = currentPage
+			this.tablePage.pageSize = pageSize
+			this.refreshList()
+		},
+		// 排序
+		sortChangeHandle(column) {
+			this.tablePage.orders = []
+			if (column.order != null) {
+				this.tablePage.orders.push({ column: this.$utils.toLine(column.property), asc: column.order === 'asc' })
+			}
+			this.refreshList()
+		},
+		// 删除
+		del(id) {
+			let ids = id || this.$refs.clientTable.getCheckboxRecords().map(item => {
+				return item.id
+			}).join(',')
+			this.$confirm(`确定删除所选项吗?`, '提示', {
+				confirmButtonText: '确定',
+				cancelButtonText: '取消',
+				type: 'warning'
+			}).then(() => {
+				this.loading = true
+				this.materialManagementService.remove(ids).then((data) => {
+					this.$message.success(data)
+					this.refreshList()
+					this.loading = false
+				})
+			})
+		},
+		resetSearch() {
+			this.$refs.searchForm.resetFields()
+			this.searchForm.supplierId = '' // 重置时清空供应商筛选
+			this.refreshList()
+		},
+		start() {
+			// 读取流程表单
+			let tabTitle = `发起流程【采购申请】`
+			let processTitle = `${this.userName} 在 ${this.moment(new Date()).format('YYYY-MM-DD HH:mm')} 发起了 [采购申请]`
+			taskService.getTaskDef({
+				procDefId: this.processDefinitionAuditId,
+				status: 'startAndHold'
+			}).then((data) => {
+				this.$router.push({
+					path: '/flowable/task/TaskForm',
+					query: {
+						...pick(data, 'formType', 'formUrl', 'procDefKey', 'taskDefKey', 'procInsId', 'procDefId', 'taskId', 'status', 'title'),
+						procDefId: this.processDefinitionAuditId,
+						procDefKey: this.procDefAuditKey,
+						status: 'startAndHold',
+						title: tabTitle,
+						formType: data.formType,
+						formUrl: data.formUrl,
+						formTitle: processTitle,
+						businessId: 'false',
+						isShow: false,
+						routePath: '/psiManagement/purchase/PurchaseList'
+					}
+				})
+			})
+		},
+		// 发起采购申请
+		push(row) {
+			// 读取流程表单
+			let title = `发起流程【采购申请】`
+			let processTitle = `${this.userName} 在 ${this.moment(new Date()).format('YYYY-MM-DD HH:mm')} 发起了[采购申请]`
+			let status = 'startAndHold'
+			if (row.status === '3') {
+				status = 'startAndClose'
+			} else if (row.status === '4') {
+				status = 'reapplyFlag'
+			}
+			taskService.getTaskDef({
+				procDefId: this.processDefinitionAuditId,
+				businessId: row.id,
+				businessTable: 'psi_management_pruchase_request_basics'
+			}).then((data) => {
+				this.$router.push({
+					path: '/flowable/task/TaskForm',
+					query: {
+						...pick(data, 'formType', 'formUrl', 'procDefKey', 'taskDefKey', 'procInsId', 'procDefId', 'taskId', 'status', 'title'),
+						procDefId: this.processDefinitionAuditId,
+						procDefKey: this.procDefAuditKey,
+						title: title,
+						formType: data.formType,
+						formUrl: data.formUrl,
+						formTitle: processTitle,
+						businessTable: 'psi_management_pruchase_request_basics',
+						businessId: row.id,
+						isShow: 'false',
+						status: status,
+						routePath: '/psiManagement/purchase/PurchaseList'
+					}
+				})
+			})
+		},
+		// 查看客户登记流程结果
+		detail(row) {
+			if (row.status !== '0' && row.status !== '1') {
+				// eslint-disable-next-line eqeqeq
+				taskService.getTaskDef({
+					procInsId: row.procInsId,
+					procDefId: this.processDefinitionAuditId
+				}).then((data) => {
+					this.$router.push({
+						path: '/flowable/task/TaskFormDetail',
+						query: {
+							...pick(data, 'formType', 'formUrl', 'procDefKey', 'taskDefKey', 'procInsId', 'procDefId', 'taskId', 'status', 'title'),
+							isShow: 'false',
+							readOnly: true,
+							title: '质控管理' + '流程详情',
+							formTitle: '质控管理' + '流程详情',
+							businessId: row.id,
+							status: 'reback'
+						}
+					})
+				})
+			}
+		},
+		// 撤回报告流程
+		reback(row) {
+			this.$confirm(`确定要撤回该申请吗?`, '提示', {
+				confirmButtonText: '确定',
+				cancelButtonText: '取消',
+				type: 'warning'
+			}).then(async () => {
+				await this.materialManagementService.findById(row.id).then((data) => {
+					if (data.status !== '2') { // status的值不等于“审核中”,就弹出提示
+						this.$message.error('数据已发生改变或不存在,请刷新数据')
+						this.refreshList()
+					} else {
+						processService.revokeProcIns(row.procInsId).then((data) => {
+							let form = { status: '3', id: row.id }
+							this.materialManagementService.updateStatusById(form)
+							this.$message.success(data)
+							this.refreshList()
+						})
+					}
+				})
+			})
+		},
+		// 驳回后调整
+		adjust(row) {
+			this.materialManagementService.findById(row.id).then((data) => {
+				if (data.status !== '4') { // status的值不等于“驳回”,就弹出提示
+					this.$message.error('数据已发生改变或不存在,请刷新数据')
+					this.refreshList()
+				} else {
+					this.todo(row)
+				}
+			})
+		},
+		// 审核
+		examine(row) {
+			this.materialManagementService.findById(row.id).then((data) => {
+				if (data.status !== '2') { // status的值不等于“审核中”,就弹出提示
+					this.$message.error('数据已发生改变或不存在,请刷新数据')
+					this.refreshList()
+				} else {
+					this.todo(row)
+				}
+			})
+		},
+		// 审核或重新调整跳转
+		todo(row) {
+			let cUser = false
+			taskService.getTaskDefInfo({
+				taskId: row.taskId
+			}).then((data) => {
+				this.$router.push({
+					path: '/flowable/task/TaskForm',
+					query: {
+						...pick(data, 'formType', 'formUrl', 'procDefKey', 'taskDefKey', 'procInsId', 'procDefId', 'taskId', 'status', 'title', 'businessId'),
+						isShow: false,
+						formReadOnly: true,
+						formTitle: `${data.taskName}`,
+						cUser: cUser,
+						title: `审批【${data.taskName || ''}】`,
+						routePath: '/psiManagement/purchase/PurchaseList'   // 数据处理后需要跳转的页面路径
+					}
+				})
+			})
+		},
+		// 查询当前登录人是否是数据的审核人
+		checkIsAudit(row) {
+			let loginUserId = this.$store.state.user.id  // 获取当前登录用户id
+			if (this.commonJS.isNotEmpty(row.auditUserIds)) {
+				for (const userId of row.auditUserIds) {
+					if (userId === loginUserId) {  // 当数据的审核人中包含当前登录人id时,返回true
+						return true
+					}
+				}
+			}
+			return false
+		},
+		exportFile() {
+			const options = {
+				filename: `${this.moment(new Date()).format('YYYY-MM-DD')}采购申请数据导出`,
+				sheetName: '采购申请数据导出',
+				mode: 'all'
+			}
+			this.loading = true
+			this.materialManagementService.exportFile({
+				current: this.tablePage.currentPage,
+				size: this.tablePage.pageSize,
+				orders: this.tablePage.orders,
+				...options,
+				...this.searchForm
+			}).then((res) => {
+				this.$utils.downloadExcel(res, options.filename)
+				this.loading = false
+			}).catch(() => {
+				this.loading = false
+			})
+		},
+		getSupplier(row) {
+			this.searchForm.supplierId = row.id
+			this.searchForm.supplierName = row.name
+		},
+		// 打开供应商选择组件
+		openSupplierChoose() {
+			this.$refs.supplierChooseForm.init()
+		}
+	}
+}
+</script>

+ 127 - 0
src/views/psiManagement/purchase/SeeWareHouseList.vue

@@ -0,0 +1,127 @@
+<template>
+	<div>
+		<el-dialog title="入库记录" :close-on-click-modal="false" draggable width="1100px" height="500px" @close="close"
+			append-to-body v-model="visible">
+			<div style="height: calc(100% - 80px);">
+
+				<vxe-table border="inner" auto-resize resizable height="400px" :loading="loading" ref="projectTable"
+					show-header-overflow show-overflow highlight-hover-row :menu-config="{}" :print-config="{}"
+					:sort-config="{ remote: true }" :data="dataList" :row-config="{ isCurrent: true }"
+					:radio-config="{ trigger: 'row' }">
+					<vxe-column type="seq" width="60" title="序号"></vxe-column>
+					<vxe-column min-width="160" align="center" title="入库编号" field="wareHouseNumber"></vxe-column>
+					<vxe-column min-width="160" align="center" title="入库名称" field="wareHouseName">
+						<template #default="scope">
+							<el-link type="primary" :underline="false" v-if="hasPermission('psi:list')"
+								@click="view(scope.row.id)">{{ scope.row.wareHouseName }}</el-link>
+							<el-link type="primary" :underline="false" v-else-if="hasPermission('psi:list')"
+								@click="view(scope.row.id,)">{{ scope.row.wareHouseName }}</el-link>
+							<span v-else>{{ scope.row.wareHouseName }}</span>
+						</template>
+					</vxe-column>
+					<vxe-column min-width="160" align="center" title="入库时间" field="wareHouseDate"></vxe-column>
+					<vxe-column min-width="160" align="center" title="经办人" field="handleByName"></vxe-column>
+					<vxe-column min-width="160" align="center" title="经办人部门" field="handledByOfficeName"></vxe-column>
+
+				</vxe-table>
+				<vxe-pager background :current-page="tablePage.currentPage" :page-size="tablePage.pageSize"
+					:total="tablePage.total" :page-sizes="[10, 20, 100, 1000, { label: '全量数据', value: 1000000 }]"
+					:layouts="['PrevPage', 'JumpNumber', 'NextPage', 'FullJump', 'Sizes', 'Total']"
+					@page-change="currentChangeHandle">
+				</vxe-pager>
+			</div>
+			<template #footer>
+				<span class="dialog-footer">
+					<el-button @click="close()" icon="el-icon-circle-close">关闭</el-button>
+				</span>
+			</template>
+		</el-dialog>
+		<WareHouseAddForm ref="wareHouseAddForm"></WareHouseAddForm>
+	</div>
+</template>
+
+<script>
+import WareHouseAddForm from '../wareHouse/WareHouseAddForm'
+import WareHouseService from '@/api/psi/WareHouseService'
+export default {
+	data() {
+		return {
+			title: '',
+			method: '',
+			visible: false,
+			loading: false,
+			tablePage: {
+				total: 0,
+				currentPage: 1,
+				pageSize: 10,
+				orders: []
+			},
+			tableKey: '',
+			dataList: [],
+			searchForm: {
+				purchaseSketch: '',
+				purchaseId: '',
+				contractDates: [],
+				// 查入库记录所需的状态数组
+				statusTwo: []
+			}
+		}
+	},
+	wareHouseService: null,
+	created() {
+		this.wareHouseService = new WareHouseService()
+	},
+	components: {
+		WareHouseAddForm,
+	},
+	methods: {
+		// 查看
+		view(id) {
+			// this.$refs.updateInfoForm.init('view', id)
+			this.$refs.wareHouseAddForm.init('view', id)
+		},
+		init(id) {
+			this.visible = true
+			this.searchForm.purchaseId = id
+			this.list()
+		},
+		list() {
+			this.loading = true
+			// eslint-disable-next-line no-unused-vars
+			let status = ['0', '5']
+			this.searchForm.statusTwo = status
+			// this.searchForm.createId = this.$store.state.user.id
+			this.wareHouseService.wareHouseList({
+				'current': this.tablePage.currentPage,
+				'size': this.tablePage.pageSize,
+				'orders': this.tablePage.orders,
+				...this.searchForm
+			}).then((data) => {
+				this.dataList = data.records
+				this.tablePage.total = data.total
+				this.tableKey = Math.random()
+				this.loading = false
+			})
+		},
+		// 当前页
+		currentChangeHandle({ currentPage, pageSize }) {
+			this.tablePage.currentPage = currentPage
+			this.tablePage.pageSize = pageSize
+			this.list()
+		},
+		resetSearch() {
+			this.$refs.searchForm.resetFields()
+			this.list()
+		},
+		close() {
+			this.visible = false
+		}
+	}
+}
+</script>
+<style scoped>
+/deep/ .el-dialog__body {
+	padding-top: 0px;
+	padding-bottom: 15px;
+}
+</style>

+ 132 - 0
src/views/psiManagement/supplier/SupplierChooseForm.vue

@@ -0,0 +1,132 @@
+<template>
+	<div>
+		<el-dialog title="选择供应商" :close-on-click-modal="false" draggable width="1200px" height="500px" @close="close"
+			append-to-body v-model="visible">
+			<div style="height: calc(100% - 80px);">
+				<el-form :inline="true" class="query-form" ref="searchForm" :model="searchForm" @submit.native.prevent>
+					<!-- 搜索框-->
+					<el-form-item label="供应商名称" prop="name">
+						<el-input v-model="searchForm.name" placeholder="请输入供应商名称" clearable></el-input>
+					</el-form-item>
+					<el-form-item label="联系电话" prop="telPhone">
+						<el-input v-model="searchForm.telPhone" placeholder="请输入联系电话" clearable></el-input>
+					</el-form-item>
+					<el-form-item label="联系人名称" prop="linkName">
+						<el-input v-model="searchForm.linkName" placeholder="请输入联系人名称" clearable></el-input>
+					</el-form-item>
+
+					<el-form-item>
+						<el-button type="primary" @click="list()" icon="el-icon-search">查询</el-button>
+						<el-button @click="resetSearch()" icon="el-icon-refresh-right">重置</el-button>
+					</el-form-item>
+				</el-form>
+
+				<vxe-table border="inner" auto-resize resizable height="400px" :loading="loading" ref="xTable"
+					show-header-overflow show-overflow highlight-hover-row :menu-config="{}" :print-config="{}"
+					:sort-config="{ remote: true }" :data="dataList" :row-config="{ isCurrent: true }"
+					:radio-config="{ trigger: 'row' }">
+					<vxe-column type="seq" width="60" title="序号"></vxe-column>
+					<vxe-column type="radio" width="60px"></vxe-column>
+					<vxe-column min-width="230" align="center" title="供应商名称" field="name"></vxe-column>
+					<vxe-column min-width="230" align="center" title="联系电话" field="telPhone"></vxe-column>
+					<vxe-column min-width="230" align="center" title="地址" field="address"></vxe-column>
+					<vxe-column min-width="130" align="center" title="创建人" field="createName"></vxe-column>
+					<vxe-column min-width="200" align="center" title="创建时间" field="createTime"></vxe-column>
+				</vxe-table>
+				<vxe-pager background :current-page="tablePage.currentPage" :page-size="tablePage.pageSize"
+					:total="tablePage.total" :page-sizes="[10, 20, 100, 1000, { label: '全量数据', value: 1000000 }]"
+					:layouts="['PrevPage', 'JumpNumber', 'NextPage', 'FullJump', 'Sizes', 'Total']"
+					@page-change="currentChangeHandle">
+				</vxe-pager>
+			</div>
+			<template #footer>
+				<span class="dialog-footer">
+					<el-button @click="close()" icon="el-icon-circle-close">关闭</el-button>
+					<el-button type="primary" v-if="method != 'view'" @click="getSupplier()" icon="el-icon-circle-check"
+						v-noMoreClick>确定</el-button>
+				</span>
+			</template>
+		</el-dialog>
+	</div>
+</template>
+
+<script>
+import SupplierService from '@/api/psi/SupplierService'
+export default {
+	data() {
+		return {
+			title: '',
+			method: '',
+			visible: false,
+			loading: false,
+			tablePage: {
+				total: 0,
+				currentPage: 1,
+				pageSize: 10,
+				orders: []
+			},
+			dataList: [],
+			searchForm: {
+				name: '',
+				telPhone: '',
+				linkName: ''
+			}
+		}
+	},
+	supplierService: null,
+	created() {
+		this.supplierService = new SupplierService()
+	},
+	components: {
+	},
+	methods: {
+		init() {
+			this.visible = true
+			this.list()
+		},
+		// 表单提交
+		getSupplier() {
+			let row = this.$refs.xTable.getRadioRecord()
+			if (this.commonJS.isEmpty(row)) {
+				this.$message.error('请选择一条数据')
+				return
+			}
+			this.close()
+			this.$emit('getSupplier', row)
+		},
+		list() {
+			this.loading = true
+			this.supplierService.list({
+				'current': this.tablePage.currentPage,
+				'size': this.tablePage.pageSize,
+				'orders': this.tablePage.orders,
+				...this.searchForm
+			}).then((data) => {
+				this.dataList = data.records
+				this.tablePage.total = data.total
+				this.loading = false
+			})
+		},
+		// 当前页
+		currentChangeHandle({ currentPage, pageSize }) {
+			this.tablePage.currentPage = currentPage
+			this.tablePage.pageSize = pageSize
+			this.list()
+		},
+		resetSearch() {
+			this.$refs.searchForm.resetFields()
+			this.list()
+		},
+		close() {
+			this.$refs.searchForm.resetFields()
+			this.visible = false
+		}
+	}
+}
+</script>
+<style scoped>
+/deep/ .el-dialog__body {
+	padding-top: 0px;
+	padding-bottom: 15px;
+}
+</style>

+ 470 - 0
src/views/psiManagement/supplier/SupplierForm.vue

@@ -0,0 +1,470 @@
+<template xmlns:v-slot="http://www.w3.org/1999/XSL/Transform">
+	<div>
+		<el-dialog :title="title" :close-on-click-modal="false" draggable width="1200px" height="500px" @close="close"
+			append-to-body v-model="visible">
+			<el-row>
+				<el-form :model="inputForm" ref="inputForm" v-loading="loading" :class="method === 'view' ? 'readonly' : ''"
+					:disabled="method === 'view'" label-width="140px" @submit.native.prevent>
+					<el-row :gutter="0">
+						<el-col :span="10">
+							<el-form-item label="供应商名称" prop="name" :rules="[
+								{ required: true, message: '请填写供应商名称', trigger: 'blur' }
+							]">
+								<!--                <span slot="label"><span style="color: red;border-top: 20px">*</span> 供应商名称</span>-->
+								<el-input maxlength="64" v-model="inputForm.name" @input="checkName" @blur="checkName"
+									placeholder="请输入供应商名称"></el-input>
+							</el-form-item>
+						</el-col>
+						<el-col :span="2">
+							<el-popover v-model="visiblePop" placement="left" width="400" height="800" trigger="click"
+								:popper-options="{ boundariesElement: 'viewport', removeOnDestroy: true }" ref="pops">
+								<vxe-table border="inner" auto-resize resizable :row-config="{ isHover: true }"
+									:data="gridData" :checkbox-config="{}" :row-style="rowStyle" :key="popKey"
+									@cell-click="rowClick" :show-header="false">
+									<vxe-column title="" field="entname"></vxe-column>
+								</vxe-table>
+								<template #reference>
+									<el-button type="info" @click="getPopTable" style="width: 100%" plain>查询</el-button>
+								</template>
+
+							</el-popover>
+							<el-form-item>
+
+							</el-form-item>
+						</el-col>
+
+						<!--            <el-col :span="12">-->
+						<!--              <el-form-item label="供应商名称" prop="name" :rules="[-->
+						<!--                      {required: true, message:'供应商名称不能为空', trigger:'blur'}-->
+						<!--                   ]">-->
+						<!--                <el-input maxlength="64" v-model="inputForm.name" placeholder="请输入供应商名称"></el-input>-->
+						<!--              </el-form-item>-->
+						<!--            </el-col>-->
+
+						<el-col :span="12">
+							<el-form-item label="是否拥有信用代码" prop="isUscCode" :rules="[
+								{ required: true, message: '请选择是否拥有信用代码', trigger: 'blur' }
+							]">
+								<el-radio-group v-model="inputForm.isUscCode">
+									<el-radio v-for="item in $dictUtils.getDictList('yes_no')"
+										:label="item.value">{{ item.label }}</el-radio>
+								</el-radio-group>
+							</el-form-item>
+						</el-col>
+					</el-row>
+					<el-row :gutter="0">
+						<el-col v-if="inputForm.isUscCode === '1'" :span="12">
+							<el-form-item label="统一社会信用代码" prop="uscCode" :rules="[
+								{ required: true, message: '统一社会信用代码不能为空', trigger: 'blur' }
+							]">
+								<el-input v-model="inputForm.uscCode" placeholder="请填写统一社会信用代码"></el-input>
+							</el-form-item>
+						</el-col>
+						<el-col v-if="inputForm.isUscCode === '0' || commonJS.isEmpty(inputForm.isUscCode)" :span="12">
+							<el-form-item label="统一社会信用代码" prop="uscCode" :rules="[
+							]">
+								<el-input v-model="inputForm.uscCode" placeholder="请填写统一社会信用代码"></el-input>
+							</el-form-item>
+						</el-col>
+						<el-col :span="12">
+							<el-form-item label="归属地区" prop="reconciliationArea" :rules="[
+							]">
+								<SelectTree ref="areaTree" :props="{
+									value: 'id',             // ID字段名
+									label: 'name',         // 显示名称
+									children: 'children'    // 子级字段名
+								}" url="/system-server/sys/area/treeData" :value="inputForm.reconciliationArea" :clearable="true"
+									size="default" :accordion="true"
+									@getValue="(value) => { inputForm.reconciliationArea = value }" />
+							</el-form-item>
+						</el-col>
+						<!--            <el-col :span="12">-->
+						<!--              <el-form-item label="供应商性质" prop="characterIs"-->
+						<!--                            :rules="[-->
+						<!--                     ]">-->
+						<!--                <el-select v-model="inputForm.characterIs" placeholder="请选择供应商性质" style="width: 100%;">-->
+						<!--                  <el-option-->
+						<!--                    v-for="item in $dictUtils.getDictList('cw_work_client_type')"-->
+						<!--                    :key="item.value"-->
+						<!--                    :label="item.label"-->
+						<!--                    :value="item.value">-->
+						<!--                  </el-option>-->
+						<!--                </el-select>-->
+						<!--              </el-form-item>-->
+						<!--            </el-col>-->
+						<el-col :span="12">
+							<el-form-item label="邮政编码" prop="zipCode">
+								<el-input maxlength="64" v-model="inputForm.zipCode" placeholder="请填写邮政编码"></el-input>
+							</el-form-item>
+						</el-col>
+						<el-col :span="12">
+							<el-form-item label="传真" prop="fax">
+								<el-input maxlength="64" v-model="inputForm.fax" placeholder="请填写传真"></el-input>
+							</el-form-item>
+						</el-col>
+						<el-col :span="12">
+							<el-form-item label="联系电话" prop="telPhone" :rules="[
+							]">
+								<el-input v-model="inputForm.telPhone" placeholder="联系电话"></el-input>
+							</el-form-item>
+						</el-col>
+						<el-col :span="12">
+							<el-form-item label="地址" prop="address" :rules="[
+							]">
+								<el-input v-model="inputForm.address" placeholder="地址"></el-input>
+							</el-form-item>
+						</el-col>
+						<el-col :span="24">
+							<el-form-item label="备注" prop="remarks" :rules="[
+							]">
+								<el-input type="textarea" style="width:100%" :rows="5" maxlength="500"
+									v-model="inputForm.remarks" placeholder="请填写备注"></el-input>
+							</el-form-item>
+						</el-col>
+
+					</el-row>
+				</el-form>
+			</el-row>
+			<!--    联系人信息-->
+			<el-divider content-position="left">
+				<i class="el-icon-document"></i>
+				联系人信息
+				<el-button style="margin-left: 20px" type="primary" :disabled="method === 'view'"
+					@click="insertEvent('link')" plain>
+					新增
+				</el-button>
+			</el-divider>
+			<el-row :gutter="15">
+				<el-col :span="24">
+					<vxe-table border :column-config="{ resizable: true }" show-overflow show-footer :key="tableKey"
+						ref="linkTable" class="vxe-table-element" :data="inputForm.materialSupplierLinkDTOList"
+						style="margin-left: 3em" highlight-current-row :edit-rules="validRules"
+						:edit-config="{ trigger: 'click', mode: 'row', showStatus: false, autoClear: true, icon: '-', activeMethod: activeRowMethod }">
+						<vxe-table-column align="center" field="name" title="姓名" :edit-render="{}">
+							<template v-slot:edit="scope">
+								<vxe-input v-model="scope.row.name" placeholder="姓名"></vxe-input>
+							</template>
+						</vxe-table-column>
+						<vxe-table-column align="center" field="sex" title="性别"
+							:edit-render="{ name: '$select', options: $dictUtils.getDictList('sex') }">
+							<template v-slot:edit="scope">
+								<vxe-select v-model="scope.row.sex" placeholder="性别" style="width: 100%;" transfer>
+									<vxe-option v-for="item in $dictUtils.getDictList('sex')" :key="item.value"
+										:label="item.label" :value="item.value">
+									</vxe-option>
+								</vxe-select>
+							</template>
+						</vxe-table-column>
+						<vxe-table-column align="center" field="office" title="部门" :edit-render="{}">
+							<template v-slot:edit="scope">
+								<vxe-input v-model="scope.row.office" placeholder="部门"></vxe-input>
+							</template>
+						</vxe-table-column>
+						<vxe-table-column align="center" field="position" title="职务" :edit-render="{}">
+							<template v-slot:edit="scope">
+								<vxe-input v-model="scope.row.position" placeholder="职务"></vxe-input>
+							</template>
+						</vxe-table-column>
+						<vxe-table-column align="center" field="linkPhone" title="联系方式1" :edit-render="{}">
+							<template v-slot:edit="scope">
+								<vxe-input v-model="scope.row.linkPhone" oninput="value=value.replace(/[^\d]/g,'')"
+									placeholder="联系方式1"></vxe-input>
+							</template>
+						</vxe-table-column>
+						<vxe-table-column align="center" field="linkMobile" title="联系方式2" :edit-render="{}">
+							<template v-slot:edit="scope">
+								<vxe-input v-model="scope.row.linkMobile" oninput="value=value.replace(/[^\d]/g,'')"
+									placeholder="联系方式2"></vxe-input>
+							</template>
+						</vxe-table-column>
+						<vxe-table-column align="center" field="email" title="邮箱" :edit-render="{}">
+							<template v-slot:edit="scope">
+								<vxe-input v-model="scope.row.email" @change="$forceUpdate()"
+									@blur="blurEmail(scope.$rowIndex)" placeholder="邮箱"></vxe-input>
+							</template>
+						</vxe-table-column>
+						<vxe-table-column align="center" field="remarks" title="备注" :edit-render="{}">
+							<template v-slot:edit="scope">
+								<vxe-input maxlength="500" v-model="scope.row.remarks" placeholder="备注"></vxe-input>
+							</template>
+						</vxe-table-column>
+						<vxe-table-column align="center" title="操作" width="100">
+							<template v-slot="scope">
+								<el-button :disabled="method === 'view'" size="small" type="danger"
+									@click="removeEvent(scope.row, scope.$rowIndex, 'link')">删除</el-button>
+							</template>
+						</vxe-table-column>
+					</vxe-table>
+				</el-col>
+			</el-row>
+			<!--    附件-->
+			<UpLoadComponent ref="uploadComponent"></UpLoadComponent>
+			<template #footer>
+				<span class="dialog-footer">
+					<el-button :loading="loading" @click="close()" icon="el-icon-circle-close">关闭</el-button>
+					<el-button :loading="loading" v-if="method === 'edit' || method === 'add'" type="primary"
+						icon="el-icon-circle-check" @click="save()">确定</el-button>
+				</span>
+			</template>
+		</el-dialog>
+	</div>
+</template>
+
+<script>
+import SelectTree from '@/components/treeSelect/treeSelect.vue'
+import UpLoadComponent from '@/views/common/UpLoadComponent'
+import SupplierService from '@/api/psi/SupplierService'
+import EnterpriseSearchService from '@/api/cw/common/EnterpriseSearchService'
+export default {
+	data() {
+		return {
+			title: '',
+			method: '',
+			loading: false,
+			inputForm: {
+				name: '',
+				isUscCode: '',
+				uscCode: '',
+				reconciliationArea: '',
+				characterIs: '',
+				zipCode: '',
+				fax: '',
+				telPhone: '',
+				address: '',
+				remarks: '',
+				materialSupplierLinkDTOList: [],
+				workAttachmentDtoList: []
+			},
+			tableKey: '',
+			visible: false,
+			visiblePop: false,
+			validRules: {
+				name: [
+					{ required: true, message: '姓名不可以为空' }
+				],
+				// linkPhone: [
+				//   {required: true, message: '联系方式1不可以为空'}
+				// ]
+			},
+			gridData: [],
+			popKey: ''
+		}
+	},
+	supplierService: null,
+	enterpriseSearchService: null,
+	created() {
+		this.supplierService = new SupplierService()
+		this.enterpriseSearchService = new EnterpriseSearchService()
+	},
+	components: {
+		UpLoadComponent,
+		SelectTree
+	},
+	methods: {
+		init(method, id) {
+			if (method === 'add') {
+				this.title = '新建供应商信息'
+			} else if (method === 'edit') {
+				this.title = '修改供应商信息'
+			} else {
+				method = 'view'
+				this.title = '查看供应商信息'
+			}
+			this.visible = true
+			this.method = method
+			this.inputForm = {
+				name: '',
+				isUscCode: '',
+				uscCode: '',
+				reconciliationArea: '',
+				characterIs: '',
+				zipCode: '',
+				fax: '',
+				telPhone: '',
+				address: '',
+				remarks: '',
+				materialSupplierLinkDTOList: [],
+				workAttachmentDtoList: []
+			}
+			this.inputForm.id = id
+			if (this.commonJS.isEmpty(this.inputForm.id)) {
+				this.inputForm.id = 'false'
+			}
+			this.loading = false
+			this.$nextTick(() => {
+				this.$refs.inputForm.resetFields()
+				this.loading = true
+				this.supplierService.queryById(this.inputForm.id).then((data) => {
+					this.$refs.uploadComponent.clearUpload()
+					this.inputForm = this.recover(this.inputForm, data)
+					this.inputForm = JSON.parse(JSON.stringify(this.inputForm))
+					if (this.commonJS.isEmpty(this.inputForm.isUscCode)) {
+						this.inputForm.isUscCode = '0'
+					}
+					if (this.commonJS.isEmpty(this.inputForm.materialSupplierLinkDTOList)) {
+						this.inputForm.materialSupplierLinkDTOList = []
+					}
+					if (this.commonJS.isEmpty(this.inputForm.workAttachmentDtoList)) {
+						this.inputForm.workAttachmentDtoList = []
+					}
+					this.$refs.uploadComponent.newUpload(this.method, this.inputForm.workAttachmentDtoList, 'material_supplier')
+					this.loading = false
+				})
+			})
+		},
+		save() {
+			this.$refs['inputForm'].validate(async (valid) => {
+				if (valid) {
+					if (this.commonJS.isEmpty(this.inputForm.materialSupplierLinkDTOList)) {
+						// this.$message.error('联系人信息至少填写一条')
+						this.saveTrue()
+					} else {
+						const errMap = await this.$refs.linkTable.validate(true).catch(errMap => errMap)
+						if (errMap) {
+							this.$message.error('联系人信息填写不正确')
+						} else {
+							this.supplierService.findByName(this.inputForm.name).then((data) => {
+								if (this.commonJS.isNotEmpty(data) && this.commonJS.isNotEmpty(data.name)) { // 说明有查询到这个名称的数据
+									if ((this.commonJS.isNotEmpty(this.inputForm.id) && this.inputForm.id !== data.id) || this.commonJS.isEmpty(this.inputForm.id)) {
+										this.$message.warning('供应商已存在')
+									} else {
+										this.saveTrue()
+									}
+								} else {
+									this.saveTrue()
+								}
+							})
+						}
+					}
+				}
+			})
+		},
+		saveTrue() {
+			this.loading = true
+			if (this.$refs.uploadComponent.checkProgress()) {
+				this.loading = false
+			} else {
+				this.inputForm.workAttachmentDtoList = this.$refs.uploadComponent.getDataList()
+				this.supplierService.save(this.inputForm).then(() => {
+					this.loading = false
+					this.$emit('refreshList')
+					this.close()
+				}).catch(() => {
+					this.loading = false
+				})
+			}
+		},
+		close() {
+			this.inputForm = {
+				name: '',
+				isUscCode: '',
+				uscCode: '',
+				reconciliationArea: '',
+				characterIs: '',
+				zipCode: '',
+				fax: '',
+				telPhone: '',
+				address: '',
+				remarks: '',
+				materialSupplierLinkDTOList: [],
+				workAttachmentDtoList: []
+			}
+			this.$refs.uploadComponent.clearUpload()
+			this.$refs.inputForm.resetFields()
+			this.visible = false
+		},
+		// 新增
+		insertEvent(type) {
+			if (type === 'link') {
+				let d = {
+					name: '',
+					office: '',
+					position: '',
+					sex: '',
+					linkPhone: '',
+					linkMobile: '',
+					email: ''
+				}
+				if (this.commonJS.isEmpty(this.inputForm.materialSupplierLinkDTOList)) {
+					this.inputForm.materialSupplierLinkDTOList = []
+				}
+				this.$refs.linkTable.insertAt(d)
+				this.inputForm.materialSupplierLinkDTOList.push(d)
+				this.tableKey = Math.random()
+			}
+		},
+		// 删除
+		removeEvent(row, rowIndex, type) {
+			if (type === 'link') {
+				this.$refs.linkTable.remove(row)
+				this.inputForm.materialSupplierLinkDTOList.splice(rowIndex, 1)
+			}
+		},
+		blurEmail(index) {
+			if (this.commonJS.isNotEmpty(this.inputForm.materialSupplierLinkDTOList[index].email)) {
+				if (!this.validateXG.isEmail(this.inputForm.materialSupplierLinkDTOList[index].email)) {
+					this.$message.error('联系人信息中,第' + (index + 1) + '条数据的“邮箱”填写错误,请重新填写')
+					this.inputForm.materialSupplierLinkDTOList[index].email = ''
+					throw new Error('联系人信息中,第' + (index + 1) + '条数据的“邮箱”填写错误,请重新填写')
+				}
+			}
+		},
+		// 禁用编辑
+		activeRowMethod({ row, rowIndex }) {
+			if (this.method === 'view') {
+				return false
+			}
+			return true
+		},
+		rowStyle(event) {
+			return 'cursor:pointer;'
+		},
+		async rowClick(event) {
+			let id = this.gridData[event.rowIndex].companyid
+			await this.enterpriseSearchService.enterpriseTicketInfo(id).then((data) => {
+				this.inputForm.name = data.ENTNAME
+				this.inputForm.uscCode = data.UNCID
+				this.inputForm.address = data.OPLOC
+				this.checkName()
+			})
+			this.visiblePop = false
+		},
+		async getPopTable() {
+			let name = this.inputForm.name
+			if (this.commonJS.isNotEmpty(name)) {
+				await this.enterpriseSearchService.enterpriseSearchByName(name).then((data) => {
+					this.gridData = data.data.items
+					this.updatePopover();
+					this.popKey = Math.random()
+				})
+			}
+			this.updatePopover();
+		},
+		updatePopover() {
+			this.visiblePop = false; // 关闭弹出框
+			this.$nextTick(() => {
+				this.visiblePop = true; // 重新打开弹出框
+			});
+		},
+		closePop() {
+			this.visiblePop = false
+		},
+		checkName() {
+			if (this.commonJS.isNotEmpty(this.inputForm.name)) {
+				this.supplierService.findByName(this.inputForm.name).then((data) => {
+					if (this.commonJS.isNotEmpty(data) && this.commonJS.isNotEmpty(data.name)) { // 说明有查询到这个名称的数据
+						if ((this.commonJS.isNotEmpty(this.inputForm.id) && this.inputForm.id !== data.id) || this.commonJS.isEmpty(this.inputForm.id)) {
+							this.$message.warning('供应商已存在')
+						}
+					}
+				})
+			}
+		}
+	}
+}
+</script>
+<style>
+.vxe-select--panel {
+	z-index: 3000 !important;
+}
+</style>

+ 190 - 0
src/views/psiManagement/supplier/SupplierList.vue

@@ -0,0 +1,190 @@
+<template>
+	<div class="page">
+		<el-form :inline="true" v-if="searchVisible" class="query-form m-b-10" ref="searchForm" :model="searchForm"
+			@keyup.enter.native="refreshList()" @submit.native.prevent>
+			<!-- 搜索框-->
+			<el-form-item label="供应商名称" prop="name">
+				<el-input v-model="searchForm.name" placeholder="请输入供应商名称" clearable></el-input>
+			</el-form-item>
+			<el-form-item label="联系电话" prop="telPhone">
+				<el-input v-model="searchForm.telPhone" placeholder="请输入联系电话" clearable></el-input>
+			</el-form-item>
+			<el-form-item label="联系人名称" prop="linkName">
+				<el-input v-model="searchForm.linkName" placeholder="请输入联系人名称" clearable></el-input>
+			</el-form-item>
+
+			<el-form-item>
+				<el-button type="primary" @click="refreshList()" icon="el-icon-search">查询</el-button>
+				<el-button @click="resetSearch()" icon="el-icon-refresh-right">重置</el-button>
+			</el-form-item>
+		</el-form>
+		<div class="jp-table top" style="">
+			<vxe-toolbar :refresh="{ query: refreshList }" custom>
+				<template #buttons>
+					<el-button v-if="hasPermission('psi:supplier:add')" type="primary" icon="el-icon-plus"
+						@click="add()">新建</el-button>
+					<el-button v-if="isAdmin" type="danger" icon="el-icon-delete" @click="del()"
+						:disabled="$refs.supplierTable && $refs.supplierTable.getCheckboxRecords().length === 0"
+						plain>删除</el-button>
+				</template>
+				<template #tools>
+					<vxe-button text type="primary" :title="searchVisible ? '收起检索' : '展开检索'" icon="vxe-icon-search"
+						class="tool-btn" @click="searchVisible = !searchVisible"></vxe-button>
+				</template>
+			</vxe-toolbar>
+			<div style="height: calc(100% - 90px)">
+				<vxe-table border="inner" auto-resize resizable height="auto" :loading="loading" ref="supplierTable"
+					show-header-overflow show-overflow highlight-hover-row :menu-config="{}" :data="dataList"
+					:checkbox-config="{}">
+					<vxe-column type="seq" width="60" title="序号"></vxe-column>
+					<vxe-column type="checkbox" width="60"></vxe-column>
+					<vxe-column min-width="230" align="center" title="供应商名称" field="name">
+						<template #default="scope">
+							<el-link type="primary" :underline="false" v-if="hasPermission('psi:supplier:view')"
+								@click="view(scope.row.id)">{{ scope.row.name }}</el-link>
+							<span v-else>{{ scope.row.name }}</span>
+						</template>
+					</vxe-column>
+					<vxe-column min-width="230" align="center" title="联系电话" field="telPhone"></vxe-column>
+					<vxe-column min-width="230" align="center" title="地址" field="address"></vxe-column>
+					<vxe-column min-width="130" align="center" title="创建人" field="createName"></vxe-column>
+					<vxe-column min-width="200" align="center" title="创建时间" field="createTime"></vxe-column>
+					<vxe-column title="操作" width="150px" fixed="right" align="center">
+						<template #default="scope">
+							<el-button
+								v-if="(hasPermission('psi:supplier:edit') && $store.state.user.id === scope.row.createBy.id) || isAdmin"
+								text type="primary" size="small" @click="edit(scope.row.id)">修改</el-button>
+							<el-button
+								v-if="(hasPermission('psi:supplier:del') && $store.state.user.id === scope.row.createBy.id) || isAdmin"
+								text type="primary" size="small" @click="del(scope.row.id)">删除</el-button>
+						</template>
+					</vxe-column>
+				</vxe-table>
+				<vxe-pager background :current-page="tablePage.currentPage" :page-size="tablePage.pageSize"
+					:total="tablePage.total" :page-sizes="[10, 20, 100, 1000, { label: '全量数据', value: 1000000 }]"
+					:layouts="['PrevPage', 'JumpNumber', 'NextPage', 'FullJump', 'Sizes', 'Total']"
+					@page-change="currentChangeHandle">
+				</vxe-pager>
+			</div>
+		</div>
+		<SupplierForm ref="supplierForm" @refreshList="refreshList"></SupplierForm>
+	</div>
+</template>
+
+<script>
+import SupplierForm from './SupplierForm'
+import SupplierService from '@/api/psi/SupplierService'
+import userService from '@/api/sys/userService'
+export default {
+	data() {
+		return {
+			searchVisible: true,
+			searchForm: {
+				telPhone: '',
+				name: '',
+				linkName: ''
+			},
+			dataList: [],
+			tablePage: {
+				total: 0,
+				currentPage: 1,
+				pageSize: 10,
+				orders: []
+			},
+			loading: false,
+			isAdmin: false
+		}
+	},
+	supplierService: null,
+	created() {
+		this.supplierService = new SupplierService()
+	},
+	components: {
+		SupplierForm
+	},
+	mounted() {
+		this.refreshList()
+	},
+	activated() {
+		this.refreshList()
+	},
+	methods: {
+		// 查询当前用户是否是管理员用户
+		checkIsAdmin() {
+			userService.is().then((data) => {
+				this.isAdmin = data
+			})
+		},
+		// 新增
+		add() {
+			this.$refs.supplierForm.init('add', 'false')
+		},
+		// 修改
+		edit(id) {
+			id = id || this.$refs.supplierTable.getCheckboxRecords().map(item => {
+				return item.id
+			})[0]
+			this.$refs.supplierForm.init('edit', id)
+		},
+		// 查看
+		view(id) {
+			this.$refs.supplierForm.init('view', id)
+		},
+		// 获取数据列表
+		refreshList() {
+			this.loading = true
+			this.supplierService.list({
+				'current': this.tablePage.currentPage,
+				'size': this.tablePage.pageSize,
+				'orders': this.tablePage.orders,
+				...this.searchForm
+			}).then((data) => {
+				this.dataList = data.records
+				this.tablePage.total = data.total
+				this.loading = false
+			})
+			this.checkIsAdmin()
+		},
+		// 当前页
+		currentChangeHandle({ currentPage, pageSize }) {
+			this.tablePage.currentPage = currentPage
+			this.tablePage.pageSize = pageSize
+			this.refreshList()
+		},
+		// 排序
+		sortChangeHandle(column) {
+			this.tablePage.orders = []
+			if (column.order != null) {
+				this.tablePage.orders.push({ column: this.$utils.toLine(column.property), asc: column.order === 'asc' })
+			}
+			this.refreshList()
+		},
+		// 删除
+		del(id) {
+			let ids = id || this.$refs.supplierTable.getCheckboxRecords().map(item => {
+				return item.id
+			}).join(',')
+			this.$confirm(`确定删除所选项吗?`, '提示', {
+				confirmButtonText: '确定',
+				cancelButtonText: '取消',
+				type: 'warning'
+			}).then(() => {
+				this.loading = true
+				this.supplierService.delete(ids).then((data) => {
+					if (data === '删除成功') {
+						this.$message.success(data)
+					} else {
+						this.$message.error(data)
+					}
+					this.refreshList()
+					this.loading = false
+				})
+			})
+		},
+		resetSearch() {
+			this.$refs.searchForm.resetFields()
+			this.refreshList()
+		}
+	}
+}
+</script>

+ 135 - 0
src/views/psiManagement/wareHouse/PurchaseChooseForm.vue

@@ -0,0 +1,135 @@
+<template>
+	<div>
+		<el-dialog title="选择采购信息" :close-on-click-modal="false" draggable width="1100px" height="500px" @close="close"
+			append-to-body v-model="visible">
+			<div style="height: calc(100% - 80px);">
+				<el-form :inline="true" class="query-form" ref="searchForm" :model="searchForm" @submit.native.prevent>
+					<!-- 搜索框-->
+					<el-form-item label="采购名称" prop="purchaseSketch">
+						<el-input v-model="searchForm.purchaseSketch" placeholder="请输入采购名称" clearable></el-input>
+					</el-form-item>
+					<el-form-item label="申请时间" prop="contractDates">
+						<el-date-picker placement="bottom-start" format="YYYY-MM-DD HH:mm:ss"
+							value-format="YYYY-MM-DD HH:mm:ss" v-model="searchForm.contractDates" type="datetimerange"
+							range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期">
+						</el-date-picker>
+					</el-form-item>
+
+					<el-form-item>
+						<el-button type="primary" @click="list()" icon="el-icon-search">查询</el-button>
+						<el-button @click="resetSearch()" icon="el-icon-refresh-right">重置</el-button>
+					</el-form-item>
+				</el-form>
+
+				<vxe-table border="inner" auto-resize resizable height="400px" :loading="loading" ref="projectTable"
+					show-header-overflow show-overflow highlight-hover-row :menu-config="{}" :print-config="{}"
+					:sort-config="{ remote: true }" :data="dataList" :row-config="{ isCurrent: true }"
+					:radio-config="{ trigger: 'row' }">
+					<vxe-column type="seq" width="60" title="序号"></vxe-column>
+					<vxe-column type="radio" width="60px"></vxe-column>
+					<vxe-column min-width="160" align="center" title="采购编号" field="purchaseNo"></vxe-column>
+					<vxe-column min-width="160" align="center" title="采购名称" field="purchaseSketch"></vxe-column>
+					<vxe-column min-width="160" align="center" title="经办人" field="handledByName"></vxe-column>
+					<vxe-column min-width="160" align="center" title="经办人部门" field="handledByOfficeName"></vxe-column>
+					<vxe-column min-width="160" align="center" title="申请时间" field="createDate"></vxe-column>
+					<vxe-column min-width="160" align="center" title="采购方式" field="purchaseMode"></vxe-column>
+
+				</vxe-table>
+				<vxe-pager background :current-page="tablePage.currentPage" :page-size="tablePage.pageSize"
+					:total="tablePage.total" :page-sizes="[10, 20, 100, 1000, { label: '全量数据', value: 1000000 }]"
+					:layouts="['PrevPage', 'JumpNumber', 'NextPage', 'FullJump', 'Sizes', 'Total']"
+					@page-change="currentChangeHandle">
+				</vxe-pager>
+			</div>
+			<template #footer>
+				<span class="dialog-footer">
+					<el-button @click="close()" icon="el-icon-circle-close">关闭</el-button>
+					<el-button type="primary" v-if="method != 'view'" @click="getProject()" icon="el-icon-circle-check"
+						v-noMoreClick>确定</el-button>
+				</span>
+			</template>
+		</el-dialog>
+	</div>
+</template>
+
+<script>
+import WareHouseService from '@/api/psi/WareHouseService'
+export default {
+	data() {
+		return {
+			title: '',
+			method: '',
+			visible: false,
+			loading: false,
+			tablePage: {
+				total: 0,
+				currentPage: 1,
+				pageSize: 10,
+				orders: []
+			},
+			dataList: [],
+			searchForm: {
+				purchaseSketch: '',
+				contractDates: []
+			}
+		}
+	},
+	wareHouseService: null,
+	created() {
+		this.wareHouseService = new WareHouseService()
+	},
+	components: {
+	},
+	methods: {
+		init() {
+			this.visible = true
+			this.list()
+		},
+		// 表单提交
+		getProject() {
+			let row = this.$refs.projectTable.getRadioRecord()
+			if (this.commonJS.isEmpty(row)) {
+				this.$message.error('请选择一条数据')
+				return
+			}
+			this.close()
+			this.$emit('getProject', row)
+		},
+		list() {
+			this.loading = true
+			// this.searchForm.createId = this.$store.state.user.id
+			this.searchForm.status = '5'
+			this.wareHouseService.reimbursementList({
+				'current': this.tablePage.currentPage,
+				'size': this.tablePage.pageSize,
+				'orders': this.tablePage.orders,
+				...this.searchForm
+			}).then((data) => {
+				this.dataList = data.records
+				this.tablePage.total = data.total
+				this.loading = false
+			})
+		},
+		// 当前页
+		currentChangeHandle({ currentPage, pageSize }) {
+			this.tablePage.currentPage = currentPage
+			this.tablePage.pageSize = pageSize
+			this.list()
+		},
+		resetSearch() {
+			this.$refs.searchForm.resetFields()
+			this.list()
+		},
+		close() {
+			this.$refs.searchForm.resetFields()
+			this.visible = false
+		}
+	}
+}
+</script>
+<style scoped>
+/deep/ .el-dialog__body {
+	padding-top: 0px;
+	padding-bottom: 15px;
+}
+</style>

Datei-Diff unterdrückt, da er zu groß ist
+ 1044 - 0
src/views/psiManagement/wareHouse/WareHouseAddForm.vue


+ 473 - 0
src/views/psiManagement/wareHouse/WareHouseHi.vue

@@ -0,0 +1,473 @@
+<template xmlns:v-slot="http://www.w3.org/1999/XSL/Transform">
+	<div>
+		<el-dialog :title="title" :close-on-click-modal="false" draggable append-to-body width="1300px" @close="close"
+			v-model="visible">
+			<el-form :model="inputForm" ref="inputForm" v-loading="loading" :class="method === 'view' ? 'readonly' : ''"
+				:disabled="true" label-width="100px" @submit.native.prevent>
+				<el-divider content-position="left"><i class="el-icon-document"></i> 基础信息</el-divider>
+				<el-row :gutter="26">
+					<el-col :span="12">
+						<el-form-item label="入库编号" prop="wareHouseNumber">
+							<el-input placeholder="自动生成" v-model="inputForm.wareHouseNumber"
+								:disabled="true"></el-input>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="入库名称" prop="wareHouseName" :rules="[{ required: true, message: '入库名称不能为空', trigger: 'blur' }
+						]">
+							<el-input v-model="inputForm.wareHouseName" placeholder="请填写入库名称"></el-input>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="经办人" prop="handledBy">
+							<el-input v-model="inputForm.handledBy" :disabled="true"></el-input>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="经办人部门" prop="handledByOffice">
+							<SelectTree :disabled="true" ref="officeTree" :props="{
+								value: 'id',             // ID字段名
+								label: 'name',         // 显示名称
+								children: 'children'    // 子级字段名
+							}" :url="`/system-server/sys/office/treeData?type=2`" :value="inputForm.handledByOffice"
+								:accordion="true" size="default"
+								@getValue="(value) => { inputForm.handledByOffice = value }" />
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="入库时间" prop="wareHouseDate"
+							:rules="[{ required: true, message: '请选择入库时间', trigger: 'blur' }]">
+							<el-date-picker v-model="inputForm.wareHouseDate" type="date" value-format="yyyy-MM-dd"
+								style="width: 100%" placement="bottom-start" placeholder="选择日期">
+							</el-date-picker>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="采购编号" prop="purchaseNo" :rules="[]">
+							<el-input :readonly="true" @focus="openContractForm()" v-model="inputForm.purchaseNo"
+								placeholder="请选择采购编号">
+								<el-button slot="append" icon="el-icon-search" @click="openContractForm()"></el-button>
+							</el-input>
+						</el-form-item>
+					</el-col>
+					<el-col :span="24">
+						<el-form-item label="备注" prop="remarks">
+							<el-input v-model="inputForm.remarks" type="textarea" :rows="5" maxlength="500"
+								placeholder="请输入简介" show-word-limit>
+							</el-input>
+						</el-form-item>
+					</el-col>
+				</el-row>
+
+				<div v-if="commonJS.isNotEmpty(inputForm.purchaseNo)">
+					<el-divider content-position="left"><i class="el-icon-document"
+							style="font-weight: bold;font-size: 16px;color:#409EFF"></i>
+						<el-link @click="viewContract(inputForm.purchaseNo)"><span
+								style="font-weight: bold;font-size: 16px;color:#409EFF">&nbsp;采购详情</span></el-link>
+					</el-divider>
+					<el-row :gutter="15">
+						<vxe-table border show-footer show-overflow :footer-method="footerMethod" ref="detailTable"
+							class="vxe-table-element" :data="inputForm.detailInfos" style="margin-left: 3em">
+							<vxe-column min-width="100" align="center" field="purchaserAgent" title="采购人"></vxe-column>
+							<vxe-column min-width="100" align="center" field="procurementOffice"
+								title="采购部门"></vxe-column>
+							<vxe-column min-width="100" align="center" field="procurementType"
+								title="采购类型"></vxe-column>
+							<vxe-column min-width="220" align="center" field="tradeName" title="商品名称"></vxe-column>
+							<vxe-column min-width="130px" align="center" field="supplierName" title="供应商"></vxe-column>
+							<vxe-column min-width="100" align="center" field="tradePrice" title="商品单价(元)"></vxe-column>
+							<vxe-column min-width="80" align="center" field="tradeNumber" title="商品数量"></vxe-column>
+							<vxe-column min-width="100" align="center" field="priceSum" title="商品总价"></vxe-column>
+							<vxe-column min-width="100" align="center" field="company" title="单位"></vxe-column>
+							<vxe-column min-width="100" align="center" field="remarks" title="备注"></vxe-column>
+							<vxe-column align="center" title="操作" fixed="right" width="80">
+								<template v-slot="scope">
+									<el-button size="small" type="primary" :disabled="false"
+										@click="seeFileInfo(scope.$rowIndex)" plain>附件</el-button>
+								</template>
+							</vxe-column>
+						</vxe-table>
+					</el-row>
+				</div>
+
+				<el-divider content-position="left"><i class="el-icon-document"></i>
+					入库详情
+				</el-divider>
+				<el-row :gutter="15">
+					<vxe-table border show-footer show-overflow :footer-method="footerMethod2" ref="detailTableWare"
+						class="vxe-table-element" :data="inputForm.wareHouse" style="margin-left: 3em"
+						:row-class-name="rowClassName" :key="tableKey">
+						<vxe-column min-width="110px" align="center" field="wareHouseMan" title="入库人">
+							<template v-slot="scope">
+								<span v-if="scope.row.upFlag === '1'"> {{ scope.row.wareHouseMan }}(修改前) </span>
+								<span v-else-if="scope.row.upFlag === '2'"> {{ scope.row.wareHouseMan }}(已删除) </span>
+								<span v-else-if="scope.row.upFlag === '0' && commonJS.isNotEmpty(scope.row.sourceId)">
+									{{ scope.row.wareHouseMan }}(修改后) </span>
+								<span v-else-if="scope.row.upFlag === '0' && commonJS.isEmpty(scope.row.sourceId)">
+									{{ scope.row.wareHouseMan }} </span>
+							</template>
+						</vxe-column>
+						<vxe-column min-width="100px" align="center" field="wareHouseManOffice"
+							title="入库部门"></vxe-column>
+						<vxe-column min-width="100px" align="center" field="wareHouseType" title="入库类型"></vxe-column>
+						<vxe-column min-width="180px" align="center" field="tradeName" title="商品名称"></vxe-column>
+						<vxe-column min-width="130px" align="center" field="supplierName" title="供应商"></vxe-column>
+						<vxe-column min-width="80px" align="center" field="tradeNumber" title="商品数量"></vxe-column>
+						<vxe-column min-width="80px" align="center" field="company" title="单位"></vxe-column>
+						<vxe-column min-width="80px" align="center" field="tradePrice" title="商品单价(元)"></vxe-column>
+						<vxe-column min-width="80px" align="center" field="priceSum" title="商品总价"></vxe-column>
+						<vxe-column min-width="80px" align="center" field="actualPrice" title="实际价格"></vxe-column>
+						<vxe-column min-width="100px" align="center" field="remarks" title="备注"></vxe-column>
+						<vxe-column align="center" fixed="right" title="操作" width="80px">
+							<template v-slot="scope">
+								<el-button size="small" type="primary" v-if="scope.row.upFlag !== '1'" :disabled="false"
+									@click="seeFileInfo2(scope.$rowIndex)" plain>附件</el-button>
+							</template>
+						</vxe-column>
+					</vxe-table>
+				</el-row>
+				<el-row>
+					<el-col :span="24" style="margin-top: 20px">
+						<el-form-item label="修改原因" prop="updateCause"
+							:rules="[{ required: true, message: '修改原因不能为空', trigger: 'blur' }]">
+							<el-input type="textarea" :rows="5" maxlength="500" placeholder="请填写修改原因" show-word-limit
+								v-model="inputForm.updateCause"></el-input>
+						</el-form-item>
+					</el-col>
+				</el-row>
+			</el-form>
+			<!-- 附件 -->
+			<MaterialManagementDialog ref="materialManagementDialog" @getUpload="getUpload"></MaterialManagementDialog>
+			<UpdateInfoForm ref="updateInfoForm"></UpdateInfoForm>
+			<PurchaseChooseForm ref="purchaseChooseForm" @getProject="getContract"></PurchaseChooseForm>
+			<UpLoadComponent ref="uploadComponent"></UpLoadComponent>
+			<CwProgramPageForm ref="cwProgramPageForm" @getProgram="getProgram"></CwProgramPageForm>
+			<MaterialTypePullForm ref="materialTypePullForm" @getProgramForType="getProgramForType">
+			</MaterialTypePullForm>
+			<UserPullForm ref="userPullForm" @getProgramForUser="getProgramForUser"></UserPullForm>
+			<template #footer>
+				<span class="dialog-footer">
+					<el-button @click="close()" icon="el-icon-circle-close">关闭</el-button>
+				</span>
+			</template>
+		</el-dialog>
+	</div>
+</template>
+
+<script>
+import MaterialManagementDialog from '../file/MaterialManagementDialog'
+import WareHouseService from '@/api/psi/WareHouseService'
+import UpdateInfoForm from '../info/UpdateInfoForm'
+import PurchaseChooseForm from './PurchaseChooseForm'
+
+import CommonApi from '@/api/cw/common/CommonApi'
+import MaterialManagementService from '@/api/psi/MaterialManagementService'
+import UpLoadComponent from '@/views/common/UpLoadComponent'
+import SelectTree from '@/components/treeSelect/treeSelect.vue'
+import XEUtils from 'xe-utils'
+import CwProgramPageForm from '@/views/cw/reimbursementApproval/info/CwProgramPageForm'
+import MaterialTypePullForm from '../info/MaterialTypePullForm'
+import UserPullForm from '@/views/finance/invoice/UserPullForm'
+export default {
+	data() {
+		return {
+			title: '',
+			method: '',
+			visible: false,
+			loading: false,
+			indexRow: '',
+			inputForm: {
+				procInsId: '',
+				wareHouseTotalPrice: '', // 入库商品总价
+				wareHouseActualPrice: '', // 入库商品实际价格
+				tradeTotalPrice: '',  // 商品总价
+				fileInfoLost: [],
+				purchaseNo: '',
+				handledBy: '',
+				handledById: '',
+				handledByOffice: '',
+				wareHouseName: '',
+				wareHouseNumber: '', // 入库编号
+				userId: '',
+				wareHouseDate: '',
+				remarks: '',
+				detailInfos: [],
+				wareHouse: [],
+				// amountInfos: [],
+				files: [], // 附件信息
+				functionFlag: ''
+			},
+			keyWatch: '',
+			tableKey: ''
+		}
+	},
+	wareHouseService: null,
+	MaterialManagementService: null,
+	commonApi: null,
+	created() {
+		this.materialManagementService = new MaterialManagementService()
+		this.commonApi = new CommonApi()
+		this.wareHouseService = new WareHouseService()
+	},
+	props: {},
+	components: {
+		MaterialManagementDialog,
+		PurchaseChooseForm,
+		UpLoadComponent,
+		SelectTree,
+		CwProgramPageForm,
+		MaterialTypePullForm,
+		UserPullForm,
+		UpdateInfoForm
+	},
+	computed: {},
+	watch: {
+		'loading': {
+			handler(newVal) {
+				this.$refs.uploadComponent.changeLoading(newVal)
+			}
+		}
+	},
+	methods: {
+		init(id) {
+			this.inputForm = {
+				procInsId: '',
+				wareHouseTotalPrice: '', // 入库商品总价
+				wareHouseActualPrice: '', // 入库商品实际价格
+				tradeTotalPrice: '',  // 商品总价
+				fileInfoLost: [],
+				purchaseNo: '',
+				handledBy: this.$store.state.user.name,
+				handledById: this.$store.state.user.id,
+				handledByOffice: this.$store.state.user.office.id,
+				wareHouseName: '',
+				wareHouseNumber: '', // 入库编号
+				userId: this.$store.state.user.id,
+				wareHouseDate: new Date(),
+				remarks: '',
+				detailInfos: [],
+				wareHouse: [],
+				// amountInfos: [],
+				files: [], // 附件信息
+				functionFlag: ''
+			}
+			this.title = '入库修改历史详情'
+			this.inputForm.id = id
+			this.visible = true
+			this.loading = false
+			this.$nextTick(() => {
+				this.loading = true
+				this.$refs.inputForm.resetFields()
+				this.wareHouseService.findHiByHiId(this.inputForm.id, this.status).then((data) => {
+					this.$refs.uploadComponent.clearUpload()
+					if (this.commonJS.isNotEmpty(data.wareHouseManId)) {
+						this.wareHouseManId = data.wareHouseManId
+					}
+					if (this.commonJS.isNotEmpty(data.wareHouseTypeId)) {
+						this.wareHouseTypeId = data.wareHouseTypeId
+					}
+					this.inputForm = this.recover(this.inputForm, data)
+					this.inputForm = JSON.parse(JSON.stringify(this.inputForm))
+					if (this.commonJS.isNotEmpty(this.inputForm.detailInfos)) {
+						let i = this.inputForm.detailInfos.length
+						for (let j = 0; j < i; j++) {
+							if (this.commonJS.isNotEmpty(this.inputForm.detailInfos[j].tradePrice)) {
+								if (this.commonJS.isNotEmpty(this.inputForm.detailInfos[j].tradeNumber)) {
+									this.inputForm.detailInfos[j].priceSum = this.inputForm.detailInfos[j].tradePrice * this.inputForm.detailInfos[j].tradeNumber
+								}
+							}
+						}
+					}
+					if (this.commonJS.isNotEmpty(this.inputForm.wareHouse)) {
+						let k = this.inputForm.wareHouse.length
+						for (let j = 0; j < k; j++) {
+							if (this.commonJS.isNotEmpty(this.inputForm.wareHouse[j].tradePrice)) {
+								if (this.commonJS.isNotEmpty(this.inputForm.wareHouse[j].tradeNumber)) {
+									this.inputForm.wareHouse[j].priceSum = this.inputForm.wareHouse[j].tradePrice * this.inputForm.wareHouse[j].tradeNumber
+								}
+							}
+						}
+					}
+					this.$refs.uploadComponent.newUpload('view', this.inputForm.files, 'wareHouse')
+					this.loading = false
+					this.tableKey = Math.random()
+				})
+			})
+		},
+		getUpload(p, index) {
+			p.then((list) => {
+				// list为返回数据
+				this.inputForm.wareHouse[index].fileInfoLost = list
+				this.inputForm.wareHouse[index].fileNumber = list.length
+				this.tableKeyClient = Math.random()
+			})
+		},
+		close() {
+			this.inputForm = {
+				procInsId: '',
+				wareHouseTotalPrice: '',
+				wareHouseActualPrice: '',
+				tradeTotalPrice: '',
+				fileInfoLost: [],
+				purchaseNo: '',
+				handledBy: '',
+				handledById: '',
+				handledByOffice: '',
+				wareHouseName: '',
+				wareHouseNumber: '',
+				userId: '',
+				wareHouseDate: '',
+				remarks: '',
+				detailInfos: [],
+				wareHouse: [],
+				files: [],
+				functionFlag: ''
+			}
+			this.method = ''
+			this.inputForm.functionFlag = ''
+			this.inputForm.detailInfos = []
+			this.inputForm.wareHouse = []
+			this.inputForm.amountInfos = []
+			this.$refs.uploadComponent.clearUpload()
+			this.$refs.inputForm.resetFields()
+			this.visible = false
+		},
+		getProgram(rows) {
+			this.inputForm.detailInfos[this.indexRow].projectId = rows[0].id
+			this.inputForm.detailInfos[this.indexRow].projectName = rows[0].name
+			this.inputForm.detailInfos[this.indexRow].reportNumber = rows[0].reportNo
+			this.indexRow = ''
+			this.$forceUpdate()
+		},
+		getProgramForType(rows) {
+			this.inputForm.wareHouse[this.indexRow].wareHouseTypeId = rows.id
+			this.inputForm.wareHouse[this.indexRow].wareHouseType = rows.name
+			// this.inputForm.detailInfos[this.indexRow].procurementType = rows.name
+			this.indexRow = ''
+			this.$forceUpdate()
+		},
+		getProgramForUser(rows) {
+			this.inputForm.wareHouse[this.indexRow].wareHouseManId = rows[0].id
+			this.inputForm.wareHouse[this.indexRow].wareHouseMan = rows[0].name
+			this.inputForm.wareHouse[this.indexRow].deptId = rows[0].parentId
+			this.inputForm.wareHouse[this.indexRow].wareHouseManOffice = rows[0].officeName
+			this.indexRow = ''
+			this.$forceUpdate()
+		},
+		openContractForm() {
+			this.$refs.purchaseChooseForm.init()
+		},
+		getContract(row) {
+			this.materialManagementService.findById(row.id).then((data) => {
+				this.inputForm.detailInfos = data.detailInfos
+				this.inputForm.purchaseNo = data.purchaseNo
+				let i = this.inputForm.detailInfos.length
+				for (let j = 0; j < i; j++) {
+					if (this.commonJS.isNotEmpty(this.inputForm.detailInfos[j].tradePrice)) {
+						if (this.commonJS.isNotEmpty(this.inputForm.detailInfos[j].tradeNumber)) {
+							this.inputForm.detailInfos[j].priceSum = this.inputForm.detailInfos[j].tradePrice * this.inputForm.detailInfos[j].tradeNumber
+						}
+					}
+				}
+			})
+			this.$forceUpdate()
+		},
+		// 查看采购详情
+		async viewContract(purchaseNo) {
+			this.wareHouseService.findRequestId(purchaseNo).then((data) => {
+				this.$refs.updateInfoForm.init('view', data)
+			}).catch(() => {
+			})
+		},
+		footerMethod({ columns, data }) {
+			const footerData = [
+				columns.map((column, columnIndex) => {
+					if (columnIndex === 0) {
+						return '商品总价'
+					}
+					if (['priceSum'].includes(column.property)) {
+						// eslint-disable-next-line no-undef
+						this.inputForm.tradeTotalPrice = XEUtils.sum(data, column.property)
+						return XEUtils.sum(data, column.property)
+					}
+					return null
+				})
+			]
+			return footerData
+		},
+		footerMethod2({ columns, data }) {
+			const footerData = [
+				columns.map((column, columnIndex) => {
+					if (columnIndex === 0) {
+						return '商品总价'
+					}
+					if (['priceSum'].includes(column.property)) {
+						// eslint-disable-next-line no-undef
+						this.inputForm.wareHouseTotalPrice = XEUtils.sum(data, column.property)
+						return XEUtils.sum(data, column.property)
+					}
+					if (['actualPrice'].includes(column.property)) {
+						// eslint-disable-next-line no-undef
+						this.inputForm.wareHouseActualPrice = XEUtils.sum(data, column.property)
+						return XEUtils.sum(data, column.property)
+					}
+					return null
+				})
+			]
+			return footerData
+		},
+		seeFileInfo(index) {
+			if (this.commonJS.isEmpty(this.inputForm.detailInfos[index].fileInfoLost)) {
+				this.inputForm.detailInfos[index].fileInfoLost = []
+			}
+			this.$refs.materialManagementDialog.newUpload('view', this.inputForm.detailInfos[index].fileInfoLost, null, null, null, null, null, false, index)
+		},
+		seeFileInfo2(index) {
+			if (this.commonJS.isEmpty(this.inputForm.wareHouse[index].fileInfoLost)) {
+				this.inputForm.wareHouse[index].fileInfoLost = []
+			}
+			this.$refs.materialManagementDialog.newUpload('view', this.inputForm.wareHouse[index].fileInfoLost, null, null, null, null, null, false, index)
+		},
+		// 采购类型下拉弹窗
+		typePullForm(rowIndex) {
+			this.indexRow = rowIndex
+			this.$refs.materialTypePullForm.init()
+		},
+		// 列表行颜色
+		rowClassName({ row, rowIndex }) {
+			if (row.upFlag === '1') { // 修改前
+				return 'row-grey'
+			} else if (row.upFlag === '2') { // 已删除
+				return 'row-red'
+			} else if (row.upFlag === '0' && this.commonJS.isNotEmpty(row.sourceId)) { // 修改后
+				return 'row-green'
+			} else if (row.upFlag === '0' && this.commonJS.isEmpty(row.sourceId)) { // 未被修改过的数据
+				return ''
+			}
+		}
+	}
+}
+</script>
+<style scoped>
+.el-divider__text {
+	font-size: 16px;
+	font-weight: bold;
+}
+
+/deep/ .row-green {
+	/*background-color: #67c23ad1;*/
+	/*color: #fff;*/
+	font-weight: bold;
+}
+
+/deep/ .row-grey {
+	background-color: #b8b7b7;
+	color: #fff;
+}
+
+/deep/ .row-red {
+	background-color: #f56c6c66;
+	/*color: #fff;*/
+	font-weight: bold;
+}
+</style>

+ 510 - 0
src/views/psiManagement/wareHouse/WareHouseList.vue

@@ -0,0 +1,510 @@
+<template>
+	<div class="page">
+		<el-form :inline="true" v-if="searchVisible" class="query-form m-b-10" ref="searchForm" :model="searchForm"
+			@keyup.enter.native="refreshList()" @submit.native.prevent>
+			<!-- 搜索框-->
+			<el-form-item label="入库编号" prop="wareHouseNumber">
+				<el-input v-model="searchForm.wareHouseNumber" placeholder="请输入入库编号" clearable></el-input>
+			</el-form-item>
+			<el-form-item label="入库名称" prop="wareHouseName">
+				<el-input v-model="searchForm.wareHouseName" placeholder="请输入入库名称" clearable></el-input>
+			</el-form-item>
+			<el-form-item v-if="showHideItem" label="经办人" prop="handledBy">
+				<UserSelect :limit='1' :modelValue="searchForm.handledBy"
+					@update:modelValue='(value, label) => { searchForm.handledBy = value }'></UserSelect>
+			</el-form-item>
+			<el-form-item v-if="showHideItem" prop="handledByOffice" label="经办人部门">
+				<SelectTree ref="officeTree" :props="{
+					value: 'id',             // ID字段名
+					label: 'name',         // 显示名称
+					children: 'children'    // 子级字段名
+				}" :url="`/system-server/sys/office/treeData?type=2`" :value="searchForm.handledByOffice" size="default"
+					:accordion="true" @getValue="(value) => { searchForm.handledByOffice = value }" />
+			</el-form-item>
+			<el-form-item v-if="showHideItem" label="状态" prop="status">
+				<el-select v-model="searchForm.status" placeholder="请选择" style="width:100%;" clearable>
+					<el-option v-for="item in $dictUtils.getDictList('cw_status')" :key="item.value" :label="item.label"
+						:value="item.value">
+					</el-option>
+				</el-select>
+			</el-form-item>
+			<el-form-item v-if="showHideItem" label="入库时间" prop="wareHouseDates">
+				<el-date-picker placement="bottom-start" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
+					v-model="searchForm.wareHouseDates" type="datetimerange" range-separator="至"
+					start-placeholder="开始日期" end-placeholder="结束日期">
+				</el-date-picker>
+			</el-form-item>
+			<el-form-item v-if="showHideItem" label="供应商" prop="supplierName">
+				<el-input v-model="searchForm.supplierName" placeholder="请选择供应商" :readonly="true"
+					@focus="openSupplierChoose"></el-input>
+			</el-form-item>
+
+			<el-form-item>
+				<el-button type="default" @click="showHide" :icon="showHideIcon">{{ showHideName }}</el-button>
+				<el-button type="primary" @click="refreshList()" icon="el-icon-search">查询</el-button>
+				<el-button @click="resetSearch()" icon="el-icon-refresh-right">重置</el-button>
+			</el-form-item>
+		</el-form>
+		<div class="jp-table top" style="">
+			<vxe-toolbar :refresh="{ query: refreshList }" custom>
+				<template #buttons>
+					<el-button v-if="hasPermission('psi:add')" :disabled="isAdmin" type="primary" icon="el-icon-plus"
+						@click="add()">新建</el-button>
+					<el-button v-if="hasPermission('psi:list')" type="warning" icon="el-icon-download" plain
+						@click="exportFile()">导出</el-button>
+				</template>
+				<template #tools>
+					<vxe-button text type="primary" :title="searchVisible ? '收起检索' : '展开检索'" icon="vxe-icon-search"
+						class="tool-btn" @click="searchVisible = !searchVisible"></vxe-button>
+				</template>
+			</vxe-toolbar>
+			<div style="height: calc(100% - 90px)">
+				<vxe-table border="inner" auto-resize resizable height="auto" :loading="loading" ref="clientTable"
+					show-header-overflow show-overflow highlight-hover-row :menu-config="{}"
+					@sort-change="sortChangeHandle" :sort-config="{ remote: true }" :data="dataList"
+					:checkbox-config="{}">
+					<vxe-column type="seq" width="60" title="序号"></vxe-column>
+					<vxe-column min-width="160" align="center" title="入库编号" field="wareHouseNumber">
+						<template #default="scope">
+							<el-link type="primary" :underline="false" v-if="hasPermission('psi:list')"
+								@click="view(scope.row.id)">{{ scope.row.wareHouseNumber }}</el-link>
+							<el-link type="primary" :underline="false" v-else-if="hasPermission('psi:list')"
+								@click="view(scope.row.id,)">{{ scope.row.wareHouseNumber }}</el-link>
+							<span v-else>{{ scope.row.wareHouseNumber }}</span>
+						</template>
+					</vxe-column>
+					<vxe-column min-width="160" align="center" title="入库名称" field="wareHouseName"></vxe-column>
+					<vxe-column min-width="160" align="center" title="入库时间" field="wareHouseDate"></vxe-column>
+					<vxe-column min-width="160" align="center" title="经办人" field="handleByName"></vxe-column>
+					<vxe-column min-width="160" align="center" title="经办人部门" field="handledByOfficeName"></vxe-column>
+					<vxe-column min-width="130" align="center" title="修改申请状态" field="status" fixed="right">
+						<template #default="scope">
+							<el-button @click="detail(scope.row)" effect="dark"
+								:type="$dictUtils.getDictLabel('cw_status_flag', scope.row.status, '-')">
+								{{ $dictUtils.getDictLabel("cw_status", scope.row.status, '-') }}
+							</el-button>
+						</template>
+					</vxe-column>
+
+					<vxe-column title="操作" width="150px" fixed="right" align="center">
+						<template #default="scope">
+							<div v-if="isAdmin">
+								<!--                <el-button text type="primary"  @click="edit(scope.row.id)">修改</el-button>-->
+								<el-button text type="primary" size="small"
+									v-if="scope.row.status === '0' || scope.row.status === '5'"
+									@click="del(scope.row.id)">删除</el-button>
+							</div>
+							<div v-else>
+								<el-button
+									v-if="hasPermission('psi:wareHouse:edit') && scope.row.createBy === $store.state.user.id && (scope.row.status === '0' || scope.row.status === '5')"
+									text type="primary" size="small" @click="push(scope.row)">申请修改</el-button>
+								<!--              当前申请人撤回-->
+								<el-button
+									v-if="hasPermission('psi:wareHouse:edit') && scope.row.createBy === $store.state.user.id && scope.row.status === '2'"
+									text type="primary" size="small" @click="reback(scope.row)">撤回</el-button>
+								<!--              当前申请人撤回后->申请修改-->
+								<el-button
+									v-if="hasPermission('psi:wareHouse:edit') && scope.row.createBy === $store.state.user.id && scope.row.status === '3'"
+									text type="primary" size="small" @click="push(scope.row)">申请修改</el-button>
+								<!--              当前申请人撤回后->取消修改申请-->
+								<el-button
+									v-if="hasPermission('psi:wareHouse:edit') && scope.row.createBy === $store.state.user.id && scope.row.status === '3'"
+									text type="primary" size="small" @click="stopUpdate(scope.row.id)">取消修改</el-button>
+								<el-button v-if="scope.row.status === '2' && checkIsAudit(scope.row)" text
+									type="primary" size="small" @click="examine(scope.row)">审核</el-button>
+								<el-button
+									v-if="hasPermission('psi:wareHouse:edit') && scope.row.status === '4' && scope.row.createBy === $store.state.user.id"
+									text type="primary" size="small" @click="adjust(scope.row)">驳回调整</el-button>
+							</div>
+						</template>
+					</vxe-column>
+				</vxe-table>
+				<vxe-pager background :current-page="tablePage.currentPage" :page-size="tablePage.pageSize"
+					:total="tablePage.total" :page-sizes="[10, 20, 100, 1000, { label: '全量数据', value: 1000000 }]"
+					:layouts="['PrevPage', 'JumpNumber', 'NextPage', 'FullJump', 'Sizes', 'Total']"
+					@page-change="currentChangeHandle">
+				</vxe-pager>
+				<WareHouseAddForm ref="wareHouseAddForm" @refreshList="refreshList"></WareHouseAddForm>
+				<SupplierChooseForm ref="supplierChooseForm" @getSupplier="getSupplier"></SupplierChooseForm>
+			</div>
+		</div>
+	</div>
+</template>
+
+<script>
+import UserSelect from '@/components/userSelect'
+import WareHouseAddForm from './WareHouseAddForm'
+import SelectTree from '@/components/treeSelect/treeSelect.vue'
+import MaterialManagementService from '@/api/psi/MaterialManagementService'
+import WareHouseService from '@/api/psi/WareHouseService'
+import taskService from '@/api/flowable/taskService'
+import processService from '@/api/flowable/processService'
+import userService from '@/api/sys/userService'
+import pick from 'lodash.pick'
+import SupplierChooseForm from '@/views/psiManagement/supplier/SupplierChooseForm'
+export default {
+	data() {
+		return {
+			searchVisible: true,
+			showHideItem: false,
+			showHideIcon: 'el-icon-arrow-down',
+			showHideName: '展示',
+			num: 0,
+			searchForm: {
+				wareHouseName: '',
+				status: '',
+				wareHouseNumber: '',
+				handledBy: '',
+				handledByOffice: '',
+				wareHouseDates: [],
+				procurementType: '',
+				createBy: '',
+				supplierId: '',
+				supplierName: ''
+			},
+			dataList: [],
+			tablePage: {
+				total: 0,
+				currentPage: 1,
+				pageSize: 10,
+				orders: []
+			},
+			tableKey: '',
+			loading: false,
+			processDefinitionAuditId: '',
+			procDefAuditKey: '',
+			isAdmin: false,
+			create: ''
+		}
+	},
+	materialManagementService: null,
+	wareHouseService: null,
+	created() {
+		this.materialManagementService = new MaterialManagementService()
+		this.wareHouseService = new WareHouseService()
+	},
+	components: {
+		SelectTree,
+		WareHouseAddForm,
+		UserSelect,
+		SupplierChooseForm
+	},
+	computed: {
+		userName() {
+			return this.$store.state.user.name
+		},
+		user() {
+			this.createName = this.$store.state.user.name
+			return this.$store.state.user
+		}
+	},
+	mounted() {
+		this.refreshList()
+	},
+	activated() {
+		this.refreshList()
+	},
+	methods: {
+		showHide() {
+			if (this.showHideItem === false) {
+				this.showHideItem = true
+				this.showHideIcon = 'el-icon-arrow-up'
+				this.showHideName = '隐藏'
+			} else {
+				this.showHideItem = false
+				this.showHideIcon = 'el-icon-arrow-down'
+				this.showHideName = '展示'
+			}
+		},
+		// 新增
+		add() {
+			// this.$refs.reportManagementForm.init('add', '')
+			this.$refs.wareHouseAddForm.init('add', '')
+		},
+		// 修改
+		edit(id) {
+			id = id || this.$refs.clientTable.getCheckboxRecords().map(item => {
+				return item.id
+			})[0]
+			this.$refs.wareHouseAddForm.init('edit', id)
+		},
+		// 查看
+		view(id) {
+			this.$refs.wareHouseAddForm.init('view', id)
+		},
+		// 查询当前用户是否是管理员用户
+		checkIsAdmin() {
+			userService.is().then((data) => {
+				this.isAdmin = data
+			})
+		},
+		// 获取数据列表
+		refreshList() {
+			this.loading = true
+			this.wareHouseService.wareHouseList({
+				'current': this.tablePage.currentPage,
+				'size': this.tablePage.pageSize,
+				'orders': this.tablePage.orders,
+				...this.searchForm
+			}).then((data) => {
+				this.dataList = data.records
+				this.tablePage.total = data.total
+				this.tableKey = Math.random()
+				this.loading = false
+			})
+			// this.materialManagementService.list({
+			//   'current': this.tablePage.currentPage,
+			//   'size': this.tablePage.pageSize,
+			//   'orders': this.tablePage.orders,
+			//   ...this.searchForm
+			// }).then((data) => {
+			//   this.dataList = data.records
+			//   this.tablePage.total = data.total
+			//   this.tableKey = Math.random()
+			//   this.loading = false
+			// })
+			this.checkIsAdmin()
+			processService.getByName('进销存-入库修改').then((data) => {
+				if (!this.commonJS.isEmpty(data.id)) {
+					this.processDefinitionAuditId = data.id
+					this.procDefAuditKey = data.key
+				}
+			})
+		},
+		// 当前页
+		currentChangeHandle({ currentPage, pageSize }) {
+			this.tablePage.currentPage = currentPage
+			this.tablePage.pageSize = pageSize
+			this.refreshList()
+		},
+		// 排序
+		sortChangeHandle(column) {
+			this.tablePage.orders = []
+			if (column.order != null) {
+				this.tablePage.orders.push({ column: this.$utils.toLine(column.property), asc: column.order === 'asc' })
+			}
+			this.refreshList()
+		},
+		// 删除
+		del(id) {
+			let ids = id || this.$refs.clientTable.getCheckboxRecords().map(item => {
+				return item.id
+			}).join(',')
+			this.$confirm(`确定删除所选项吗?`, '提示', {
+				confirmButtonText: '确定',
+				cancelButtonText: '取消',
+				type: 'warning'
+			}).then(() => {
+				this.loading = true
+				this.wareHouseService.remove(ids).then((data) => {
+					this.$message.success(data)
+					this.refreshList()
+					this.loading = false
+				})
+			})
+		},
+		resetSearch() {
+			this.$refs.searchForm.resetFields()
+			this.searchForm.supplierId = '' // 重置时清空供应商筛选
+			this.refreshList()
+		},
+		// 发起进销存-入库修改
+		push(row) {
+			this.wareHouseService.findById(row.id).then((data) => {
+				if (data.status !== row.status) { // status的值不等于“审核中”,就弹出提示
+					this.$message.error('数据已发生改变或不存在,请刷新数据')
+					this.refreshList()
+				} else {
+					// 读取流程表单
+					let title = `发起流程【入库修改】`
+					let processTitle = `${this.userName} 在 ${this.moment(new Date()).format('YYYY-MM-DD HH:mm')} 发起了[入库修改]`
+					let status = 'startAndClose'
+					if (row.status === '3') {
+						status = 'startAndClose'
+					} else if (row.status === '4') {
+						status = 'reapplyFlag'
+					}
+					taskService.getTaskDef({
+						procDefId: this.processDefinitionAuditId,
+						businessId: row.id,
+						businessTable: 'psi_management_warehouse_basics'
+					}).then((data) => {
+						this.$router.push({
+							path: '/flowable/task/TaskForm',
+							query: {
+								...pick(data, 'formType', 'formUrl', 'procDefKey', 'taskDefKey', 'procInsId', 'procDefId', 'taskId', 'status', 'title'),
+								procDefId: this.processDefinitionAuditId,
+								procDefKey: this.procDefAuditKey,
+								title: title,
+								formType: data.formType,
+								formUrl: data.formUrl,
+								formTitle: processTitle,
+								businessTable: 'psi_management_warehouse_basics',
+								businessId: row.id,
+								isShow: 'false',
+								status: status,
+								routePath: '/psiManagement/wareHouse/WareHouseList',
+								wareHouseId: row.id
+							}
+						})
+					})
+				}
+			})
+		},
+		// 查看修改流程结果
+		detail(row) {
+			if (row.status !== '0' && row.status !== '1') {
+				// eslint-disable-next-line eqeqeq
+				taskService.getTaskDef({
+					procInsId: row.procInsId,
+					procDefId: this.processDefinitionAuditId
+				}).then((data) => {
+					this.$router.push({
+						path: '/flowable/task/TaskFormDetail',
+						query: {
+							...pick(data, 'formType', 'formUrl', 'procDefKey', 'taskDefKey', 'procInsId', 'procDefId', 'taskId', 'status', 'title'),
+							isShow: 'false',
+							readOnly: true,
+							title: '入库修改' + '流程详情',
+							formTitle: '入库修改' + '流程详情',
+							businessId: row.id,
+							status: 'reback',
+							wareHouseId: row.id
+						}
+					})
+				})
+			}
+		},
+		// 撤回入库修改
+		reback(row) {
+			this.$confirm(`确定要撤回该申请吗?`, '提示', {
+				confirmButtonText: '确定',
+				cancelButtonText: '取消',
+				type: 'warning'
+			}).then(() => {
+				this.wareHouseService.findById(row.id).then((data) => {
+					if (data.status !== '2') { // status的值不等于“审核中”,就弹出提示
+						this.$message.error('数据已发生改变或不存在,请刷新数据')
+						this.refreshList()
+					} else {
+						processService.revokeProcIns(row.procInsId).then((data) => {
+							let form = { status: '3', id: row.id }
+							this.wareHouseService.updateStatusById(form)
+							this.$message.success(data)
+							this.refreshList()
+						})
+					}
+				})
+			})
+		},
+		stopUpdate(id) {
+			this.wareHouseService.findById(id).then((data) => {
+				if (data.status !== '3') { // status的值不等于“撤回”,就弹出提示
+					this.$message.error('数据已发生改变或不存在,请刷新数据')
+					this.refreshList()
+				} else {
+					this.$confirm(`确定要取消修改申请吗?`, '提示', {
+						confirmButtonText: '确定',
+						cancelButtonText: '取消',
+						type: 'warning'
+					}).then(() => {
+						this.wareHouseService.backSourceData(id).then((data) => {
+							if (data.result === 'success') {
+								this.$message.success('取消修改申请成功')
+							} else {
+								this.$message.error('取消修改申请失败')
+							}
+							this.refreshList()
+						}).catch(() => {
+							this.refreshList()
+						})
+					})
+				}
+			})
+		},
+		// 驳回后调整
+		adjust(row) {
+			this.wareHouseService.findById(row.id).then((data) => {
+				if (data.status !== '4') { // status的值不等于“驳回”,就弹出提示
+					this.$message.error('数据已发生改变或不存在,请刷新数据')
+					this.refreshList()
+				} else {
+					this.todo(row)
+				}
+			})
+		},
+		// 审核
+		examine(row) {
+			this.wareHouseService.findById(row.id).then((data) => {
+				if (data.status !== '2') { // status的值不等于“审核中”,就弹出提示
+					this.$message.error('数据已发生改变或不存在,请刷新数据')
+					this.refreshList()
+				} else {
+					this.todo(row)
+				}
+			})
+		},
+		// 审核或重新调整跳转
+		todo(row) {
+			let cUser = false
+			taskService.getTaskDefInfo({
+				taskId: row.taskId
+			}).then((data) => {
+				this.$router.push({
+					path: '/flowable/task/TaskForm',
+					query: {
+						...pick(data, 'formType', 'formUrl', 'procDefKey', 'taskDefKey', 'procInsId', 'procDefId', 'taskId', 'status', 'title', 'businessId'),
+						isShow: false,
+						formReadOnly: true,
+						formTitle: `${data.taskName}`,
+						cUser: cUser,
+						title: `审批【${data.taskName || ''}】`,
+						routePath: '/materialManagement/wareHouse/WareHouseList',   // 数据处理后需要跳转的页面路径
+						wareHouseId: row.id
+					}
+				})
+			})
+		},
+		// 查询当前登录人是否是数据的审核人
+		checkIsAudit(row) {
+			let loginUserId = this.$store.state.user.id  // 获取当前登录用户id
+			if (this.commonJS.isNotEmpty(row.auditUserIds)) {
+				for (const userId of row.auditUserIds) {
+					if (userId === loginUserId) {  // 当数据的审核人中包含当前登录人id时,返回true
+						return true
+					}
+				}
+			}
+			return false
+		},
+		getSupplier(row) {
+			this.searchForm.supplierId = row.id
+			this.searchForm.supplierName = row.name
+		},
+		// 打开供应商选择组件
+		openSupplierChoose() {
+			this.$refs.supplierChooseForm.init()
+		},
+		exportFile() {
+			const options = {
+				filename: `${this.moment(new Date()).format('YYYY-MM-DD')}入库申请数据导出`,
+				sheetName: '入库申请数据导出',
+				mode: 'all'
+			}
+			this.loading = true
+			this.wareHouseService.exportFile({
+				current: this.tablePage.currentPage,
+				size: this.tablePage.pageSize,
+				orders: this.tablePage.orders,
+				...options,
+				...this.searchForm
+			}).then((res) => {
+				this.$utils.downloadExcel(res, options.filename)
+				this.loading = false
+			}).catch(() => {
+				this.loading = false
+			})
+		}
+	}
+}
+</script>

Datei-Diff unterdrückt, da er zu groß ist
+ 1180 - 0
src/views/psiManagement/wareHouse/WareHouseUpdateForm.vue


+ 100 - 0
src/views/psiManagement/wareHouseSummary/EditTradeNameForm.vue

@@ -0,0 +1,100 @@
+<template>
+	<div>
+		<el-dialog title="修改商品名称" :close-on-click-modal="false" draggable width="500px" @close="close" append-to-body
+			v-model="visible">
+			<div style="height: calc(100% - 80px);">
+				<el-form style="margin-top: 30px" ref="inputForm" :model="inputForm" @submit.native.prevent>
+					<!-- 搜索框-->
+					<el-row :gutter="26">
+						<el-col :span="24">
+							<el-form-item prop="tradeName" :rules="[
+								{ required: true, message: '商品名称不能为空', trigger: 'blur' }
+							]">
+								<el-input v-model="inputForm.tradeName" placeholder="请输入商品名称"></el-input>
+							</el-form-item>
+						</el-col>
+					</el-row>
+
+				</el-form>
+			</div>
+			<template #footer>
+				<span class="dialog-footer">
+					<el-button @click="close()" icon="el-icon-circle-close">关闭</el-button>
+					<el-button type="primary" @click="submit()" icon="el-icon-circle-check" v-noMoreClick>确定</el-button>
+				</span>
+			</template>
+		</el-dialog>
+	</div>
+</template>
+
+<script>
+import WareHouseService from '@/api/psi/WareHouseService'
+export default {
+	data() {
+		return {
+			title: '',
+			method: '',
+			visible: false,
+			loading: false,
+			dataList: [],
+			inputForm: {
+				tradeName: ''
+			},
+			oldTradeName: '',
+			type: '',
+			typeName: ''
+		}
+	},
+	wareHouseService: null,
+	created() {
+		this.wareHouseService = new WareHouseService()
+	},
+	components: {
+	},
+	methods: {
+		init(tradeName, type, typeName) {
+			this.visible = true
+			this.inputForm.tradeName = tradeName
+			this.type = type
+			this.typeName = typeName
+			this.oldTradeName = tradeName
+		},
+		// 表单提交
+		submit() {
+			this.$refs['inputForm'].validate((valid) => {
+				if (valid) {
+					this.$confirm('确定将 [' + this.typeName + '] 商品 ”' + this.oldTradeName + '“ 全部改为 ”' + this.inputForm.tradeName + '“ 吗?', '提示', {
+						confirmButtonText: '确定',
+						cancelButtonText: '取消',
+						type: 'warning'
+					}).then(() => {
+						this.loading = true
+						this.wareHouseService.saveTradeName(this.oldTradeName, this.inputForm.tradeName, this.type).then(({ data }) => {
+							this.$message.success(data)
+							this.close()
+							this.$emit('refreshList')
+							this.loading = false
+						}).catch(() => {
+							this.$refs.inputForm.resetFields()
+							this.loading = false
+						})
+					})
+				}
+			})
+		},
+		close() {
+			this.$refs.inputForm.resetFields()
+			this.inputForm = {
+				tradeName: ''
+			}
+			this.visible = false
+		}
+	}
+}
+</script>
+<style scoped>
+/deep/ .el-dialog__body {
+	padding-top: 0px;
+	padding-bottom: 15px;
+}
+</style>

+ 294 - 0
src/views/psiManagement/wareHouseSummary/WareHouseHistory.vue

@@ -0,0 +1,294 @@
+<template>
+	<div>
+		<el-dialog title="记录" :close-on-click-modal="false" draggable width="1300px" height="500px" @close="close"
+			append-to-body v-model="visible">
+			<el-tabs v-model="activeNameTop" type="border-card" @tab-click="tabHandleClickTop">
+				<el-tab-pane label="入库记录" name="wareHouse">
+					<div style="height: calc(100% - 80px);">
+						<el-form :inline="true" class="query-form" ref="searchForm" :model="searchForm"
+							@keyup.enter.native="refreshList()" @submit.native.prevent>
+							<!-- 搜索框-->
+							<el-form-item label="入库编号" prop="wareHouseNumber">
+								<el-input v-model="searchForm.wareHouseNumber" placeholder="请输入入库编号"
+									clearable></el-input>
+							</el-form-item>
+							<el-form-item label="入库时间" prop="wareHouseDates">
+								<el-date-picker placement="bottom-start" format="YYYY-MM-DD HH:mm:ss"
+									value-format="YYYY-MM-DD HH:mm:ss" v-model="searchForm.wareHouseDates"
+									type="datetimerange" range-separator="至" start-placeholder="开始日期"
+									end-placeholder="结束日期">
+								</el-date-picker>
+							</el-form-item>
+
+							<el-form-item>
+								<el-button type="primary" @click="list()" icon="el-icon-search">查询</el-button>
+								<el-button @click="resetSearch()" icon="el-icon-refresh-right">重置</el-button>
+							</el-form-item>
+						</el-form>
+						<vxe-table border="inner" auto-resize resizable height="400px" :loading="loading"
+							ref="projectTable" show-header-overflow show-overflow highlight-hover-row :menu-config="{}"
+							:print-config="{}" :sort-config="{ remote: true }" :data="dataList"
+							:row-config="{ isCurrent: true }" :radio-config="{ trigger: 'row' }">
+							<!--              <vxe-column type="seq" width="60" title="序号"></vxe-column>-->
+							<vxe-column min-width="160" align="center" title="入库编号"
+								field="wareHouseNumber"></vxe-column>
+							<vxe-column min-width="160" align="center" title="入库名称" field="wareHouseName">
+								<template #default="scope">
+									<el-link type="primary" :underline="false" v-if="hasPermission('psi:list')"
+										@click="view(scope.row.wareHouseId)">{{ scope.row.wareHouseName }}</el-link>
+									<el-link type="primary" :underline="false" v-else-if="hasPermission('psi:list')"
+										@click="view(scope.row.wareHouseId,)">{{ scope.row.wareHouseName }}</el-link>
+									<span v-else>{{ scope.row.wareHouseName }}</span>
+								</template>
+							</vxe-column>
+							<vxe-column min-width="160" align="center" title="入库数量" field="tradeNumber"></vxe-column>
+							<vxe-column min-width="160" align="center" title="当前库存"
+								field="currentInventory"></vxe-column>
+							<vxe-column min-width="160" align="center" title="生产日期" field="produceDate"></vxe-column>
+							<vxe-column min-width="160" align="center" title="保质期" field="shelfLife">
+								<template #default="scope">
+									<span v-if="scope.row.shelfLife && scope.row.shelfLifeUnit">
+										{{ scope.row.shelfLife }} {{ scope.row.shelfLifeUnit }}
+									</span>
+								</template>
+							</vxe-column>
+							<vxe-column min-width="160" align="center" title="到期时间" field="expireDate">
+								<!-- 需要写个方法,根据生产日期和保质期计算 -->
+								<template #default="scope">
+									<span
+										v-if="scope.row.produceDate && scope.row.shelfLife && scope.row.shelfLifeUnit">
+										{{ calculateExpireDate(scope.row.produceDate, scope.row.shelfLife,
+											scope.row.shelfLifeUnit) }}
+									</span>
+								</template>
+							</vxe-column>
+							<vxe-column min-width="160" align="center" title="经办人"
+								field="wareHouseHandledBy"></vxe-column>
+							<vxe-column min-width="160" align="center" title="经办人部门"
+								field="wareHouseHandledByOff"></vxe-column>
+							<vxe-column min-width="160" align="center" title="入库时间" field="wareHouseDate"></vxe-column>
+
+						</vxe-table>
+						<vxe-pager background :current-page="tablePage.currentPage" :page-size="tablePage.pageSize"
+							:total="tablePage.total"
+							:page-sizes="[10, 20, 100, 1000, { label: '全量数据', value: 1000000 }]"
+							:layouts="['PrevPage', 'JumpNumber', 'NextPage', 'FullJump', 'Sizes', 'Total']"
+							@page-change="currentChangeHandle">
+						</vxe-pager>
+					</div>
+				</el-tab-pane>
+				<el-tab-pane label="领用记录" name="collect">
+					<div style="height: calc(100% - 80px);">
+						<el-form :inline="true" class="query-form" ref="searchForm2" :model="searchForm2"
+							@keyup.enter.native="refreshList()" @submit.native.prevent>
+							<!-- 搜索框-->
+							<el-form-item label="领用编号" prop="collectNo">
+								<el-input v-model="searchForm2.collectNo" placeholder="请输入领用编号" clearable></el-input>
+							</el-form-item>
+							<el-form-item label="领用时间" prop="collectDates">
+								<el-date-picker placement="bottom-start" format="YYYY-MM-DD HH:mm:ss"
+									value-format="YYYY-MM-DD HH:mm:ss" v-model="searchForm2.collectDates"
+									type="datetimerange" range-separator="至" start-placeholder="开始日期"
+									end-placeholder="结束日期">
+								</el-date-picker>
+							</el-form-item>
+
+							<el-form-item>
+								<el-button type="primary" @click="list2()" icon="el-icon-search">查询</el-button>
+								<el-button @click="resetSearch2()" icon="el-icon-refresh-right">重置</el-button>
+							</el-form-item>
+						</el-form>
+						<vxe-table border="inner" auto-resize resizable height="400px" :loading="loading"
+							ref="projectTable" show-header-overflow show-overflow highlight-hover-row :menu-config="{}"
+							:print-config="{}" :sort-config="{ remote: true }" :data="collectList"
+							:row-config="{ isCurrent: true }" :radio-config="{ trigger: 'row' }">
+							<!--              <vxe-column type="seq" width="60" title="序号"></vxe-column>-->
+							<vxe-column min-width="160" align="center" title="领用编号" field="collectNo"></vxe-column>
+							<vxe-column min-width="160" align="center" title="领用物品名称" field="goodsName">
+								<template #default="scope">
+									<el-link type="primary" :underline="false" v-if="hasPermission('psi:list')"
+										@click="view2(scope.row.collectId)">{{ scope.row.goodsName }}</el-link>
+									<el-link type="primary" :underline="false" v-else-if="hasPermission('psi:list')"
+										@click="view2(scope.row.collectId,)">{{ scope.row.goodsName }}</el-link>
+									<span v-else>{{ scope.row.goodsName }}</span>
+								</template>
+							</vxe-column>
+							<vxe-column min-width="160" align="center" title="领用数量" field="collectNumber"></vxe-column>
+							<vxe-column min-width="160" align="center" title="当前库存"
+								field="currentInventory"></vxe-column>
+							<vxe-column min-width="160" align="center" title="经办人" field="collectHandleBy"></vxe-column>
+							<vxe-column min-width="160" align="center" title="经办人部门"
+								field="collectHandleByOff"></vxe-column>
+							<vxe-column min-width="160" align="center" title="领用时间" field="collectDate"></vxe-column>
+
+						</vxe-table>
+						<vxe-pager background :current-page="tablePage2.currentPage" :page-size="tablePage2.pageSize"
+							:total="tablePage2.total"
+							:page-sizes="[10, 20, 100, 1000, { label: '全量数据', value: 1000000 }]"
+							:layouts="['PrevPage', 'JumpNumber', 'NextPage', 'FullJump', 'Sizes', 'Total']"
+							@page-change="currentChangeHandle2">
+						</vxe-pager>
+					</div>
+				</el-tab-pane>
+			</el-tabs>
+			<template #footer>
+				<span class="dialog-footer">
+					<el-button @click="close()" icon="el-icon-circle-close">关闭</el-button>
+				</span>
+			</template>
+		</el-dialog>
+		<WareHouseAddForm ref="wareHouseAddForm"></WareHouseAddForm>
+		<UpdateCollectInfoForm ref="updateCollectInfoForm"></UpdateCollectInfoForm>
+	</div>
+</template>
+
+<script>
+import WareHouseAddForm from '../wareHouse/WareHouseAddForm'
+// import ProjectRecordsService from '@/api/cw/projectRecords/ProjectRecordsService'
+import WareHouseService from '@/api/psi/WareHouseService'
+import UpdateCollectInfoForm from '../collect/UpdateCollectInfoForm'
+export default {
+	data() {
+		return {
+			title: '',
+			method: '',
+			visible: false,
+			loading: false,
+			tablePage: {
+				total: 0,
+				currentPage: 1,
+				pageSize: 10,
+				orders: []
+			},
+			tablePage2: {
+				total: 0,
+				currentPage: 1,
+				pageSize: 10,
+				orders: []
+			},
+			tableKey: '',
+			dataList: [],
+			collectList: [],
+			searchForm: {
+				tradeName: '',
+				wareHouseNumber: '',
+				wareHouseDates: []
+			},
+			searchForm2: {
+				tradeName: '',
+				collectNo: '',
+				collectDates: []
+			},
+			activeNameTop: 'wareHouse',
+			detailId: ''
+		}
+	},
+	// projectRecordsService: null,
+	wareHouseService: null,
+	created() {
+		// this.projectRecordsService = new ProjectRecordsService()
+		this.wareHouseService = new WareHouseService()
+	},
+	components: {
+		WareHouseAddForm,
+		UpdateCollectInfoForm
+	},
+	methods: {
+		// 查看
+		view(id) {
+			this.$refs.wareHouseAddForm.init('view', id)
+		},
+		// 查看2
+		view2(id) {
+			this.$refs.updateCollectInfoForm.init('view', id)
+		},
+		init(tradeName, detailId) {
+			this.activeNameTop = 'wareHouse'
+			this.visible = true
+			this.searchForm.tradeName = tradeName
+			this.searchForm2.tradeName = tradeName
+			if (this.commonJS.isNotEmpty(detailId)) {
+				this.detailId = detailId
+			} else {
+				this.detailId = ''
+			}
+			this.list()
+			this.list2()
+		},
+		list() {
+			this.loading = true
+			// this.searchForm.createId = this.$store.state.user.id
+			this.wareHouseService.wareHouseHistoryList({
+				'detailId': this.detailId,
+				...this.searchForm
+			}).then((data) => {
+				this.dataList = data.records
+				// this.collectList = data.collectList
+				this.tablePage.total = data.total
+				this.tableKey = Math.random()
+				this.loading = false
+			})
+		},
+		list2() {
+			this.wareHouseService.collectHistoryList({
+				...this.searchForm2
+			}).then((data) => {
+				this.collectList = data.records
+				// this.collectList = data.collectList
+				this.tablePage2.total = data.total
+				this.tableKey = Math.random()
+				this.loading = false
+			})
+		},
+		// 当前页
+		currentChangeHandle({ currentPage, pageSize }) {
+			this.tablePage.currentPage = currentPage
+			this.tablePage.pageSize = pageSize
+			this.list()
+		},
+		currentChangeHandle2({ currentPage, pageSize }) {
+			this.tablePage2.currentPage = currentPage
+			this.tablePage2.pageSize = pageSize
+			this.list2()
+		},
+		resetSearch() {
+			this.$refs.searchForm.resetFields()
+			this.list()
+		},
+		resetSearch2() {
+			this.$refs.searchForm2.resetFields()
+			this.list2()
+		},
+		close() {
+			this.visible = false
+			this.$refs.searchForm.resetFields()
+			this.$refs.searchForm2.resetFields()
+		},
+		tabHandleClickTop(event) {
+			// console.log(event)
+		},
+		// 计算到期时间
+		calculateExpireDate(produceDate, shelfLife, shelfLifeUnit) {
+			if (!produceDate || !shelfLife || !shelfLifeUnit) {
+				return ''
+			}
+			const produce = new Date(produceDate)
+			let expire = new Date(produce)
+			if (shelfLifeUnit === '年') {
+				expire.setFullYear(expire.getFullYear() + parseInt(shelfLife))
+			} else if (shelfLifeUnit === '月') {
+				expire.setMonth(expire.getMonth() + parseInt(shelfLife))
+			} else if (shelfLifeUnit === '天') {
+				expire.setDate(expire.getDate() + parseInt(shelfLife))
+			}
+			return expire.toISOString().split('T')[0]
+		}
+	}
+}
+</script>
+<style scoped>
+/deep/ .el-dialog__body {
+	padding-top: 0px;
+	padding-bottom: 15px;
+}
+</style>

+ 160 - 0
src/views/psiManagement/wareHouseSummary/WareHouseHistoryPopup.vue

@@ -0,0 +1,160 @@
+<template>
+	<div>
+		<el-dialog title="库存信息" :close-on-click-modal="false" draggable width="1100px" height="500px" @close="close"
+			append-to-body v-model="visible">
+			<div style="height: calc(100% - 80px);">
+				<el-form :inline="true" class="query-form" ref="searchForm" :model="searchForm" @submit.native.prevent>
+					<!-- 搜索框-->
+					<el-form-item label="商品名称" prop="tradeName">
+						<el-input v-model="searchForm.tradeName" placeholder="请输入商品名称" clearable></el-input>
+					</el-form-item>
+					<el-form-item label="入库类型" prop="wareHouseType">
+						<SelectTree ref="areaTree" :props="{
+							value: 'id',             // ID字段名
+							label: 'name',         // 显示名称
+							children: 'children'    // 子级字段名
+						}" url="/psi-management-server/psi/materialType/summaryTreeData?type=last" :value="searchForm.wareHouseType"
+							:clearable="true" :accordion="true" size="default"
+							@getValue="(value, label) => { searchForm.wareHouseType = value }" />
+					</el-form-item>
+
+					<el-form-item>
+						<el-button type="primary" @click="refreshList()" icon="el-icon-search">查询</el-button>
+						<el-button @click="resetSearch()" icon="el-icon-refresh-right">重置</el-button>
+					</el-form-item>
+				</el-form>
+
+				<vxe-table border="inner" auto-resize resizable height="400px" :loading="loading" ref="projectTable"
+					show-header-overflow show-overflow highlight-hover-row :menu-config="{}" :print-config="{}"
+					:sort-config="{ remote: true }" :data="dataList" :row-config="{ isCurrent: true }"
+					:radio-config="{ trigger: 'row' }">
+					<vxe-column type="seq" width="60" title="序号"></vxe-column>
+					<vxe-column min-width="160" align="center" title="入库类型" field="wareHouseTypeName"></vxe-column>
+					<vxe-column min-width="160" align="center" title="商品名称" field="tradeName">
+						<template #default="scope">
+							<el-link type="primary" :underline="false" v-if="hasPermission('psi:list')"
+								@click="view(scope.row.tradeName)">{{ scope.row.tradeName }}</el-link>
+							<el-link type="primary" :underline="false" v-else-if="hasPermission('psi:list')"
+								@click="view(scope.row.tradeName,)">{{ scope.row.tradeName }}</el-link>
+							<span v-else>{{ scope.row.tradeName }}</span>
+						</template>
+					</vxe-column>
+					<vxe-column min-width="160" align="center" title="总量" field="allNumber"></vxe-column>
+					<vxe-column min-width="160" align="center" title="领用量" field="borrowNumber"></vxe-column>
+					<vxe-column min-width="160" align="center" title="剩余量" field="tradeNumber"></vxe-column>
+					<vxe-column min-width="160" align="center" title="单位" field="company"></vxe-column>
+
+				</vxe-table>
+				<vxe-pager background :current-page="tablePage.currentPage" :page-size="tablePage.pageSize"
+					:total="tablePage.total" :page-sizes="[10, 20, 100, 1000, { label: '全量数据', value: 1000000 }]"
+					:layouts="['PrevPage', 'JumpNumber', 'NextPage', 'FullJump', 'Sizes', 'Total']"
+					@page-change="currentChangeHandle">
+				</vxe-pager>
+			</div>
+			<template #footer>
+				<span class="dialog-footer">
+					<el-button @click="close()" icon="el-icon-circle-close">关闭</el-button>
+				</span>
+			</template>
+		</el-dialog>
+		<WareHouseHistory ref="wareHouseHistory"></WareHouseHistory>
+	</div>
+</template>
+
+<script>
+import SelectTree from '@/components/treeSelect/treeSelect.vue'
+import WareHouseHistory from './WareHouseHistory'
+// import CollectService from '@/api/materialManagement/CollectService'
+import WareHouseService from '@/api/psi/WareHouseService'
+export default {
+	data() {
+		return {
+			visible: false,
+			num: 0,
+			searchForm: {
+				wareHouseType: '',
+				tradeName: '',
+				wareHouseNumber: '',
+				wareHouseMan: '',
+				wareHouseManOffice: '',
+				wareHouseDates: [],
+				procurementType: '',
+				createBy: ''
+			},
+			basicId: '',
+			dataList: [],
+			tablePage: {
+				total: 0,
+				currentPage: 1,
+				pageSize: 10,
+				orders: []
+			},
+			tableKey: '',
+			loading: false,
+			processDefinitionAuditId: '',
+			procDefAuditKey: '',
+			isAdmin: false,
+			create: ''
+		}
+	},
+	// collectService: null,
+	wareHouseService: null,
+	created() {
+		// this.collectService = new CollectService()
+		this.wareHouseService = new WareHouseService()
+	},
+	components: {
+		SelectTree,
+		WareHouseHistory,
+	},
+	methods: {
+		init(basicId) {
+			console.log('basicId', basicId)
+			this.visible = true
+			this.basicId = basicId
+			this.refreshList()
+		},
+		// 获取数据列表
+		refreshList() {
+			this.searchForm.basicId = this.basicId
+			this.loading = true
+			this.wareHouseService.wareHouseSummaryList2({
+				'current': this.tablePage.currentPage,
+				'size': this.tablePage.pageSize,
+				'orders': this.tablePage.orders,
+				...this.searchForm
+			}).then((data) => {
+				this.dataList = data.records
+				this.tablePage.total = data.total
+				this.tableKey = Math.random()
+				this.loading = false
+			})
+		},
+		// 当前页
+		currentChangeHandle({ currentPage, pageSize }) {
+			this.tablePage.currentPage = currentPage
+			this.tablePage.pageSize = pageSize
+			this.refreshList()
+		},
+		resetSearch() {
+			this.$refs.searchForm.resetFields()
+			this.refreshList()
+		},
+		close() {
+			this.$refs.searchForm.resetFields()
+			this.visible = false
+			this.typeTest = ''
+		},
+		// 查看
+		view(tradeName) {
+			this.$refs.wareHouseHistory.init(tradeName)
+		}
+	}
+}
+</script>
+<style scoped>
+/deep/ .el-dialog__body {
+	padding-top: 0px;
+	padding-bottom: 15px;
+}
+</style>

+ 313 - 0
src/views/psiManagement/wareHouseSummary/WareHouseSummaryList.vue

@@ -0,0 +1,313 @@
+<template>
+	<div class="page">
+		<el-form :inline="true" v-if="searchVisible" class="query-form m-b-10" ref="searchForm" :model="searchForm"
+			@keyup.enter.native="refreshList()" @submit.native.prevent>
+			<!-- 搜索框-->
+			<!--      <el-form-item label="入库编号" prop="wareHouseNumber">-->
+			<!--        <el-input size="small" v-model="searchForm.wareHouseNumber" placeholder="请输入入库编号" clearable></el-input>-->
+			<!--      </el-form-item>-->
+			<el-form-item label="商品名称" prop="tradeName">
+				<el-input v-model="searchForm.tradeName" placeholder="请输入商品名称" clearable></el-input>
+			</el-form-item>
+			<el-form-item label="入库类型" prop="wareHouseType">
+				<SelectTree ref="areaTree" :props="{
+					value: 'id',             // ID字段名
+					label: 'name',         // 显示名称
+					children: 'children'    // 子级字段名
+				}" url="/psi-management-server/psi/materialType/summaryTreeData?type=last" :value="searchForm.wareHouseType"
+					:clearable="true" :accordion="true" size="default"
+					@getValue="(value, label) => { searchForm.wareHouseType = value }" />
+			</el-form-item>
+			<el-form-item label="供应商" prop="supplierName">
+				<el-input v-model="searchForm.supplierName" placeholder="请选择供应商" :readonly="true"
+					@focus="openSupplierChoose"></el-input>
+			</el-form-item>
+			<el-form-item>
+				<el-button type="primary" @click="refreshList()" icon="el-icon-search">查询</el-button>
+				<el-button @click="resetSearch()" icon="el-icon-refresh-right">重置</el-button>
+			</el-form-item>
+		</el-form>
+		<div class="jp-table top" style="">
+			<vxe-toolbar :refresh="{ query: refreshList }" custom>
+				<template #buttons>
+					<el-button v-if="hasPermission('psi:summary:list')" type="warning" icon="el-icon-download" plain
+						@click="exportFile()">导出</el-button>
+				</template>
+				<template #tools>
+					<vxe-button text type="primary" :title="searchVisible ? '收起检索' : '展开检索'" icon="vxe-icon-search"
+						class="tool-btn" @click="searchVisible = !searchVisible"></vxe-button>
+				</template>
+			</vxe-toolbar>
+			<div style="height: calc(100% - 90px)">
+				<vxe-table :key="tableKey" border="inner" auto-resize resizable height="auto" :loading="loading"
+					ref="clientTable" show-header-overflow show-overflow highlight-hover-row :menu-config="{}"
+					@sort-change="sortChangeHandle" :sort-config="{ remote: true }" :data="dataList"
+					:checkbox-config="{}"
+					:edit-config="{ trigger: 'click', mode: 'row', showStatus: false, autoClear: true, icon: 'false' }">
+					<vxe-column type="seq" width="60" title="序号"></vxe-column>
+					<!--          <vxe-column min-width="160" align="center" title="入库编号" field="wareHouseNumber"></vxe-column>-->
+					<!--          <vxe-column min-width="160" align="center" title="入库人" field="wareHouseManName"></vxe-column>-->
+					<!--          <vxe-column min-width="160" align="center" title="入库部门" field="wareHouseManOfficeName"></vxe-column>-->
+					<vxe-column min-width="160" align="center" title="商品名称" field="tradeName">
+						<template #default="scope">
+							<el-link type="primary" :underline="false" v-if="hasPermission('psi:list')"
+								@click="view(scope.row)">{{ scope.row.tradeName }}</el-link>
+							<el-link type="primary" :underline="false" v-else-if="hasPermission('psi:list')"
+								@click="view(scope.row)">{{ scope.row.tradeName }}</el-link>
+							<span v-else>{{ scope.row.tradeName }}</span>
+						</template>
+					</vxe-column>
+					<vxe-column min-width="160" align="center" title="入库类型" field="wareHouseTypeName"></vxe-column>
+					<vxe-column min-width="160" align="center" title="总量" field="allNumber"></vxe-column>
+					<vxe-column min-width="160" align="center" title="领用量" field="borrowNumber">
+						<template #default="scope">
+							<span v-if="scope.row.borrowNumber">
+								{{ scope.row.borrowNumber }}
+							</span>
+							<span v-else>
+								0
+							</span>
+
+						</template>
+					</vxe-column>
+					<vxe-column min-width="160" align="center" title="报损量" field="lossNumber">
+						<template #default="scope">
+							<span v-if="scope.row.lossNumber">
+								{{ scope.row.lossNumber }}
+							</span>
+							<span v-else>
+								0
+							</span>
+
+						</template>
+					</vxe-column>
+					<vxe-column min-width="160" align="center" title="剩余量" field="tradeNumber"></vxe-column>
+					<vxe-column min-width="160" align="center" title="单位" field="company"></vxe-column>
+					<vxe-column min-width="160" align="center" fixed="right" title="提醒数量" field="warnNum"
+						:edit-render="{}">
+						<template #edit="scope">
+							<vxe-input v-model="scope.row.warnNum" type="float" min="0" @blur="changeWarnNum(scope.row)"
+								:controls="false"></vxe-input>
+						</template>
+					</vxe-column>
+					<vxe-column min-width="100" align="center" fixed="right" title="是否提醒" field="warnFlag">
+						<template #default="scope">
+							<el-switch :model-value="scope.row.warnFlag === '1'" active-color="#13ce66"
+								inactive-color="#ff4949"
+								@change="updateStatus(scope.row.tradeName, scope.row.wareHouseType)">
+							</el-switch>
+						</template>
+					</vxe-column>
+					<!--          <vxe-column min-width="160" align="center" title="入库时间" field="wareHouseDate"></vxe-column>-->
+					<vxe-column title="操作" width="80px" fixed="right" align="center">
+						<template #default="scope">
+							<el-button v-if="hasPermission('psi:summary:edit')" text type="primary" size="small"
+								@click="edit(scope.row.tradeName, scope.row.wareHouseType, scope.row.wareHouseTypeName)">修改</el-button>
+						</template>
+					</vxe-column>
+				</vxe-table>
+				<vxe-pager background :current-page="tablePage.currentPage" :page-size="tablePage.pageSize"
+					:total="tablePage.total" :page-sizes="[10, 20, 100, 1000, { label: '全量数据', value: 1000000 }]"
+					:layouts="['PrevPage', 'JumpNumber', 'NextPage', 'FullJump', 'Sizes', 'Total']"
+					@page-change="currentChangeHandle">
+				</vxe-pager>
+				<WareHouseAddForm ref="wareHouseAddForm" @refreshList="refreshList"></WareHouseAddForm>
+				<WareHouseHistory ref="wareHouseHistory"></WareHouseHistory>
+				<WareHouseHistoryPopup ref="wareHouseHistoryPopup"></WareHouseHistoryPopup>
+				<SupplierChooseForm ref="supplierChooseForm" @getSupplier="getSupplier"></SupplierChooseForm>
+				<EditTradeNameForm ref="editTradeNameForm" @refreshList="refreshList"></EditTradeNameForm>
+			</div>
+		</div>
+	</div>
+</template>
+
+<script>
+import WareHouseAddForm from '../wareHouse/WareHouseAddForm'
+import WareHouseHistory from './WareHouseHistory'
+import WareHouseHistoryPopup from './WareHouseHistoryPopup'
+import SelectTree from '@/components/treeSelect/treeSelect.vue'
+import MaterialManagementService from '@/api/psi/MaterialManagementService'
+import WareHouseService from '@/api/psi/WareHouseService'
+import processService from '@/api/flowable/processService'
+import userService from '@/api/sys/userService'
+import SupplierChooseForm from '@/views/materialManagement/supplier/SupplierChooseForm'
+import EditTradeNameForm from '@/views/materialManagement/wareHouseSummary/EditTradeNameForm'
+export default {
+	data() {
+		return {
+			searchVisible: true,
+			num: 0,
+			searchForm: {
+				wareHouseType: '',
+				tradeName: '',
+				wareHouseNumber: '',
+				wareHouseMan: '',
+				wareHouseManOffice: '',
+				wareHouseDates: [],
+				procurementType: '',
+				createBy: '',
+				supplierId: '',
+				supplierName: ''
+			},
+			dataList: [],
+			tablePage: {
+				total: 0,
+				currentPage: 1,
+				pageSize: 10,
+				orders: []
+			},
+			tableKey: '',
+			loading: false,
+			processDefinitionAuditId: '',
+			procDefAuditKey: '',
+			isAdmin: false,
+			create: ''
+		}
+	},
+	materialManagementService: null,
+	wareHouseService: null,
+	created() {
+		this.materialManagementService = new MaterialManagementService()
+		this.wareHouseService = new WareHouseService()
+	},
+	components: {
+		WareHouseHistory,
+		WareHouseHistoryPopup,
+		SelectTree,
+		WareHouseAddForm,
+		SupplierChooseForm,
+		EditTradeNameForm
+	},
+	computed: {
+		userName() {
+			return this.$store.state.user.name
+		},
+		user() {
+			this.createName = this.$store.state.user.name
+			return this.$store.state.user
+		}
+	},
+	mounted() {
+		this.refreshList()
+	},
+	activated() {
+		this.refreshList()
+	},
+	methods: {
+		// 查看
+		view(row) {
+			// this.$refs.wareHouseHistoryPopup.init()
+			let detailId = this.commonJS.isNotEmpty(this.searchForm.supplierId) ? row.id : ''
+			this.$refs.wareHouseHistory.init(row.tradeName, detailId)
+		},
+		// 修改商品名称
+		edit(tradeName, type, typeName) {
+			this.$refs.editTradeNameForm.init(tradeName, type, typeName)
+		},
+		// 查询当前用户是否是管理员用户
+		checkIsAdmin() {
+			userService.is().then((data) => {
+				this.isAdmin = data
+			})
+		},
+		// 获取数据列表
+		refreshList() {
+			this.loading = true
+			this.wareHouseService.wareHouseSummaryList({
+				'current': this.tablePage.currentPage,
+				'size': this.tablePage.pageSize,
+				'orders': this.tablePage.orders,
+				...this.searchForm
+			}).then((data) => {
+				this.dataList = data.records
+				this.tablePage.total = data.total
+				this.tableKey = Math.random()
+				this.loading = false
+			})
+			this.checkIsAdmin()
+			processService.getByName('物资管理-采购申请').then((data) => {
+				if (!this.commonJS.isEmpty(data.id)) {
+					this.processDefinitionAuditId = data.id
+					this.procDefAuditKey = data.key
+				}
+			})
+		},
+		// 当前页
+		currentChangeHandle({ currentPage, pageSize }) {
+			this.tablePage.currentPage = currentPage
+			this.tablePage.pageSize = pageSize
+			this.refreshList()
+		},
+		// 排序
+		sortChangeHandle(column) {
+			this.tablePage.orders = []
+			if (column.order != null) {
+				this.tablePage.orders.push({ column: this.$utils.toLine(column.property), asc: column.order === 'asc' })
+			}
+			this.refreshList()
+		},
+		resetSearch() {
+			this.$refs.searchForm.resetFields()
+			this.searchForm.supplierId = '' // 重置时清空供应商筛选
+			this.refreshList()
+		},
+		// 修改提醒状态 启用/停用
+		updateStatus(tradeName, wareHouseType) {
+			this.loading = true
+			this.wareHouseService.updateWarnFlagByTradeNameAndType(tradeName, wareHouseType).then((data) => {
+				this.$message.success(data)
+				this.loading = false
+				this.refreshList()
+			}).catch(() => {
+				this.refreshList()
+				this.loading = false
+			})
+		},
+		// 修改提醒数量blur事件
+		changeWarnNum(row) {
+			this.loading = true
+			// 如果提醒数量的值为空的话,将赋值为0
+			if (this.commonJS.isEmpty(row.warnNum)) {
+				row.warnNum = 0.00
+			}
+			// 根据商品名称、入库类型修改提醒数量
+			this.wareHouseService.updateWarnNumByTradeNameAndType(row.tradeName, row.wareHouseType, row.warnNum).then((data) => {
+				this.$message.success(data)
+				this.refreshList()
+				this.loading = false
+			}).catch(() => {
+				this.refreshList()
+				this.loading = false
+			})
+		},
+		getSupplier(row) {
+			this.searchForm.supplierId = row.id
+			this.searchForm.supplierName = row.name
+		},
+		// 打开供应商选择组件
+		openSupplierChoose() {
+			this.$refs.supplierChooseForm.init()
+		},
+		exportFile() {
+			const options = {
+				filename: `${this.moment(new Date()).format('YYYY-MM-DD')}入库申请数据导出`,
+				sheetName: '入库申请数据导出',
+				mode: 'all'
+			}
+			this.loading = true
+			this.wareHouseService.exportSummaryFile({
+				current: this.tablePage.currentPage,
+				size: this.tablePage.pageSize,
+				orders: this.tablePage.orders,
+				...options,
+				...this.searchForm
+			}).then((res) => {
+				this.$utils.downloadExcel(res, options.filename)
+				this.loading = false
+			}).catch(() => {
+				this.loading = false
+			})
+		}
+	}
+}
+</script>