index.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. <template>
  2. <hc-new-dialog v-model="isShow" :title="title" :widths="widths" @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 label="验收日期" prop="startDate">
  8. <el-date-picker v-model="formModel.startDate" type="date" class="block" value-format="YYYY-MM-DD" :clearable="false" />
  9. </el-form-item>
  10. <el-form-item v-if="isDatas && reportDatas.length > 0" label="申请内容">
  11. <!-- <div class="task-tag-data-box">
  12. <template v-for="(item, index) in reportDatas" :key="item.id">
  13. <el-tag type="info" size="default" closable @close="taskTagClose(index)">{{ item.name }}</el-tag>
  14. </template>
  15. </div> -->
  16. <div v-infinite-scroll="load" class="task-tag-data-box" style="overflow: auto">
  17. <template v-for="(item, index) in tableData" :key="index">
  18. <el-tag type="info" size="default" closable @close="taskTagClose(index)">{{ item?.name }}</el-tag>
  19. </template>
  20. </div>
  21. </el-form-item>
  22. <el-form-item label="上传附件">
  23. <HcFormUpload
  24. :src="formModel.attachmentPdfUrlName"
  25. @upload="formItemUpload"
  26. />
  27. </el-form-item>
  28. <el-form-item label="验收专家信息" prop="list">
  29. <HcReportExperts v-model="formModel.list" />
  30. </el-form-item>
  31. <el-form-item label="申请说明">
  32. <el-input v-model="formModel.taskContent" type="textarea" placeholder="请输入申请说明" :autosize="{ minRows: 3, maxRows: 5 }" />
  33. </el-form-item>
  34. <el-form-item label="任务流程" prop="fixedFlowId">
  35. <el-select v-model="formModel.fixedFlowId" block @change="handleProcessValue">
  36. <el-option v-for="item in processData" :label="item.fixedFlowName" :disabled="item.disabled" :value="item.id" />
  37. </el-select>
  38. </el-form-item>
  39. <el-form-item v-if="diyProcessUser" label="任务人" prop="userTasks">
  40. <HcTasksUser ui="w-full" :project-id="projectId" :contract-id="contractId" @change="diyProcessUserChange" />
  41. </el-form-item>
  42. <el-form-item v-else label="任务人">
  43. <div class="form-item-div">{{ linkUserJoinString }}</div>
  44. </el-form-item>
  45. </el-form>
  46. <template #footer>
  47. <div class="dialog-footer">
  48. <el-button size="large" @click="cancelReportClick">
  49. <HcIcon name="close" />
  50. <span>取消</span>
  51. </el-button>
  52. <el-button type="primary" hc-btn :loading="formReportLoading" @click="formReportClick">
  53. <HcIcon name="check" />
  54. <span>提交</span>
  55. </el-button>
  56. </div>
  57. </template>
  58. <HcUploadFile ref="HcUploadFileRef" :options="UploadFileOptions" @finish="HcUploadFileFinish" @success="HcUploadFileSuccess" />
  59. </hc-new-dialog>
  60. </template>
  61. <script setup>
  62. import { onMounted, ref, watch } from 'vue'
  63. import tasksFlowApi from '~api/tasks/flow'
  64. import { arrIndex, formValidate, getArrValue } from 'js-fast-way'
  65. import { getTokenHeader } from '~src/api/request/header'
  66. import initialgApi from '~api/initial/initial'
  67. const props = defineProps({
  68. show: {
  69. type: Boolean,
  70. default: false,
  71. },
  72. title: {
  73. type: String,
  74. default: '上报审批',
  75. },
  76. widths: {
  77. type: String,
  78. default: '47rem',
  79. },
  80. taskName: {
  81. type: String,
  82. default: '',
  83. },
  84. ids: {
  85. type: String,
  86. default: null,
  87. },
  88. projectId: {
  89. type: [String, Number],
  90. default: '',
  91. },
  92. contractId: {
  93. type: [String, Number],
  94. default: '',
  95. },
  96. url: {
  97. type: [String, Number],
  98. default: '',
  99. },
  100. datas: {
  101. type: Array,
  102. default: () => ([]),
  103. },
  104. isDatas: {
  105. type: Boolean,
  106. default: false,
  107. },
  108. addition: {
  109. type: Object,
  110. default: () => ({}),
  111. },
  112. })
  113. const emit = defineEmits(['hide', 'finish', 'tagClose'])
  114. //变量
  115. const isShow = ref(props.show)
  116. const projectId = ref(props.projectId)
  117. const contractId = ref(props.contractId)
  118. const ApiUrl = ref(props.url)
  119. const reportDatas = ref(props.datas)
  120. //表单
  121. const formRef = ref(null)
  122. const processData = ref([])
  123. const formModel = ref({
  124. projectId: projectId.value, contractId: contractId.value, archiveIds: props.ids, list: [],
  125. userTasks: null, taskName: props.taskName, fixedFlowId: '', ...props.addition,
  126. })
  127. const formRules = ref({
  128. startDate: {
  129. required: true,
  130. trigger: 'blur',
  131. message: '请选择验收日期',
  132. },
  133. list: {
  134. required: true,
  135. trigger: 'blur',
  136. message: '请完善专家信息',
  137. },
  138. fixedFlowId: {
  139. required: true,
  140. trigger: 'blur',
  141. message: '请选择任务流程',
  142. },
  143. userTasks: {
  144. required: true,
  145. trigger: 'blur',
  146. message: '请选择任务人',
  147. },
  148. })
  149. //监听
  150. watch(() => [
  151. props.show,
  152. props.projectId,
  153. props.taskName,
  154. props.ids,
  155. props.url,
  156. props.addition,
  157. props.datas,
  158. ], ([val, pid, name, ids, url, addition, datas]) => {
  159. isShow.value = val
  160. projectId.value = pid
  161. ApiUrl.value = url
  162. //更新到表单数据
  163. formModel.value = {
  164. projectId: pid, archiveIds: ids, taskName: name,
  165. taskContent: '', fixedFlowId: '', list: [],
  166. ...addition,
  167. }
  168. reportDatas.value = datas
  169. //判断数据长度有没有9个,有就先添加9个,没有直接获取所有数据
  170. if (reportDatas.value.length > 9) {
  171. for (let i = 0;i < needle.value ;i++) {
  172. tableData.value[i] = reportDatas.value[i]
  173. }
  174. } else {
  175. tableData.value = reportDatas.value
  176. }
  177. if (val) {
  178. getProcessDatasApi()
  179. }
  180. })
  181. //渲染完成
  182. onMounted(() => {
  183. getProcessDatasApi()
  184. })
  185. const processDefaultData = [{ id: 0, fixedFlowName: '自定义流程', disabled: false }]
  186. const getProcessDatasApi = () => {
  187. if (isShow.value) {
  188. getProcessData()
  189. }
  190. }
  191. //获取流程数据
  192. const linkUserJoinString = ref('')
  193. const getProcessData = async () => {
  194. linkUserJoinString.value = ''
  195. const { error, code, data } = await tasksFlowApi.getPageData({
  196. projectId: projectId.value,
  197. contractId: contractId.value,
  198. current: 1, size: 100,
  199. })
  200. if (!error && code === 200) {
  201. const arr = getArrValue(data['records'])
  202. processData.value = [...processDefaultData, ...arr]
  203. } else {
  204. processData.value = processDefaultData
  205. }
  206. }
  207. //流程数据切换
  208. const diyProcessUser = ref(false)
  209. const handleProcessValue = (val) => {
  210. if (val > 0) {
  211. diyProcessUser.value = false
  212. const list = processData.value
  213. const index = arrIndex(list, 'id', val)
  214. linkUserJoinString.value = list[index]?.linkUserJoinString
  215. } else {
  216. linkUserJoinString.value = ''
  217. diyProcessUser.value = true
  218. }
  219. }
  220. //自定义流程任务人选择完毕
  221. const diyProcessUserChange = (user) => {
  222. formModel.value.userTasks = user
  223. }
  224. //审批内容的标签移除
  225. const taskTagClose = (index) => {
  226. reportDatas.value.splice(index, 1)
  227. tableData.value.splice(index, 1)
  228. emit('tagClose', index)
  229. if (reportDatas.value.length <= 0) {
  230. window.$message?.warning('请重新选择要上报的内容')
  231. cancelReportClick()
  232. }
  233. }
  234. //取消
  235. const cancelReportClick = () => {
  236. linkUserJoinString.value = ''
  237. isShow.value = false
  238. needle.value = 10
  239. emit('hide', false)
  240. }
  241. //上报
  242. const formReportClick = async () => {
  243. const res = await formValidate(formRef.value)
  244. if (res) await batchApprovalApi()
  245. }
  246. //上报请求
  247. const formReportLoading = ref(false)
  248. const batchApprovalApi = async () => {
  249. console.log(formModel.value)
  250. formReportLoading.value = true
  251. //发起请求
  252. const { error, code, data } = await initialgApi.saveApply (formModel.value)
  253. linkUserJoinString.value = ''
  254. formReportLoading.value = false
  255. if (!error && code === 200) {
  256. isShow.value = false
  257. window.$message?.success('上报成功')
  258. emit('hide', false)
  259. emit('finish', data)
  260. } else {
  261. processData.value = []
  262. }
  263. }
  264. //上传配置
  265. const UploadFileOptions = {
  266. //此处设置header
  267. headers: getTokenHeader(),
  268. accept:'application/pdf,.doc,.docx,application/msword',
  269. accept_tip: 'PDF、Word格式文件',
  270. }
  271. const HcUploadFileRef = ref(null)
  272. //上传
  273. const formItemUpload = () => {
  274. HcUploadFileRef.value?.selectFile()
  275. }
  276. // 文件全部上传完成
  277. const HcUploadFileFinish = () => {
  278. HcUploadFileRef?.value.setModalShow(false)
  279. }
  280. // 文件全部上传成功
  281. const HcUploadFileSuccess = (res) => {
  282. formModel.value.attachmentPdfUrl = res.resData.link
  283. formModel.value.attachmentPdfUrlName = res.resData.originalName
  284. }
  285. const tableData = ref([])
  286. const needle = ref(10)
  287. const load = async () => {
  288. const res = await queryData()
  289. if (res) {
  290. tableData.value = res
  291. }
  292. }
  293. const queryData = async ()=>{
  294. console.log('查询数据')
  295. let ortab = tableData.value
  296. if (needle.value < reportDatas.value.length) {
  297. let pusharr = reportDatas.value.slice(needle.value, needle.value + 10)
  298. pusharr.forEach((ele)=>{
  299. ortab.push(ele)
  300. })
  301. needle.value = needle.value + 10
  302. return ortab
  303. }
  304. }
  305. </script>
  306. <style lang="scss">
  307. .task-tag-data-box {
  308. position: relative;
  309. border: 1px solid #e0e0e6;
  310. border-radius: 4px;
  311. padding: 5px;
  312. min-height: 40px;
  313. display: flex;
  314. align-items: center;
  315. flex-flow: row wrap;
  316. width: 100%;
  317. max-height: 300px;
  318. overflow-y: auto;
  319. overflow-x: hidden;
  320. .el-tag {
  321. margin: 5px;
  322. }
  323. }
  324. .hc-report-modal-form-item .hc-table-ref-box {
  325. margin-top: 14px;
  326. }
  327. </style>