index.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. <template>
  2. <hc-new-dialog :show="isShow" :title="title" widths="47rem" @close="cancelReportClick">
  3. <el-form ref="formRef" :model="formModel" :rules="formRules" label-width="auto" size="large">
  4. <el-form-item label="任务名称" prop="taskName">
  5. <el-input v-model="formModel.taskName" disabled />
  6. </el-form-item>
  7. <el-form-item v-if="isDatas && reportDatas.length > 0" label="审批内容">
  8. <div class="task-tag-data-box">
  9. <template v-for="(item, index) in reportDatas" :key="item.id">
  10. <el-tag closable size="default" type="info" @close="taskTagClose(index)">{{ item.name }}</el-tag>
  11. </template>
  12. </div>
  13. </el-form-item>
  14. <el-form-item label="任务描述" prop="taskContent">
  15. <el-input v-model="formModel.taskContent" :autosize="{ minRows: 3, maxRows: 5 }" placeholder="请输入任务描述" type="textarea" />
  16. </el-form-item>
  17. <el-form-item label="任务流程" prop="fixedFlowId">
  18. <el-select v-model="formModel.fixedFlowId" block @change="handleProcessValue">
  19. <el-option v-for="item in processData" :key="item.id" :disabled="item.disabled" :value="item.id" :label="item.fixedFlowName">
  20. <el-tooltip
  21. v-if="item.tips && item.disabled"
  22. class="box-item"
  23. effect="light"
  24. :content="item.tips "
  25. placement="right-end"
  26. >
  27. {{ item.fixedFlowName }}
  28. </el-tooltip>
  29. </el-option>
  30. </el-select>
  31. </el-form-item>
  32. <el-form-item v-if="diyProcessUser" label="任务人" prop="userTasks">
  33. <HcTasksUser
  34. :contract-id="contractId" :project-id="projectId" :type="type" :type-data="typeData"
  35. ui="w-full" :classify-type="classifyType" :table-owner="tableOwner" :node-id="formModel.ids ? formModel.ids : nodeId "
  36. :info-ids="infoIds" :data="dataInfo" @change="diyProcessUserChange"
  37. />
  38. </el-form-item>
  39. <el-form-item v-else label="任务人">
  40. <div class="form-item-div">{{ linkUserJoinString }}</div>
  41. </el-form-item>
  42. <el-form-item label="上报批次">
  43. <HcCounter v-model="formModel.batch" />
  44. </el-form-item>
  45. <el-form-item label="限定审批时间">
  46. <HcCounter v-model="formModel.restrictDay" text="(天)" />
  47. </el-form-item>
  48. </el-form>
  49. <template #footer>
  50. <div class="dialog-footer text-center">
  51. <el-button size="large" @click="cancelReportClick">取消</el-button>
  52. <el-button :loading="formReportLoading" hc-btn type="primary" @click="formReportClick">提交</el-button>
  53. </div>
  54. </template>
  55. </hc-new-dialog>
  56. </template>
  57. <script setup>
  58. import { onMounted, ref, watch } from 'vue'
  59. //import tasksFlowApi from '~api/tasks/flow'
  60. import { ApprovalApi, queryFixedFlow, queryFixedFlow1, queryFixedFlow3 } from '~api/other'
  61. import { arrIndex, arrToId, formValidate, getArrValue, isNullES } from 'js-fast-way'
  62. import { useAppStore } from '~src/store'
  63. const useAppState = useAppStore()
  64. const props = defineProps({
  65. show: {
  66. type: Boolean,
  67. default: false,
  68. },
  69. title: {
  70. type: String,
  71. default: '上报审批',
  72. },
  73. taskName: {
  74. type: String,
  75. default: '',
  76. },
  77. ids: {
  78. type: String,
  79. default: null,
  80. },
  81. projectId: {
  82. type: [String, Number],
  83. default: '',
  84. },
  85. contractId: {
  86. type: [String, Number],
  87. default: '',
  88. },
  89. flowContractId: {
  90. type: [String, Number],
  91. default: '',
  92. },
  93. classifyType: {
  94. type: [String, Number],
  95. default: '',
  96. },
  97. tableOwner: {
  98. type: [String, Number],
  99. default: '',
  100. },
  101. url: {
  102. type: [String, Number],
  103. default: '',
  104. },
  105. datas: {
  106. type: Array,
  107. default: () => ([]),
  108. },
  109. isDatas: {
  110. type: Boolean,
  111. default: false,
  112. },
  113. addition: {
  114. type: Object,
  115. default: () => ({}),
  116. },
  117. type: { //first,log,wbs
  118. type: [String, Number],
  119. default: '',
  120. },
  121. typeData: {
  122. type: [String, Number, Array, Object],
  123. default: '',
  124. },
  125. trialSelfInspectionRecordId: {
  126. type: [String, Number],
  127. default: '',
  128. },
  129. nodeId:{
  130. type: [String, Number],
  131. default: '',
  132. },
  133. reportArr: {
  134. type: Array,
  135. default: () => ([]),
  136. },
  137. })
  138. const emit = defineEmits(['hide', 'finish', 'tagClose'])
  139. //变量
  140. const isShow = ref(props.show)
  141. const projectId = ref(props.projectId)
  142. const contractId = ref(props.contractId)
  143. const flowContractId = ref(props.flowContractId)
  144. const classifyType = ref(props.classifyType)
  145. const tableOwner = ref(props.tableOwner)
  146. const ApiUrl = ref(props.url)
  147. const isTypes = ref(props.type)
  148. const typeDatas = ref(props.typeData)
  149. const reportDatas = ref(props.datas)
  150. const nodeId = ref(props.nodeId)
  151. const dataInfo = ref({
  152. projectId:props.projectId,
  153. contractId:props.contractId,
  154. })
  155. const contractId1 = ref(useAppState.contractId)
  156. //表单
  157. const formRef = ref(null)
  158. const processData = ref([])
  159. const formModel = ref({
  160. projectId: projectId.value,
  161. contractId: contractId.value,
  162. ids: props.ids,
  163. userTasks: null,
  164. taskName: props.taskName,
  165. taskContent: '',
  166. fixedFlowId: '',
  167. batch: 1,
  168. restrictDay: 1,
  169. trialSelfInspectionRecordId: props.trialSelfInspectionRecordId,
  170. ...props.addition,
  171. })
  172. const formRules = ref({
  173. taskContent: {
  174. required: false,
  175. trigger: 'blur',
  176. message: '请输入任务描述',
  177. },
  178. fixedFlowId: {
  179. required: true,
  180. trigger: 'blur',
  181. message: '请选择任务流程',
  182. },
  183. userTasks: {
  184. required: true,
  185. trigger: 'blur',
  186. message: '请选择任务人',
  187. },
  188. })
  189. //监听
  190. watch(() => [
  191. props.show,
  192. props.projectId,
  193. props.contractId,
  194. props.classifyType,
  195. props.tableOwner,
  196. props.taskName,
  197. props.ids,
  198. props.url,
  199. props.addition,
  200. props.type,
  201. props.typeData,
  202. props.datas,
  203. props.trialSelfInspectionRecordId,
  204. props.nodeId,
  205. props.flowContractId,
  206. ], ([val, pid, cid, cla, tab, name, ids, url, addition, type, typeData, datas, trialSelfInspectionRecordId, nodeid, flowCid]) => {
  207. isShow.value = val
  208. projectId.value = pid
  209. contractId.value = cid
  210. classifyType.value = cla
  211. tableOwner.value = tab
  212. ApiUrl.value = url
  213. nodeId.value = nodeid
  214. dataInfo.value = {
  215. projectId:pid,
  216. contractId:cid,
  217. }
  218. //更新到表单数据
  219. formModel.value = {
  220. projectId: pid,
  221. contractId: cid,
  222. ids: ids,
  223. taskName: name,
  224. taskContent: '',
  225. fixedFlowId: '',
  226. batch: 1,
  227. restrictDay: 1,
  228. trialSelfInspectionRecordId: trialSelfInspectionRecordId,
  229. ...addition,
  230. }
  231. isTypes.value = type
  232. typeDatas.value = typeData
  233. reportDatas.value = datas
  234. flowContractId.value = flowCid
  235. if (val) {
  236. getProcessDatasApi()
  237. }
  238. })
  239. //渲染完成
  240. onMounted(() => {
  241. getProcessDatasApi()
  242. })
  243. const processDefaultData = [{ id: 0, fixedFlowName: '自定义流程', disabled: false }]
  244. const getProcessDatasApi = () => {
  245. if (isShow.value) {
  246. const type = isTypes.value
  247. if (type === 'wbs') {
  248. queryFixedFlowApi(type, typeDatas.value)
  249. } else if (type === 'query') {
  250. getProcessData(type, typeDatas.value)
  251. } else if (type === 'log' || type === 'first' ) {
  252. queryFixedFlowApi3(type, typeDatas.value)
  253. }
  254. }
  255. }
  256. //获取资料查询获取流程数据
  257. const infoIds = ref('')
  258. const linkUserJoinString = ref('')
  259. const getProcessData = async (type, datas) => {
  260. linkUserJoinString.value = ''
  261. let flowJson = {}
  262. if (type === 'first') {
  263. flowJson['firstId'] = datas
  264. } else if (type === 'log') {
  265. flowJson['theLogPrimaryKeyId'] = datas
  266. } else if (type === 'wbs' || type === 'query') {
  267. flowJson['privatePKeyId'] = datas
  268. }
  269. infoIds.value = arrToId(reportDatas.value)
  270. const cid = isNullES(flowContractId.value) ? contractId.value : flowContractId.value
  271. const { error, code, data } = await queryFixedFlow1({
  272. projectId: projectId.value,
  273. contractId: contractId.value,
  274. contractIdRelation:flowContractId.value,
  275. nodeId:nodeId.value,
  276. classifyType:classifyType.value,
  277. tableOwner:tableOwner.value,
  278. infoIds:infoIds.value,
  279. ...flowJson,
  280. })
  281. if (!error && code === 200) {
  282. const arr = getArrValue(data['records'])
  283. processData.value = [...processDefaultData, ...arr]
  284. } else {
  285. processData.value = processDefaultData
  286. }
  287. }
  288. //获取符合条件的预设流程(三大填报页、日志列表的批量上报、首件列表的批量上报)
  289. const queryFixedFlowApi = async (type, datas) => {
  290. let flowJson = {}
  291. if (type === 'first') {
  292. flowJson['firstId'] = datas
  293. } else if (type === 'log') {
  294. flowJson['theLogPrimaryKeyId'] = datas
  295. } else if (type === 'wbs') {
  296. flowJson['privatePKeyId'] = datas
  297. }
  298. //请求数据
  299. linkUserJoinString.value = ''
  300. const cid = isNullES(flowContractId.value) ? contractId.value : flowContractId.value
  301. const { error, code, data, msg } = await queryFixedFlow({
  302. projectId: projectId.value,
  303. // contractId: cid,
  304. contractId: contractId1.value,
  305. contractIdRelation:flowContractId.value,
  306. ...flowJson,
  307. nodeId:formModel.value.ids,
  308. classifyType:classifyType.value,
  309. tableOwner:tableOwner.value,
  310. })
  311. if (!error && code === 200) {
  312. const arr = getArrValue(data['records'])
  313. processData.value = [...processDefaultData, ...arr]
  314. } else {
  315. window.$message.error(msg)
  316. processData.value = processDefaultData
  317. }
  318. }
  319. //日志填报获取流程数据
  320. const queryFixedFlowApi3 = async (type, datas) => {
  321. let flowJson = {}
  322. if (type === 'first') {
  323. flowJson['firstId'] = datas
  324. } else if (type === 'log') {
  325. // flowJson['theLogPrimaryKeyId'] = datas
  326. flowJson['theLogPrimaryKeyId'] = formModel.value.ids
  327. } else if (type === 'wbs') {
  328. flowJson['privatePKeyId'] = datas
  329. }
  330. //请求数据
  331. linkUserJoinString.value = ''
  332. const cid = isNullES(flowContractId.value) ? contractId.value : flowContractId.value
  333. const { error, code, data, msg } = await queryFixedFlow3({
  334. projectId: projectId.value,
  335. contractId: contractId.value,
  336. contractIdRelation:flowContractId.value,
  337. ...flowJson,
  338. // nodeId:formModel.value.ids,
  339. classifyType:classifyType.value,
  340. tableOwner:tableOwner.value,
  341. })
  342. if (!error && code === 200) {
  343. const arr = getArrValue(data['records'])
  344. processData.value = [...processDefaultData, ...arr]
  345. } else {
  346. window.$message.error(msg)
  347. processData.value = processDefaultData
  348. }
  349. }
  350. //流程数据切换
  351. const diyProcessUser = ref(false)
  352. const handleProcessValue = (val) => {
  353. if (val > 0) {
  354. diyProcessUser.value = false
  355. const list = processData.value
  356. const index = arrIndex(list, 'id', val)
  357. linkUserJoinString.value = list[index]?.linkUserJoinString
  358. } else {
  359. linkUserJoinString.value = ''
  360. diyProcessUser.value = true
  361. }
  362. }
  363. //自定义流程任务人选择完毕
  364. const diyProcessUserChange = (user) => {
  365. formModel.value.userTasks = user
  366. }
  367. //审批内容的标签移除
  368. const taskTagClose = (index) => {
  369. reportDatas.value.splice(index, 1)
  370. emit('tagClose', index)
  371. if (reportDatas.value.length <= 0) {
  372. window.$message?.warning('请重新选择要上报的内容')
  373. cancelReportClick()
  374. }
  375. }
  376. //取消
  377. const cancelReportClick = () => {
  378. linkUserJoinString.value = ''
  379. isShow.value = false
  380. emit('hide', false)
  381. }
  382. //上报
  383. const formReportClick = async () => {
  384. const res = await formValidate(formRef.value)
  385. if (res) await batchApprovalApi()
  386. }
  387. //上报请求
  388. const formReportLoading = ref(false)
  389. const batchApprovalApi = async () => {
  390. formReportLoading.value = true
  391. //发起请求
  392. const { error, code, data } = await ApprovalApi(ApiUrl.value, {
  393. projectId: projectId.value,
  394. contractId: contractId.value,
  395. ...formModel.value,
  396. })
  397. linkUserJoinString.value = ''
  398. formReportLoading.value = false
  399. if (!error && code === 200) {
  400. isShow.value = false
  401. window.$message?.success('上报成功')
  402. emit('hide', false)
  403. emit('finish', data)
  404. } else {
  405. processData.value = []
  406. }
  407. }
  408. </script>
  409. <style lang="scss">
  410. .task-tag-data-box {
  411. position: relative;
  412. border: 1px solid #e0e0e6;
  413. border-radius: 4px;
  414. padding: 5px;
  415. min-height: 40px;
  416. display: flex;
  417. align-items: center;
  418. flex-flow: row wrap;
  419. width: 100%;
  420. .el-tag {
  421. margin: 5px;
  422. }
  423. }
  424. </style>