dataModal.vue 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697
  1. <template>
  2. <hc-new-dialog v-model="isShow" :title="`${dataId ? '编辑' : '新增'}材料调差单`" is-footer-center is-table widths="80rem" @close="modalClose">
  3. <div class="hc-info-table-form">
  4. <el-form ref="formRef" :model="formModel" :rules="formRules" label-position="top" label-width="auto">
  5. <hc-info-table>
  6. <tr>
  7. <hc-info-table-td is-title width="10%">
  8. <span>计量期:</span>
  9. <i class="i-iconoir-asterisk asterisk-icon" />
  10. </hc-info-table-td>
  11. <hc-info-table-td>
  12. <el-form-item prop="key1">
  13. <el-select v-model="formModel.meterPeriodId" placeholder="选择计量期" filterable block>
  14. <el-option v-for="item in measurement" :key="item.id" :label="item.periodName" :value="item.id" />
  15. </el-select>
  16. </el-form-item>
  17. </hc-info-table-td>
  18. <hc-info-table-td is-title width="10%">
  19. <span>调差期:</span>
  20. <i class="i-iconoir-asterisk asterisk-icon" />
  21. </hc-info-table-td>
  22. <hc-info-table-td>
  23. <el-form-item prop="contractPeriodId">
  24. <el-select v-model="formModel.contractPeriodId" placeholder="选择调差期" filterable block @change="adjustmentChange">
  25. <template v-for="item in adjustment" :key="item.id">
  26. <el-option v-if="item.approveStatus === 2" :label="item.periodNumber" :value="item.id" />
  27. </template>
  28. </el-select>
  29. </el-form-item>
  30. </hc-info-table-td>
  31. </tr>
  32. <tr>
  33. <hc-info-table-td is-title width="10%">
  34. <span>材料名称:</span>
  35. <i class="i-iconoir-asterisk asterisk-icon" />
  36. </hc-info-table-td>
  37. <hc-info-table-td>
  38. <el-form-item prop="contractMaterialId">
  39. <el-select v-model="formModel.contractMaterialId" placeholder="选择材料名称" filterable block :disabled="isNullES(formModel.meterPeriodId)" @change="materialNameChange">
  40. <el-option v-for="item in materialName" :key="item.id" :label="item.materialName" :value="item.id" />
  41. </el-select>
  42. </el-form-item>
  43. </hc-info-table-td>
  44. <hc-info-table-td is-title width="10%">
  45. <span>施工期市场价格:</span>
  46. <i class="i-iconoir-asterisk asterisk-icon" />
  47. </hc-info-table-td>
  48. <hc-info-table-td>
  49. <el-form-item prop="currentPrice">
  50. <el-input v-model="formModel.currentPrice" disabled>
  51. <template #suffix>元</template>
  52. <template #append>
  53. <el-button type="primary" class="hc-input-btn" color="#C99AD7" @click="realTimePriceClick">
  54. <hc-icon name="add" />
  55. <span>选择实时价格</span>
  56. </el-button>
  57. </template>
  58. </el-input>
  59. </el-form-item>
  60. </hc-info-table-td>
  61. </tr>
  62. <tr>
  63. <hc-info-table-td is-title width="10%">调差月份:</hc-info-table-td>
  64. <hc-info-table-td>
  65. <el-form-item>
  66. <el-date-picker v-if="isAdjustDate" v-model="formModel.adjustMonth" class="block" type="month" format="YYYY-MM" value-format="YYYY-MM" :disabled="isNullES(formModel.currentPriceId)" :disabled-date="disabledDate" />
  67. </el-form-item>
  68. </hc-info-table-td>
  69. <hc-info-table-td is-title width="10%">材料基准价格:</hc-info-table-td>
  70. <hc-info-table-td>
  71. <el-form-item>
  72. <el-input v-model="formModel.materialPrice" disabled>
  73. <template #suffix>元</template>
  74. </el-input>
  75. </el-form-item>
  76. </hc-info-table-td>
  77. </tr>
  78. <tr>
  79. <hc-info-table-td is-title width="10%">
  80. <span>材料数量:</span>
  81. <i class="i-iconoir-asterisk asterisk-icon" />
  82. </hc-info-table-td>
  83. <hc-info-table-td>
  84. <el-form-item prop="materialTotal">
  85. <el-input v-model="formModel.materialTotal" />
  86. </el-form-item>
  87. </hc-info-table-td>
  88. <hc-info-table-td is-title width="10%">价差幅度:</hc-info-table-td>
  89. <hc-info-table-td>
  90. <el-form-item>
  91. <el-input v-model="formModel.rangePriceRatio" disabled>
  92. <template #suffix>%</template>
  93. </el-input>
  94. </el-form-item>
  95. </hc-info-table-td>
  96. </tr>
  97. <tr>
  98. <hc-info-table-td is-title width="10%">调差金额:</hc-info-table-td>
  99. <hc-info-table-td width="auto" colspan="3">
  100. <el-form-item>
  101. <el-input v-model="formModel.adjustMoney" disabled />
  102. </el-form-item>
  103. </hc-info-table-td>
  104. </tr>
  105. <tr>
  106. <hc-info-table-td is-title width="10%">材料调差计算式:</hc-info-table-td>
  107. <hc-info-table-td width="auto" colspan="3">
  108. <el-form-item>
  109. <el-input v-model="formModel.adjustCalculation" type="textarea" :rows="4" resize="none" disabled />
  110. </el-form-item>
  111. </hc-info-table-td>
  112. </tr>
  113. </hc-info-table>
  114. </el-form>
  115. </div>
  116. <div class="hc-info-form-table">
  117. <el-divider border-style="dashed">
  118. <el-segmented v-model="tab_key" :options="['材料明细', '上传附件']" />
  119. </el-divider>
  120. <div v-if="tab_key === '材料明细'" class="loop-refresh-icon" @click="getMaterialDetail">
  121. <hc-icon name="loop-left" />
  122. </div>
  123. <div v-if="tab_key === '材料明细'" class="table-body">
  124. <hc-table :column="tableColumn1" :datas="tableData1" :index-style="{ width: 60 }" :loading="tableLoading1">
  125. <template #changeTotal="{ row }">
  126. <el-input v-model="row.changeTotal" @blur="changeTotalBlur(row)" />
  127. </template>
  128. </hc-table>
  129. </div>
  130. <div v-if="tab_key === '上传附件'" class="table-body">
  131. <div class="table-upload-attachment">
  132. <el-button @click="uploadAttachmentClick">点击上传附件</el-button>
  133. </div>
  134. <div class="table-upload">
  135. <hc-table :column="tableColumn2" :datas="tableData2" :index-style="{ width: 60 }" :loading="tableLoading2">
  136. <template #action="{ row, index }">
  137. <el-link type="primary" @click="previewFile(row)">预览</el-link>
  138. <el-link type="danger" @click="delFile(index)">删除</el-link>
  139. </template>
  140. </hc-table>
  141. </div>
  142. </div>
  143. </div>
  144. <template #footer>
  145. <el-button hc-btn @click="modalClose">取消</el-button>
  146. <el-button :loading="saveLoaing" hc-btn type="primary" @click="modalSave">保存</el-button>
  147. </template>
  148. </hc-new-dialog>
  149. <!-- 材料实时发布价格 -->
  150. <hc-new-dialog v-model="isRealTimePrice" ui="hc-realTime-price" title="材料实时发布价格" is-table :footer="false" widths="70rem" @close="realTimePriceClose">
  151. <div class="h-full">
  152. <div class="search-year-month mb-14px">
  153. <div class="w-48">
  154. <el-date-picker v-model="yearMonth" class="block" type="month" format="YYYY-MM" value-format="YYYY-MM" placeholder="调差月份" clearable @change="getMaterialCurrentPrice" />
  155. </div>
  156. </div>
  157. <div class="realTime-price-table">
  158. <hc-table :column="tableColumn3" :datas="tableData3" :index-style="{ width: 60 }" :loading="tableLoading3">
  159. <template #action="{ row }">
  160. <el-link v-if="formModel.currentPriceId === row.id" type="danger" @click="deselectTimePrice">取消选择</el-link>
  161. <el-link v-else type="primary" @click="rowRealTimePrice(row)">选择</el-link>
  162. </template>
  163. </hc-table>
  164. </div>
  165. </div>
  166. </hc-new-dialog>
  167. <!-- 上传附件 -->
  168. <hc-new-dialog v-model="isAttachment" title="上传文件" is-footer-center widths="30rem" @close="attachmentClose">
  169. <hc-form-upload v-model="formUploadFile" is-res :options="{ type: 'list', props: uploadFormProps, isArr: true, num: 0 }" @success="fileUploadSuccess" />
  170. <template #footer>
  171. <el-button hc-btn @click="attachmentClose">取消</el-button>
  172. <el-button hc-btn type="primary" @click="attachmentSave">确认</el-button>
  173. </template>
  174. </hc-new-dialog>
  175. </template>
  176. <script setup>
  177. import dayjs from 'dayjs'
  178. import { nextTick, ref, watch } from 'vue'
  179. import { useAppStore } from '~src/store'
  180. import { isNumberReg } from '~uti/tools'
  181. import mainApi from '~api/debit-pay/material/material'
  182. import { deepClone, formValidate, getArrValue, getObjValue, isNullES, newWindow } from 'js-fast-way'
  183. const props = defineProps({
  184. ids: {
  185. type: [String, Number],
  186. default: '',
  187. },
  188. })
  189. //事件
  190. const emit = defineEmits(['finish', 'close'])
  191. //初始变量
  192. const useAppState = useAppStore()
  193. const contractId = ref(useAppState.getContractId)
  194. const projectId = ref(useAppState.getProjectId)
  195. //双向绑定
  196. // eslint-disable-next-line no-undef
  197. const isShow = defineModel('modelValue', {
  198. default: false,
  199. })
  200. //监听
  201. const dataId = ref(props.ids)
  202. watch(() => props.ids, (id) => {
  203. dataId.value = id
  204. }, { deep: true })
  205. //监听
  206. watch(isShow, (val) => {
  207. if (val) detailsModalShow()
  208. })
  209. //分段器
  210. const tab_key = ref('材料明细')
  211. //表单数据
  212. const formRef = ref(null)
  213. const formModel = ref({})
  214. const formRules = {
  215. meterPeriodId: {
  216. required: true,
  217. trigger: 'blur',
  218. message: '请选择计量期',
  219. },
  220. contractPeriodId: {
  221. required: true,
  222. trigger: 'blur',
  223. message: '请选择调差期',
  224. },
  225. contractMaterialId: {
  226. required: true,
  227. trigger: 'blur',
  228. message: '请选择材料名称',
  229. },
  230. currentPrice: {
  231. required: true,
  232. trigger: 'blur',
  233. message: '请选择实时价格',
  234. },
  235. materialTotal: {
  236. required: true,
  237. trigger: 'blur',
  238. message: '请填写材料数量',
  239. },
  240. }
  241. //处理数据
  242. const detailsModalShow = () => {
  243. getPeriodMeasurement()
  244. getPeriodAdjustment()
  245. getMaterialName()
  246. //过去数据详情
  247. if (!isNullES(dataId.value)) {
  248. getDetailData()
  249. } else {
  250. isAdjustDate.value = true
  251. }
  252. }
  253. //获取数据详情
  254. const getDetailData = async () => {
  255. const { code, data, msg } = await mainApi.detail(dataId.value)
  256. if (code === 200) {
  257. const obj = getObjValue(data)
  258. formModel.value = obj
  259. tableData1.value = obj.details
  260. tableData2.value = obj.files
  261. try {
  262. adjustStartDate.value = dayjs(obj.startDate).format('YYYY-MM') ?? ''
  263. adjustEndDate.value = dayjs(obj.endDate).format('YYYY-MM') ?? ''
  264. } catch { /* empty */ }
  265. isAdjustDate.value = true
  266. } else {
  267. window.$message.error(msg ?? '数据异常')
  268. modalClose()
  269. }
  270. }
  271. //获取计量期
  272. const measurement = ref([])
  273. const getPeriodMeasurement = async () => {
  274. const { data } = await mainApi.periodMeasurement(contractId.value)
  275. measurement.value = getArrValue(data)
  276. }
  277. //获取调差期
  278. const adjustment = ref([])
  279. const getPeriodAdjustment = async () => {
  280. const { data } = await mainApi.periodAdjustment(contractId.value)
  281. adjustment.value = getArrValue(data)
  282. }
  283. //获取调差期号
  284. const adjustmentChange = () => {
  285. const { contractPeriodId } = formModel.value
  286. const info = adjustment.value.find((item) => item.id === contractPeriodId)
  287. formModel.value.contractPeriodNumber = info.periodNumber ?? ''
  288. }
  289. //获取材料名称
  290. const materialName = ref([])
  291. const getMaterialName = async () => {
  292. const { meterPeriodId } = formModel.value
  293. const { data } = await mainApi.materialName(contractId.value, meterPeriodId)
  294. materialName.value = getArrValue(data)
  295. }
  296. const materialNameChange = () => {
  297. const { contractMaterialId } = formModel.value
  298. const info = materialName.value.find((item) => item.id === contractMaterialId)
  299. isAdjusts.value = 0
  300. formModel.value.currentPriceId = null
  301. formModel.value.currentPrice = ''
  302. formModel.value.adjustMonth = null
  303. formModel.value.materialPrice = info.price ?? ''
  304. formModel.value.materialName = info.materialName ?? ''
  305. formModel.value.rangePriceRatio = ''
  306. formModel.value.adjustCalculation = ''
  307. formModel.value.materialValidityId = null
  308. tableData1.value = []
  309. tableLoading1.value = false
  310. }
  311. //禁用时间
  312. const isAdjustDate = ref(false)
  313. const disabledDate = (time) => {
  314. if (isNullES(adjustStartDate.value) || isNullES(adjustEndDate.value)) {
  315. return true
  316. }
  317. //处理时间
  318. const date = dayjs(time).format('YYYY-MM') //当前时间
  319. const isStart = dayjs(date).isSame(dayjs(adjustStartDate.value)) //是否等于开始时间
  320. const isEnd = dayjs(date).isSame(dayjs(adjustEndDate.value)) //是否等于结束时间
  321. const isBefore = dayjs(date).isBefore(dayjs(adjustEndDate.value)) //是否在结束时间之前
  322. const isAfter = dayjs(date).isAfter(dayjs(adjustStartDate.value)) //是否在开始时间之后
  323. //如果当前时间,大于等于开始时间,小于等于结束时间,则可用,否则禁用
  324. if ((isStart || isAfter) && (isEnd || isBefore)) {
  325. return false
  326. } else {
  327. return true
  328. }
  329. }
  330. //材料实时发布价格表格
  331. const yearMonth = ref(null)
  332. const tableColumn3 = [
  333. { key: 'nodeName', name: '有效时间' },
  334. { key: 'materialNumber', name: '材料编号', width: 100, align: 'center' },
  335. { key: 'materialName', name: '材料名称' },
  336. { key: 'unit', name: '材料单位', width: 100, align: 'center' },
  337. { key: 'currentPrice', name: '单价(元)', width: 100, align: 'center' },
  338. { key: 'action', name: '操作', width: 100, align: 'center' },
  339. ]
  340. const tableData3 = ref([])
  341. const tableLoading3 = ref(false)
  342. const getMaterialCurrentPrice = async () => {
  343. const { contractMaterialId } = formModel.value
  344. //发起请求
  345. tableLoading3.value = true
  346. const { data } = await mainApi.getMaterialCurrentPrice({
  347. yearMonth: yearMonth.value,
  348. materialId: contractMaterialId,
  349. contractId: contractId.value,
  350. })
  351. tableData3.value = getArrValue(data)
  352. tableLoading3.value = false
  353. }
  354. //材料实时发布价格
  355. const isRealTimePrice = ref(false)
  356. const realTimePriceClick = () => {
  357. const { contractMaterialId } = formModel.value
  358. if (isNullES(contractMaterialId)) {
  359. window.$message.warning('请先选择材料名称')
  360. return
  361. }
  362. isRealTimePrice.value = true
  363. getMaterialCurrentPrice()
  364. }
  365. //选择实时发布价格
  366. const adjustStartDate = ref('')
  367. const adjustEndDate = ref('')
  368. const isAdjusts = ref(1) //0不允许,1允许
  369. const rowRealTimePrice = async (row) => {
  370. const { id, currentPrice, startDate, endDate, materialValidityId } = row
  371. const { code, msg, data } = await mainApi.getMaterialRangePrice({
  372. priceId: id,
  373. })
  374. const { isAdjust, rangePriceRatio, adjustCalculation } = getObjValue(data)
  375. if (code !== 200) {
  376. window.$message.error(msg ?? '操作失败')
  377. return
  378. }
  379. isAdjustDate.value = false
  380. let startDate1 = '', endDate1 = ''
  381. try {
  382. startDate1 = dayjs(startDate).format('YYYY-MM') ?? ''
  383. endDate1 = dayjs(endDate).format('YYYY-MM') ?? ''
  384. } catch { /* empty */ }
  385. isAdjusts.value = isAdjust ?? 0
  386. formModel.value.startDate = startDate1
  387. formModel.value.endDate = endDate1
  388. formModel.value.currentPriceId = id
  389. formModel.value.currentPrice = currentPrice
  390. formModel.value.adjustMonth = startDate1
  391. formModel.value.rangePriceRatio = rangePriceRatio
  392. formModel.value.adjustCalculation = adjustCalculation
  393. formModel.value.materialValidityId = materialValidityId
  394. adjustStartDate.value = startDate1
  395. adjustEndDate.value = endDate1
  396. await nextTick(() => {
  397. isAdjustDate.value = true
  398. realTimePriceClose()
  399. })
  400. }
  401. //关闭材料实时发布价格
  402. const realTimePriceClose = () => {
  403. isRealTimePrice.value = false
  404. tableData3.value = []
  405. tableLoading3.value = false
  406. }
  407. //材料明细表格
  408. const tableColumn1 = [
  409. { key: 'meterNumber', name: '计量单编号' },
  410. { key: 'formNumber', name: '清单编号' },
  411. { key: 'formName', name: '清单名称' },
  412. { key: 'unit', name: '单位', width: 120, align: 'center' },
  413. { key: 'meterTotal', name: '计量数量', width: 120, align: 'center' },
  414. { key: 'changeTotal', name: '可调量', width: 120, align: 'center' },
  415. { key: 'adjustFactor', name: '调差系数', width: 120, align: 'center' },
  416. { key: 'adjustTotal', name: '调差数量', width: 120, align: 'center' },
  417. ]
  418. const tableData1 = ref([])
  419. const tableLoading1 = ref(false)
  420. const getMaterialDetail = async () => {
  421. const {
  422. contractPeriodId, contractMaterialId, currentPrice,
  423. materialValidityId, materialPrice, rangePriceRatio,
  424. } = formModel.value
  425. if (isNullES(contractPeriodId)) {
  426. window.$message.warning('请先选择调差期')
  427. } else if (isNullES(contractMaterialId)) {
  428. window.$message.warning('请先选择材料名称')
  429. } else if (isNullES(currentPrice) || isNullES(materialValidityId)) {
  430. window.$message.warning('请先选择实时价格')
  431. } else if (isNullES(materialPrice)) {
  432. window.$message.warning('请先选择材料基准价格不为空的')
  433. } else if (isNullES(rangePriceRatio)) {
  434. window.$message.warning('请先选择价差幅度不为空的')
  435. } else {
  436. //获取数据
  437. const { code, msg, data } = await mainApi.getMaterialDetail({
  438. contractMaterialId: contractMaterialId,
  439. contractPeriodId: contractPeriodId,
  440. projectId: projectId.value,
  441. contractId: contractId.value,
  442. currentPrice: currentPrice,
  443. materialPrice: materialPrice,
  444. materialValidityId: materialValidityId,
  445. rangePriceRatio: rangePriceRatio,
  446. })
  447. tableData1.value = getArrValue(data)
  448. if (code !== 200 && msg) {
  449. window.$message.error(msg)
  450. }
  451. }
  452. }
  453. //价格取消选择
  454. const deselectTimePrice = () => {
  455. isAdjustDate.value = false
  456. const form = deepClone(formModel.value)
  457. tableData1.value = []
  458. formModel.value = {
  459. id: form.id,
  460. meterPeriodId: form.meterPeriodId,
  461. materialPrice: form.materialPrice,
  462. materialName: form.materialName,
  463. contractPeriodId: form.contractPeriodId,
  464. contractMaterialId: form.contractMaterialId,
  465. contractPeriodNumber: form.contractPeriodNumber,
  466. materialTotal: form.materialTotal,
  467. }
  468. isAdjustDate.value = true
  469. realTimePriceClose()
  470. }
  471. //可调量失去焦点
  472. const changeTotalBlur = (row) => {
  473. const { meterTotal, changeTotal } = row
  474. if (!isNumberReg(changeTotal)) {
  475. row.changeTotal = meterTotal
  476. window.$message.warning('请输入正确的可调量')
  477. } else if (changeTotal > meterTotal) {
  478. row.changeTotal = meterTotal
  479. window.$message.warning('只能小于等于计量数量')
  480. }
  481. }
  482. //上传附件
  483. const tableColumn2 = [
  484. { key: 'fileName', name: '文件名称' },
  485. { key: 'fileSizeName', name: '文件大小', align: 'center' },
  486. { key: 'fileUpTime', name: '更新时间', align: 'center' },
  487. { key: 'fileSuffix', name: '文件类型', align: 'center' },
  488. { key: 'action', name: '操作', width: 120, align: 'center' },
  489. ]
  490. const tableData2 = ref([])
  491. const tableLoading2 = ref(false)
  492. //附件上传
  493. const formUploadFile = ref([])
  494. const uploadFormProps = {
  495. url: 'link',
  496. name: 'originalName',
  497. }
  498. //点击上传附件
  499. const isAttachment = ref(false)
  500. const uploadAttachmentClick = () => {
  501. isAttachment.value = true
  502. }
  503. //附件上传成功的回调
  504. const fileUploadSuccess = ({ res }, resolve) => {
  505. resolve(res)
  506. }
  507. //提交确定
  508. const attachmentSave = async () => {
  509. const list = formUploadFile.value
  510. for (let i = 0; i < list.length; i++) {
  511. tableData2.value.push({
  512. fileName: list[i].originalName,
  513. filePdfUrl: list[i].pdfUrl,
  514. fileSizeName: list[i].fileSizeName,
  515. fileSuffix: list[i].fileSuffix,
  516. fileType: list[i].fileType,
  517. fileUpTime: list[i].fileDate,
  518. fileUrl: list[i].link,
  519. })
  520. }
  521. attachmentClose()
  522. }
  523. //关闭上传附件
  524. const attachmentClose = () => {
  525. isAttachment.value = false
  526. formUploadFile.value = []
  527. }
  528. //预览附件
  529. const previewFile = ({ fileUrl }) => {
  530. if (isNullES(fileUrl)) {
  531. window.$message.warning('此文件已不存在,请删除后,重新上传')
  532. return
  533. }
  534. newWindow(fileUrl)
  535. }
  536. //预览附件
  537. const delFile = (index) => {
  538. tableData2.value.splice(index, 1)
  539. }
  540. //保存
  541. const saveLoaing = ref(false)
  542. const modalSave = async () => {
  543. const isForm = await formValidate(formRef.value)
  544. if (!isForm) return
  545. //处理表单
  546. const form = formModel.value
  547. form.details = tableData1.value
  548. form.files = tableData2.value
  549. form.projectId = projectId.value
  550. form.contractId = contractId.value
  551. //发起请求
  552. let res = {}
  553. if (isNullES(form.id)) {//新增
  554. res = await mainApi.add(form)
  555. } else {
  556. res = await mainApi.update(form)
  557. }
  558. //处理结果
  559. const { code, msg } = res
  560. if (code === 200) {
  561. window.$message.success('保存成功')
  562. modalClose()
  563. emit('finish')
  564. } else {
  565. window.$message.error(msg ?? '保存失败')
  566. }
  567. }
  568. //关闭弹窗
  569. const modalClose = () => {
  570. isShow.value = false
  571. emit('close')
  572. dataId.value = ''
  573. formModel.value = {}
  574. isAdjustDate.value = false
  575. tableData1.value = []
  576. tableLoading1.value = false
  577. tableData2.value = []
  578. tableLoading2.value = false
  579. tableData3.value = []
  580. tableLoading3.value = false
  581. }
  582. </script>
  583. <style lang="scss">
  584. .hc-info-table-form {
  585. position: relative;
  586. height: 357px;
  587. .el-form .hc-info-table-td .el-form-item {
  588. margin-bottom: 0;
  589. .el-form-item__error {
  590. display: none;
  591. }
  592. }
  593. .asterisk-icon {
  594. position: absolute;
  595. display: inline-block;
  596. color: red;
  597. font-size: 8px;
  598. }
  599. .el-input-group__append .hc-input-btn {
  600. background-color: var(--el-button-bg-color);
  601. border-radius: 0 3px 3px 0;
  602. font-weight: 400;
  603. color: #000000;
  604. }
  605. }
  606. .hc-info-form-table {
  607. position: relative;
  608. height: calc(100% - 382px);
  609. .el-divider {
  610. border-color: #008200;
  611. }
  612. .el-divider .el-divider__text {
  613. padding: 0 4px;
  614. }
  615. .el-divider .el-segmented {
  616. --el-segmented-color: #008200;
  617. --el-segmented-item-hover-color: #008200;
  618. --el-segmented-item-selected-bg-color: #008200;
  619. --el-segmented-item-hover-bg-color: transparent;
  620. border: 1px solid #008200;
  621. }
  622. .loop-refresh-icon {
  623. position: absolute;
  624. color: #008200;
  625. font-size: 26px;
  626. height: 32px;
  627. width: 32px;
  628. display: flex;
  629. align-items: center;
  630. justify-content: center;
  631. background: white;
  632. left: 10px;
  633. top: -14px;
  634. cursor: pointer;
  635. &:hover {
  636. color: #035903;
  637. }
  638. }
  639. .table-body {
  640. position: relative;
  641. height: calc(100% - 25px);
  642. .table-upload-attachment {
  643. position: relative;
  644. margin-bottom: 10px;
  645. .el-button {
  646. width: 100%;
  647. }
  648. }
  649. .table-upload {
  650. position: relative;
  651. height: calc(100% - 42px);
  652. }
  653. }
  654. }
  655. .el-overlay-dialog .el-dialog.hc-new-dialog.hc-modal-table.hc-realTime-price {
  656. --el-dialog-margin-top: 100px;
  657. height: calc(100% - 200px);
  658. .realTime-price-table {
  659. position: relative;
  660. height: calc(100% - 46px);
  661. }
  662. }
  663. </style>