material-form.vue 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. <template>
  2. <div v-loading="isLoading" class="hc-task-form white relative">
  3. <!-- 基础表单 -->
  4. <hc-card-item>
  5. <hc-info-table>
  6. <tr>
  7. <hc-info-table-td center is-title>合同材料:</hc-info-table-td>
  8. <hc-info-table-td width="120px">{{ baseForm?.contractMaterialName }}</hc-info-table-td>
  9. <hc-info-table-td center is-title>材料到场编号:</hc-info-table-td>
  10. <hc-info-table-td width="120px">{{ baseForm?.materialArriveNumber }}</hc-info-table-td>
  11. </tr>
  12. <tr>
  13. <hc-info-table-td center is-title>计量期:</hc-info-table-td>
  14. <hc-info-table-td width="120px">{{ baseForm?.periodName }}</hc-info-table-td>
  15. <hc-info-table-td center is-title>业务日期:</hc-info-table-td>
  16. <hc-info-table-td width="120px">{{ baseForm?.businessDate }}</hc-info-table-td>
  17. </tr>
  18. <tr>
  19. <hc-info-table-td center is-title>单价:</hc-info-table-td>
  20. <hc-info-table-td v-loading="priceLoading" width="120px">
  21. <el-input v-model="baseForm.price" :disabled="!isEdits || tableInfo.status === 2" @blur="priceInputBlur" />
  22. </hc-info-table-td>
  23. <hc-info-table-td center is-title>计量数量:</hc-info-table-td>
  24. <hc-info-table-td v-loading="meterLoading" width="120px">
  25. <el-input v-model="baseForm.meterAmount" :disabled="!isEdits || tableInfo.status === 2" @blur="meterAmountInputBlur" />
  26. </hc-info-table-td>
  27. </tr>
  28. <tr>
  29. <hc-info-table-td center is-title>计量金额:</hc-info-table-td>
  30. <hc-info-table-td width="120px">{{ baseForm?.meterMoney }}</hc-info-table-td>
  31. <hc-info-table-td center is-title>备料堆放地点:</hc-info-table-td>
  32. <hc-info-table-td width="120px">{{ baseForm?.storagePlace }}</hc-info-table-td>
  33. </tr>
  34. <tr>
  35. <hc-info-table-td center is-title>存储情况:</hc-info-table-td>
  36. <hc-info-table-td width="120px">{{ baseForm?.storageStatus }}</hc-info-table-td>
  37. <hc-info-table-td center is-title>材料来源:</hc-info-table-td>
  38. <hc-info-table-td width="120px">{{ baseForm?.materialSource }}</hc-info-table-td>
  39. </tr>
  40. <tr>
  41. <hc-info-table-td center is-title>材料是否符合要求:</hc-info-table-td>
  42. <hc-info-table-td width="120px">{{ baseForm?.materialConformName }}</hc-info-table-td>
  43. <hc-info-table-td center is-title>存储方法是否符合要求:</hc-info-table-td>
  44. <hc-info-table-td width="120px">{{ baseForm?.storageConformName }}</hc-info-table-td>
  45. </tr>
  46. <tr>
  47. <hc-info-table-td center is-title>合格证号:</hc-info-table-td>
  48. <hc-info-table-td width="auto" colspan="3">{{ baseForm?.certificate }}</hc-info-table-td>
  49. </tr>
  50. <tr>
  51. <hc-info-table-td center is-title>备注:</hc-info-table-td>
  52. <hc-info-table-td width="auto" colspan="3">{{ baseForm?.remark }}</hc-info-table-td>
  53. </tr>
  54. </hc-info-table>
  55. </hc-card-item>
  56. <!-- 附件列表 -->
  57. <hc-card-item class="mt-3" title="附件列表">
  58. <template #extra>
  59. <span class="text-[13px] text-orange font-400">可上传 图片(png、jpg、jpeg)、Excel(xls、xlsx)、PDF、Word(doc、docx)文件</span>
  60. </template>
  61. <el-form :model="baseForm" label-position="left" label-width="auto">
  62. <el-form-item label="上传附件">
  63. <hc-form-upload type="list" :src="baseForm.fileList" :h-props="uploadFormProps" is-del @upload="attachmentUpload" @change="attachmentUploadChange" @del="attachmentUploadDel" />
  64. </el-form-item>
  65. </el-form>
  66. </hc-card-item>
  67. <!-- 文件上传组件 -->
  68. <hc-upload-file ref="uploadFileRef" :options="uploadFileOptions" @success="uploadFileSuccess" />
  69. </div>
  70. </template>
  71. <script setup>
  72. import { nextTick, onMounted, ref, watch } from 'vue'
  73. import { useAppStore } from '~src/store'
  74. import { getArrValue, getObjVal, getObjValue, isNullES } from 'js-fast-way'
  75. import { delMessage, isNumberReg } from '~uti/tools'
  76. import { getHeader } from 'hc-vue3-ui'
  77. import mainApi from '~api/tasks/hc-data'
  78. const props = defineProps({
  79. isEdit: {
  80. type: Boolean,
  81. default: true,
  82. },
  83. info: {
  84. type: Object,
  85. default: () => ({}),
  86. },
  87. table: {
  88. type: Object,
  89. default: () => ({}),
  90. },
  91. })
  92. const useAppState = useAppStore()
  93. const projectId = ref(useAppState.getProjectId || '')
  94. const contractId = ref(useAppState.getContractId || '')
  95. //监听可否编辑
  96. const isEdits = ref(props.isEdit)
  97. watch(() => props.isEdit, (val) => {
  98. isEdits.value = val
  99. }, { immediate: true, deep: true })
  100. //监听数据
  101. watch(() => [
  102. props.table,
  103. props.info,
  104. ], ([table, row]) => {
  105. setTaskInfo(table, row)
  106. }, { deep: true })
  107. //渲染完成
  108. onMounted(() => {
  109. setTaskInfo(props.table, props.info)
  110. })
  111. //设置任务信息
  112. const taskInfo = ref({})
  113. const tableInfo = ref({})
  114. const setTaskInfo = (table, row) => {
  115. tableInfo.value = table
  116. taskInfo.value = row
  117. if (getObjVal(table) && getObjVal(row)) {
  118. getDataDetail()
  119. }
  120. }
  121. //基础表单
  122. const baseForm = ref({ fileList: [] })
  123. //获取任务数据信息详情
  124. const isLoading = ref(false)
  125. const getDataDetail = async () => {
  126. const id = taskInfo.value.id
  127. const dataId = tableInfo.value.id
  128. const { data } = await mainApi.getDataDetail({ id, dataId })
  129. //转换数据
  130. const { attachmentFormTask, basicsInfo } = getObjValue(data)
  131. baseForm.value = getObjValue(basicsInfo) //表单信息
  132. baseForm.value.fileList = getArrValue(attachmentFormTask) //附件列表
  133. }
  134. //单价输入框失去焦点
  135. const priceLoading = ref(false)
  136. const priceInputBlur = async () => {
  137. let { id, price } = baseForm.value
  138. const isMeter = isNumberReg(price)
  139. let priceValue = price
  140. if (isNullES(price) || !isMeter) {
  141. priceValue = 0
  142. }
  143. await nextTick(() => {
  144. baseForm.value.price = priceValue
  145. })
  146. //发起请求
  147. priceLoading.value = true
  148. const { error, code, msg } = await mainApi.taskMaterialUpdate({
  149. projectId: projectId.value,
  150. contractId: contractId.value,
  151. taskId: taskInfo.value.id,
  152. price: priceValue,
  153. id,
  154. })
  155. priceLoading.value = false
  156. if (!error && code === 200) {
  157. window.$message.success('修改成功')
  158. } else {
  159. window.$message.error(msg ?? '修改失败')
  160. }
  161. }
  162. //单价输入框失去焦点
  163. const meterLoading = ref(false)
  164. const meterAmountInputBlur = async () => {
  165. let { id, meterAmount } = baseForm.value
  166. const isMeter = isNumberReg(meterAmount)
  167. let meterAmountValue = meterAmount
  168. if (isNullES(meterAmount) || !isMeter) {
  169. meterAmountValue = 0
  170. }
  171. await nextTick(() => {
  172. baseForm.value.meterAmount = meterAmountValue
  173. })
  174. //发起请求
  175. meterLoading.value = true
  176. const { error, code, msg } = await mainApi.taskMaterialUpdate({
  177. projectId: projectId.value,
  178. contractId: contractId.value,
  179. meterAmount: meterAmountValue,
  180. taskId: taskInfo.value.id,
  181. id,
  182. })
  183. meterLoading.value = false
  184. if (!error && code === 200) {
  185. window.$message.success('修改成功')
  186. } else {
  187. window.$message.error(msg ?? '修改失败')
  188. }
  189. }
  190. //文件上传
  191. const uploadFileRef = ref(null)
  192. const uploadFileOptions = ref({
  193. headers: getHeader(),
  194. multiple: false,
  195. })
  196. const uploadFormProps = {
  197. url: 'filePdfUrl',
  198. name: 'fileName',
  199. }
  200. const attachmentUpload = () => {
  201. if (isEdits.value || tableInfo.value.status !== 2) {
  202. uploadFileRef.value?.selectFile()
  203. } else {
  204. window.$message.error('当前状态不可上传')
  205. }
  206. }
  207. const attachmentUploadChange = (a, b, fileList) => {
  208. baseForm.value.fileList = getArrValue(fileList)
  209. }
  210. // 文件上传成功的回调
  211. const uploadFileSuccess = async ({ resData }) => {
  212. const { pdfUrl } = resData
  213. if (isNullES(pdfUrl)) {
  214. window.$message.warning('该文件不能生成pdf,请更换文件上传')
  215. uploadFileRef.value?.setModalShow(false)
  216. return
  217. }
  218. baseForm.value.fileList.push({
  219. contractId: contractId.value,
  220. fileName: resData.originalName ?? '',
  221. filePdfUrl: resData.pdfUrl ?? '',
  222. fileUrl: resData.link ?? '',
  223. taskId: taskInfo.value.id,
  224. })
  225. uploadFileRef.value?.setModalShow(false)
  226. //发起请求
  227. const dataId = tableInfo.value.id
  228. const { error, code, msg } = await mainApi.taskUploadFile({
  229. projectId: projectId.value,
  230. contractId: contractId.value,
  231. fileList: baseForm.value.fileList,
  232. taskId: taskInfo.value.id,
  233. dataId,
  234. })
  235. if (!error && code === 200) {
  236. window.$message.success('上传成功')
  237. } else {
  238. window.$message.error(msg ?? '上传失败')
  239. }
  240. }
  241. //删除文件
  242. const attachmentUploadDel = ({ file }, resolve) => {
  243. if (!isEdits.value) {
  244. window.$message.error('当前状态不可删除')
  245. return
  246. }
  247. delMessage(async () => {
  248. const { error, code, msg } = await mainApi.removeFile({
  249. id: file.id,
  250. taskId: taskInfo.value.id,
  251. })
  252. if (!error && code === 200) {
  253. resolve(true)
  254. } else {
  255. window.$message.error(msg ?? '删除失败')
  256. resolve(false)
  257. }
  258. })
  259. }
  260. </script>
  261. <style lang="scss">
  262. .hc-task-form.white .hc-card-item-box {
  263. background: white !important;
  264. }
  265. </style>