info.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. <template>
  2. <div class="hc-contract-info-data relative">
  3. <el-form ref="formRef" :model="contractForm" :rules="formRules" label-position="top" label-width="auto">
  4. <hc-card-item title="基础信息">
  5. <el-row :gutter="20">
  6. <el-col :span="12">
  7. <el-form-item label="项目名称:">
  8. <el-input v-model="projectInfo.projectName" disabled />
  9. </el-form-item>
  10. </el-col>
  11. <el-col :span="12">
  12. <el-form-item label="合同段名称:" prop="contractName">
  13. <el-input v-model="contractForm.contractName" clearable />
  14. </el-form-item>
  15. </el-col>
  16. <el-col :span="6">
  17. <el-form-item label="合同段类型:" prop="contractType">
  18. <el-select v-model="contractForm.contractType" placeholder="选择所属系统" clearable filterable block :disabled="!!contractForm.id" @change="treeAllConstruction">
  19. <el-option v-for="item in contractTypeList" :key="item.value" :label="item.label" :value="item.value" />
  20. </el-select>
  21. </el-form-item>
  22. </el-col>
  23. <el-col :span="6">
  24. <el-form-item label="合同段编号:" prop="contractNumber">
  25. <el-input v-model="contractForm.contractNumber" clearable />
  26. </el-form-item>
  27. </el-col>
  28. <el-col :span="6">
  29. <el-form-item label="参与方进场日期:">
  30. <el-date-picker v-model="contractForm.contractorJoinTime" class="block" format="YYYY 年 MM 月 DD 日" type="date" value-format="YYYY-MM-DD" clearable />
  31. </el-form-item>
  32. </el-col>
  33. <el-col :span="6">
  34. <el-form-item label="合同金额:">
  35. <el-input v-model="contractForm.contractAmount" clearable>
  36. <template #append>万元</template>
  37. </el-input>
  38. </el-form-item>
  39. </el-col>
  40. <el-col :span="contractForm.isTestModule === 1 ? 4 : 6">
  41. <el-form-item label="是否开启电签:" prop="isElectronicSignature">
  42. <div class="form-item-div">
  43. <el-radio-group v-model="contractForm.isElectronicSignature">
  44. <el-radio :value="0">关闭</el-radio>
  45. <el-radio :value="1">开启</el-radio>
  46. </el-radio-group>
  47. </div>
  48. </el-form-item>
  49. </el-col>
  50. <el-col :span="contractForm.isTestModule === 1 ? 4 : 6">
  51. <el-form-item label="是否开启试验模块:" prop="isTestModule">
  52. <div class="form-item-div">
  53. <el-radio-group v-model="contractForm.isTestModule">
  54. <el-radio :value="0">关闭</el-radio>
  55. <el-radio :value="1">开启</el-radio>
  56. </el-radio-group>
  57. </div>
  58. </el-form-item>
  59. </el-col>
  60. <el-col v-if="contractForm.isTestModule === 1" :span="4">
  61. <el-form-item label="是否强制引用记录/报告编号:" prop="isTestRecord">
  62. <div class="form-item-div">
  63. <el-radio-group v-model="contractForm.isTestRecord">
  64. <el-radio :value="0">关闭</el-radio>
  65. <el-radio :value="1">开启</el-radio>
  66. </el-radio-group>
  67. </div>
  68. </el-form-item>
  69. </el-col>
  70. <el-col :span="contractForm.isTestModule === 1 ? 4 : 6">
  71. <el-form-item label="是否引用编号:" prop="isReferenceNumber">
  72. <div class="form-item-div">
  73. <el-radio-group v-model="contractForm.isReferenceNumber">
  74. <el-radio :value="0">否</el-radio>
  75. <el-radio :value="1">是</el-radio>
  76. </el-radio-group>
  77. </div>
  78. </el-form-item>
  79. </el-col>
  80. <el-col :span="contractForm.isTestModule === 1 ? 4 : 6">
  81. <el-form-item label="是否允许超计:" prop="isOverMeter">
  82. <div class="form-item-div">
  83. <el-radio-group v-model="contractForm.isOverMeter">
  84. <el-radio :value="0">否</el-radio>
  85. <el-radio :value="1">是</el-radio>
  86. </el-radio-group>
  87. </div>
  88. </el-form-item>
  89. </el-col>
  90. <el-col :span="6">
  91. <el-form-item label="计划开工日期:" prop="planStartTime">
  92. <el-date-picker v-model="contractForm.planStartTime" class="block" format="YYYY 年 MM 月 DD 日" type="date" value-format="YYYY-MM-DD" clearable />
  93. </el-form-item>
  94. </el-col>
  95. <el-col :span="6">
  96. <el-form-item label="计划完工日期:" prop="planEndTime">
  97. <el-date-picker v-model="contractForm.planEndTime" class="block" format="YYYY 年 MM 月 DD 日" type="date" value-format="YYYY-MM-DD" clearable />
  98. </el-form-item>
  99. </el-col>
  100. <el-col :span="6">
  101. <el-form-item label="实际开工日期:" prop="actualStartTime">
  102. <el-date-picker v-model="contractForm.actualStartTime" class="block" format="YYYY 年 MM 月 DD 日" type="date" value-format="YYYY-MM-DD" clearable />
  103. </el-form-item>
  104. </el-col>
  105. <el-col :span="6">
  106. <el-form-item label="实际完工日期:" prop="actualEndTime">
  107. <el-date-picker v-model="contractForm.actualEndTime" class="block" format="YYYY 年 MM 月 DD 日" type="date" value-format="YYYY-MM-DD" clearable />
  108. </el-form-item>
  109. </el-col>
  110. <el-col v-if="contractForm.contractType === 1" :span="6">
  111. <el-form-item label="业主单位名称:" prop="contractorUnitName">
  112. <el-input v-model="contractForm.contractorUnitName" clearable />
  113. </el-form-item>
  114. </el-col>
  115. <el-col v-if="[1, 2].includes(contractForm.contractType)" :span="6">
  116. <el-form-item label="监理单位名称:" prop="supervisionUnitName">
  117. <el-input v-model="contractForm.supervisionUnitName" clearable />
  118. </el-form-item>
  119. </el-col>
  120. <el-col v-if="contractForm.contractType === 3" :span="6">
  121. <el-form-item label="建设单位名称:" prop="contractorUnitName">
  122. <el-input v-model="contractForm.contractorUnitName" clearable />
  123. </el-form-item>
  124. </el-col>
  125. <el-col v-if="contractForm.contractType === 1" :span="6">
  126. <el-form-item label="施工单位名称:" prop="constructionUnitName">
  127. <el-input v-model="contractForm.constructionUnitName" clearable />
  128. </el-form-item>
  129. </el-col>
  130. <el-col v-if="[1, 2, 3].includes(contractForm.contractType)" :span="6">
  131. <el-form-item label="试验室名称:" prop="laboratoryName">
  132. <el-input v-model="contractForm.laboratoryName" clearable />
  133. </el-form-item>
  134. </el-col>
  135. <el-col :span="24">
  136. <el-form-item>
  137. <template #label>
  138. <div class="hc-form-item-label">
  139. <div class="title-content">
  140. <span class="title">上传开工令:</span>
  141. </div>
  142. <div class="right-content">
  143. <el-link type="warning" @click="startFileDel">清除</el-link>
  144. </div>
  145. </div>
  146. </template>
  147. <hc-form-upload v-model="contractForm.startFileUrl" :upload="{ options: fileUpload }" @success="startFileSuccess" />
  148. </el-form-item>
  149. </el-col>
  150. </el-row>
  151. </hc-card-item>
  152. <hc-card-item v-if="contractForm.contractType !== 1" class="mt-14px" title="合同段权限配置">
  153. <el-form-item>
  154. <el-checkbox-group v-model="contractCheckIds">
  155. <el-checkbox v-for="item in contractCheckList" :key="item.contractId" :label="item.contractName" :value="item.contractId" />
  156. </el-checkbox-group>
  157. </el-form-item>
  158. </hc-card-item>
  159. <hc-card-item class="mt-14px" title="组卷归档默认信息">
  160. <el-row :gutter="20">
  161. <el-col :span="4">
  162. <el-form-item label="立卷人:">
  163. <el-input v-model="contractForm.filer" />
  164. </el-form-item>
  165. </el-col>
  166. <el-col :span="4">
  167. <el-form-item label="审核人:">
  168. <el-input v-model="contractForm.reviewer" />
  169. </el-form-item>
  170. </el-col>
  171. <el-col :span="4">
  172. <el-form-item label="档案前缀:">
  173. <el-input v-model="contractForm.prefix" />
  174. </el-form-item>
  175. </el-col>
  176. <el-col :span="4">
  177. <el-form-item label="保管期限:">
  178. <el-select v-model="contractForm.storagePeriod" filterable clearable block>
  179. <el-option v-for="item in storagePeriods" :key="item.value" :label="item.label" :value="item.value" />
  180. </el-select>
  181. </el-form-item>
  182. </el-col>
  183. <el-col :span="4">
  184. <el-form-item label="保管密级:">
  185. <el-select v-model="contractForm.securityLevel" filterable clearable block>
  186. <el-option v-for="item in securityLevels" :key="item.value" :label="item.label" :value="item.value" />
  187. </el-select>
  188. </el-form-item>
  189. </el-col>
  190. </el-row>
  191. </hc-card-item>
  192. <hc-card-item v-if="contractForm.contractType === 1" class="mt-14px" title="附加信息">
  193. <el-row :gutter="20">
  194. <el-col :span="24">
  195. <el-form-item label="项目地址:" prop="projectPlace">
  196. <el-input v-model="contractForm.projectPlace" clearable />
  197. </el-form-item>
  198. </el-col>
  199. <el-col :span="8">
  200. <el-form-item label="起始桩号:" prop="startStation">
  201. <el-input v-model="contractForm.startStation" clearable />
  202. </el-form-item>
  203. </el-col>
  204. <el-col :span="8">
  205. <el-form-item label="结束桩号:" prop="endStation">
  206. <el-input v-model="contractForm.endStation" clearable />
  207. </el-form-item>
  208. </el-col>
  209. <el-col :span="8">
  210. <el-form-item label="里程:">
  211. <el-input v-model="contractForm.projectMileage" clearable>
  212. <template #append>公里(KM)</template>
  213. </el-input>
  214. </el-form-item>
  215. </el-col>
  216. </el-row>
  217. </hc-card-item>
  218. <hc-card-item class="mb-70px mt-14px" title="计量信息">
  219. <HcMeterTable v-model="contractForm.meterContractInfo" />
  220. </hc-card-item>
  221. </el-form>
  222. <div class="action">
  223. <el-button hc-btn class="mr-4" :loading="submitLoading" @click="saveAndExit">保存并退出</el-button>
  224. <el-button hc-btn type="primary" :loading="submitLoading" @click="saveAndNextStep">保存并进入下一步</el-button>
  225. </div>
  226. </div>
  227. </template>
  228. <script setup>
  229. import { onMounted, ref, watch } from 'vue'
  230. import { deepClone, formValidate, getArrValue, getObjValue, isNullES } from 'js-fast-way'
  231. import { getDictionaryData } from '~uti/tools'
  232. import HcMeterTable from './table.vue'
  233. //请求接口
  234. import mainApi from '~api/project/contract'
  235. import projectApi from '~api/project/project'
  236. const props = defineProps({
  237. data: {
  238. type: Object,
  239. default: () => ({}),
  240. },
  241. })
  242. //事件
  243. const emit = defineEmits(['close', 'next'])
  244. //渲染完成
  245. onMounted(() => {
  246. getDataApi()
  247. })
  248. //监听数据
  249. const dataInfo = ref(props.data)
  250. watch(() => props.data, (data) => {
  251. dataInfo.value = data
  252. getDataApi()
  253. }, { deep: true })
  254. //获取数据
  255. const getDataApi = async () => {
  256. const { cid, type } = getObjValue(dataInfo.value)
  257. await getContractTypeList()
  258. if (!isNullES(cid)) {
  259. if ([1, 4, 8].includes(type)) {
  260. await getContractInfo()
  261. } else if ([2, 3].includes(type)) {
  262. await getContractInfo2()
  263. await getContractRelation()
  264. }
  265. }
  266. await getProjectDeatil()
  267. await treeAllConstruction()
  268. getStoragePeriodList().then()
  269. getSecurityLevelList().then()
  270. }
  271. //获取项目详情
  272. const projectInfo = ref({})
  273. const getProjectDeatil = async () => {
  274. const { pid } = getObjValue(dataInfo.value)
  275. projectInfo.value = {}
  276. if (isNullES(pid)) return
  277. const { data } = await projectApi.detail(pid)
  278. projectInfo.value = getObjValue(data)
  279. }
  280. //获取合同类型
  281. const contractTypeList = ref([])
  282. const getContractTypeList = async () => {
  283. contractTypeList.value = await getDictionaryData('contract_type')
  284. }
  285. //获取合同段基本信息
  286. const contractForm = ref({})
  287. const getContractInfo = async () => {
  288. const { cid } = getObjValue(dataInfo.value)
  289. contractForm.value = {}
  290. if (isNullES(cid)) return
  291. const { data } = await mainApi.detail(cid)
  292. const res = getObjValue(data)
  293. const info = getObjValue(res.meterContractInfo)
  294. res.meterContractInfo = info
  295. contractForm.value = res
  296. }
  297. //获取合同段基本信息
  298. const getContractInfo2 = async () => {
  299. const { cid, type } = getObjValue(dataInfo.value)
  300. contractForm.value = {}
  301. if (isNullES(cid)) return
  302. const { data } = await mainApi.detail2({
  303. id: cid,
  304. contractType: type,
  305. })
  306. const res = getObjValue(data)
  307. const info = getObjValue(res.meterContractInfo)
  308. res.meterContractInfo = info
  309. contractForm.value = res
  310. }
  311. //获取业务字典
  312. const storagePeriods = ref([])
  313. const getStoragePeriodList = async () => {
  314. storagePeriods.value = await getDictionaryData('storage_period', true)
  315. }
  316. //获取安全等级
  317. const securityLevels = ref([])
  318. const getSecurityLevelList = async () => {
  319. securityLevels.value = await getDictionaryData('security_level', true)
  320. }
  321. //菜单表单
  322. const formRef = ref(null)
  323. const formRules = {
  324. contractName: { required: true, trigger: 'blur', message: '请输入合同段名称' },
  325. contractType: { required: true, trigger: 'blur', message: '请选择合同段类型' },
  326. contractNumber: { required: true, trigger: 'blur', message: '请输入合同段编号' },
  327. isElectronicSignature: { required: true, trigger: 'blur', message: '请选择是否开启电签' },
  328. isTestModule: { required: true, trigger: 'blur', message: '请选择是否开启试验模块' },
  329. isReferenceNumber: { required: true, trigger: 'blur', message: '请选择是否引用编号' },
  330. isOverMeter: { required: true, trigger: 'blur', message: '请选择是否允许超计' },
  331. contractorUnitName: { required: true, trigger: 'blur', message: '请输入单位名称' },
  332. supervisionUnitName: { required: true, trigger: 'blur', message: '请输入单位名称' },
  333. constructionUnitName: { required: true, trigger: 'blur', message: '请输入单位名称' },
  334. projectPlace: { required: true, trigger: 'blur', message: '请输入项目地址' },
  335. startStation: { required: true, trigger: 'blur', message: '请输入起始桩号' },
  336. endStation: { required: true, trigger: 'blur', message: '请输入结束桩号' },
  337. }
  338. //文件上传
  339. const fileUpload = {
  340. url: '/api/blade-resource/oss/endpoint/put-file-attach',
  341. multiple: false,
  342. size: 100,
  343. }
  344. //上传文件完成
  345. const startFileSuccess = ({ res }) => {
  346. const { link } = getObjValue(res.data)
  347. contractForm.value.startFileUrl = link
  348. }
  349. //删除文件
  350. const startFileDel = () => {
  351. contractForm.value.startFileUrl = ''
  352. }
  353. //合同段信息
  354. const contractCheckList = ref([])
  355. const treeAllConstruction = async () => {
  356. const { pid } = getObjValue(dataInfo.value)
  357. const { contractType } = contractForm.value
  358. if (isNullES(pid) || isNullES(contractType)) {
  359. contractCheckList.value = []
  360. return
  361. }
  362. //发起请求
  363. const { data } = await projectApi.treeAllConstruction({
  364. projectId: pid,
  365. contractType: contractType,
  366. })
  367. contractCheckList.value = getArrValue(data)
  368. }
  369. //监理、业主关联施工
  370. const contractCheckIds = ref([])
  371. const getContractRelation = async () => {
  372. const { cid } = getObjValue(dataInfo.value)
  373. if (isNullES(cid)) return
  374. const { data } = await projectApi.getContractRelation(cid)
  375. const res = getArrValue(data)
  376. contractCheckIds.value = res.map(({ id }) => {
  377. return id
  378. })
  379. }
  380. //保存并退出
  381. const saveAndExit = async () => {
  382. const isRes = await saveDataApi()
  383. if (!isRes) return
  384. emit('close', dataInfo.value)
  385. }
  386. //保存并进入下一步
  387. const saveAndNextStep = async () => {
  388. const isRes = await saveDataApi()
  389. if (!isRes) return
  390. emit('next', dataInfo.value)
  391. }
  392. //保存数据
  393. const submitLoading = ref(false)
  394. const saveDataApi = async () => {
  395. const isForm = await formValidate(formRef.value)
  396. if (!isForm) return false
  397. submitLoading.value = true
  398. const obj = deepClone(contractForm.value)
  399. if (obj.contractType !== 1) {
  400. const checkIds = contractCheckIds.value
  401. delete obj.startStation
  402. delete obj.endStation
  403. delete obj.projectPlace
  404. let idList = []
  405. checkIds.forEach(val => {
  406. idList.push({ contractId: val })
  407. })
  408. obj.idList = idList
  409. }
  410. const { code, data } = await mainApi.submit(obj)
  411. submitLoading.value = false
  412. if (code === 200) {
  413. dataInfo.value.cid = data.id
  414. window?.$message?.success('保存成功')
  415. getDataApi().then()
  416. }
  417. return code === 200
  418. }
  419. </script>
  420. <style scoped lang="scss">
  421. .hc-contract-info-data .action {
  422. position: fixed;
  423. bottom: 14px;
  424. width: calc(100% - 240px);
  425. text-align: center;
  426. background: #fff;
  427. padding: 14px;
  428. }
  429. </style>