index.vue 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. <template>
  2. <el-dialog v-model="isShow" :title="title" width="47rem" class="hc-modal-border" draggable destroy-on-close @closed="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 label="审批内容" v-if="isDatas && reportDatas.length > 0">
  8. <div class="task-tag-data-box">
  9. <template v-for="(item,index) in reportDatas" :key="item.id">
  10. <el-tag type="info" size="default" closable @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 type="textarea" v-model="formModel.taskContent" placeholder="请输入任务描述" :autosize="{ minRows: 3, maxRows: 5 }"/>
  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" :label="item.fixedFlowName" :disabled="item.disabled" :value="item.id"/>
  20. </el-select>
  21. </el-form-item>
  22. <el-form-item label="任务人" prop="userTasks" v-if="diyProcessUser">
  23. <HcTasksUser ui="w-full" :projectId="projectId" :contractId="contractId" :type="type" :typeData="typeData" @change="diyProcessUserChange"/>
  24. </el-form-item>
  25. <el-form-item label="任务人" v-else>
  26. <div class="form-item-div">{{linkUserJoinString}}</div>
  27. </el-form-item>
  28. <el-form-item label="上报批次">
  29. <HcCounter v-model:value="formModel.batch" @update:modelValue="batchUpdateValue"/>
  30. </el-form-item>
  31. <el-form-item label="限定审批时间">
  32. <HcCounter v-model:value="formModel.restrictDay" text="(天)" @update:modelValue="restrictDayUpdateValue"/>
  33. </el-form-item>
  34. </el-form>
  35. <template #footer>
  36. <div class="dialog-footer">
  37. <el-button size="large" @click="cancelReportClick">取消</el-button>
  38. <el-button type="primary" hc-btn :loading="formReportLoading" @click="formReportClick">提交</el-button>
  39. </div>
  40. </template>
  41. </el-dialog>
  42. </template>
  43. <script setup>
  44. import {ref,watch,onMounted} from "vue";
  45. import tasksFlowApi from '~api/tasks/flow';
  46. import {ApprovalApi,queryFixedFlow} from '~api/other';
  47. import {getArrValue,getIndex,formValidate} from "vue-utils-plus"
  48. const props = defineProps({
  49. show: {
  50. type: Boolean,
  51. default: false
  52. },
  53. title: {
  54. type: String,
  55. default: '上报审批'
  56. },
  57. taskName: {
  58. type: String,
  59. default: ''
  60. },
  61. ids: {
  62. type: String,
  63. default: null
  64. },
  65. projectId: {
  66. type: [String,Number],
  67. default: ''
  68. },
  69. contractId: {
  70. type: [String,Number],
  71. default: ''
  72. },
  73. url: {
  74. type: [String,Number],
  75. default: ''
  76. },
  77. datas: {
  78. type: Array,
  79. default: () => ([])
  80. },
  81. isDatas: {
  82. type: Boolean,
  83. default: false
  84. },
  85. addition: {
  86. type: Object,
  87. default: () => ({})
  88. },
  89. type: { //first,log,wbs
  90. type: [String,Number],
  91. default: ''
  92. },
  93. typeData: {
  94. type: [String, Number, Array, Object],
  95. default: ''
  96. },
  97. trialSelfInspectionRecordId:{
  98. type: [String,Number],
  99. default: ''
  100. }
  101. })
  102. //变量
  103. const isShow = ref(props.show)
  104. const projectId = ref(props.projectId)
  105. const contractId = ref(props.contractId)
  106. const ApiUrl = ref(props.url)
  107. const isTypes = ref(props.type)
  108. const typeDatas = ref(props.typeData)
  109. const reportDatas = ref(props.datas)
  110. //表单
  111. const formRef = ref(null)
  112. const processData = ref([])
  113. const formModel = ref({
  114. projectId: projectId.value, contractId: contractId.value, ids: props.ids, userTasks: null,
  115. taskName: props.taskName, taskContent: '', fixedFlowId: '', batch: 1, restrictDay: 1,trialSelfInspectionRecordId:props.trialSelfInspectionRecordId,
  116. ...props.addition
  117. })
  118. const formRules = ref({
  119. taskContent: {
  120. required: false,
  121. trigger: "blur",
  122. message: "请输入任务描述"
  123. },
  124. fixedFlowId: {
  125. required: true,
  126. trigger: "blur",
  127. message: "请选择任务流程"
  128. },
  129. userTasks: {
  130. required: true,
  131. trigger: "blur",
  132. message: "请选择任务人"
  133. }
  134. })
  135. //监听
  136. watch(() => [
  137. props.show,
  138. props.projectId,
  139. props.contractId,
  140. props.taskName,
  141. props.ids,
  142. props.url,
  143. props.addition,
  144. props.type,
  145. props.typeData,
  146. props.datas,
  147. props.trialSelfInspectionRecordId
  148. ], ([val,pid,cid,name,ids,url,addition, type, typeData, datas,trialSelfInspectionRecordId]) => {
  149. isShow.value = val
  150. projectId.value = pid
  151. contractId.value = cid
  152. ApiUrl.value = url
  153. //更新到表单数据
  154. formModel.value = {
  155. projectId: pid, contractId: cid, ids: ids, taskName: name,
  156. taskContent: '', fixedFlowId: '', batch: 1, restrictDay: 1,trialSelfInspectionRecordId:trialSelfInspectionRecordId,
  157. ...addition
  158. }
  159. isTypes.value = type
  160. typeDatas.value = typeData
  161. reportDatas.value = datas
  162. if (val) {
  163. getProcessDatasApi()
  164. }
  165. })
  166. //渲染完成
  167. onMounted(() => {
  168. getProcessDatasApi()
  169. })
  170. const processDefaultData = [{ id: 0, fixedFlowName: '自定义流程', disabled: false}]
  171. const getProcessDatasApi = () => {
  172. if (isShow.value) {
  173. const type = isTypes.value
  174. if (type === 'first' || type === 'log' || type === 'wbs') {
  175. queryFixedFlowApi(type, typeDatas.value)
  176. } else {
  177. getProcessData()
  178. }
  179. }
  180. }
  181. //获取流程数据
  182. const linkUserJoinString = ref('')
  183. const getProcessData = async () => {
  184. linkUserJoinString.value = ''
  185. const { error, code, data } = await tasksFlowApi.getPageData({
  186. projectId: projectId.value,
  187. contractId: contractId.value,
  188. current: 1, size: 100
  189. })
  190. if (!error && code === 200) {
  191. const arr = getArrValue(data['records'])
  192. processData.value = [...processDefaultData, ...arr]
  193. } else {
  194. processData.value = processDefaultData
  195. }
  196. }
  197. //获取符合条件的预设流程(三大填报页、日志列表的批量上报、首件列表的批量上报)
  198. const queryFixedFlowApi = async (type, datas) => {
  199. let flowJson = {}
  200. if (type === 'first') {
  201. flowJson['firstId'] = datas
  202. } else if (type === 'log') {
  203. flowJson['theLogPrimaryKeyId'] = datas
  204. } else if (type === 'wbs') {
  205. flowJson['privatePKeyId'] = datas
  206. }
  207. //请求数据
  208. linkUserJoinString.value = ''
  209. const { error, code, data } = await queryFixedFlow({
  210. projectId: projectId.value,
  211. contractId: contractId.value,
  212. ...flowJson
  213. })
  214. if (!error && code === 200) {
  215. const arr = getArrValue(data['records'])
  216. processData.value = [...processDefaultData, ...arr]
  217. } else {
  218. processData.value = processDefaultData
  219. }
  220. }
  221. //流程数据切换
  222. const diyProcessUser = ref(false)
  223. const handleProcessValue = (val) => {
  224. if (val > 0) {
  225. diyProcessUser.value = false
  226. const list = processData.value
  227. const index = getIndex(list, 'id', val)
  228. linkUserJoinString.value = list[index]?.linkUserJoinString
  229. } else {
  230. linkUserJoinString.value = ''
  231. diyProcessUser.value = true
  232. }
  233. }
  234. //自定义流程任务人选择完毕
  235. const diyProcessUserChange = (user) => {
  236. formModel.value.userTasks = user
  237. }
  238. //上报批次改变
  239. const batchUpdateValue = (val) => {
  240. formModel.value.batch = val
  241. }
  242. //上报批次改变
  243. const restrictDayUpdateValue = (val) => {
  244. formModel.value.restrictDay = val
  245. }
  246. const emit = defineEmits(['hide','finish', 'tagClose'])
  247. //审批内容的标签移除
  248. const taskTagClose = (index) => {
  249. reportDatas.value.splice(index, 1)
  250. emit('tagClose', index)
  251. if (reportDatas.value.length <= 0) {
  252. window.$message?.warning('请重新选择要上报的内容')
  253. cancelReportClick()
  254. }
  255. }
  256. //取消
  257. const cancelReportClick = () => {
  258. linkUserJoinString.value = ''
  259. isShow.value = false
  260. emit('hide', false)
  261. }
  262. //上报
  263. const formReportClick = async () => {
  264. const res = await formValidate(formRef.value)
  265. if (res) await batchApprovalApi()
  266. }
  267. //上报请求
  268. const formReportLoading = ref(false)
  269. const batchApprovalApi = async () => {
  270. formReportLoading.value = true
  271. //发起请求
  272. const { error, code, data } = await ApprovalApi(ApiUrl.value, {
  273. projectId: projectId.value,
  274. contractId: contractId.value,
  275. ...formModel.value
  276. })
  277. linkUserJoinString.value = ''
  278. formReportLoading.value = false
  279. if (!error && code === 200) {
  280. isShow.value = false
  281. window.$message?.success('上报成功')
  282. emit('hide', false)
  283. emit('finish', data)
  284. } else {
  285. processData.value = []
  286. }
  287. }
  288. </script>
  289. <style lang="scss" >
  290. .task-tag-data-box {
  291. position: relative;
  292. border: 1px solid #e0e0e6;
  293. border-radius: 4px;
  294. padding: 5px;
  295. min-height: 40px;
  296. display: flex;
  297. align-items: center;
  298. flex-flow: row wrap;
  299. width: 100%;
  300. .el-tag {
  301. margin: 5px;
  302. }
  303. }
  304. </style>