index.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478
  1. <template>
  2. <div :class="ui" class="hc-tasks-user">
  3. <div class="tasks-user-box">
  4. <div class="tag-user-list" @click="showModalClick">
  5. <template v-for="(item, index) in UserDataList" :key="index">
  6. <el-tag>{{ setCheckboxUserName(item) }}</el-tag>
  7. <HcIcon v-if="(UserDataList.length - 1) > index" name="arrow-right" ui="arrow-icon-tag" />
  8. </template>
  9. <div v-if="UserDataList.length <= 0" class="tasks-placeholder">
  10. 点击这里选择任务人
  11. </div>
  12. </div>
  13. </div>
  14. <!-- 选择任务人 -->
  15. <el-dialog
  16. v-model="showModal" class="hc-modal-border hc-modal-nop" destroy-on-close draggable
  17. title="选择任务人"
  18. width="62rem"
  19. append-to-body
  20. >
  21. <div class="hc-tasks-user-modal-content-box">
  22. <div class="tree-box">
  23. <el-scrollbar>
  24. <ElTree
  25. v-if="isShowTree"
  26. :data="ElTreeData" :default-expanded-keys="[0]" :props="ElTreeProps" accordion
  27. class="hc-tree-node-box" highlight-current node-key="roleId"
  28. @node-click="ElTreeNodeClick"
  29. />
  30. </el-scrollbar>
  31. </div>
  32. <div class="user-box">
  33. <div class="y-user-list-box">
  34. <div class="title-box">
  35. <div class="title">
  36. 可选择
  37. </div>
  38. </div>
  39. <div class="user-list">
  40. <el-scrollbar>
  41. <el-checkbox-group v-model="checkboxUserList">
  42. <template v-for="item in signUserList">
  43. <div class="user-item checkbox-li">
  44. <el-checkbox
  45. :label="`${item.certificateUserName}-${item.certificateUserId}`"
  46. >
  47. <div class="item-user-name">
  48. {{ item.certificateUserName }}
  49. </div>
  50. </el-checkbox>
  51. </div>
  52. </template>
  53. </el-checkbox-group>
  54. </el-scrollbar>
  55. </div>
  56. </div>
  57. <div class="s-user-list-box">
  58. <div class="title-box">
  59. <div class="title">
  60. 已选择({{ checkboxUserList.length }})
  61. </div>
  62. <el-button plain size="small" @click="sequenceModal = true">
  63. 调整顺序
  64. </el-button>
  65. </div>
  66. <div class="user-list">
  67. <el-scrollbar>
  68. <template v-for="(item, index) in checkboxUserList" :key="index">
  69. <el-tag closable @close="delCheckboxUser(index)">
  70. {{ setCheckboxUserName(item) }}
  71. </el-tag>
  72. </template>
  73. </el-scrollbar>
  74. </div>
  75. </div>
  76. </div>
  77. </div>
  78. <template #footer>
  79. <div class="dialog-footer">
  80. <el-button size="large" @click="showModal = false">
  81. <HcIcon name="close" />
  82. <span>取消</span>
  83. </el-button>
  84. <el-button :loading="sureSignUserLoading" hc-btn type="primary" @click="sureSignUserClick">
  85. <HcIcon name="check" />
  86. <span>确定</span>
  87. </el-button>
  88. </div>
  89. </template>
  90. </el-dialog>
  91. <!-- 调整顺序 -->
  92. <el-dialog
  93. v-model="sequenceModal" class="hc-modal-border" destroy-on-close draggable title="调整顺序" append-to-body
  94. width="38rem"
  95. >
  96. <el-alert :closable="false" title="可拖动排序,也可在后面点击图标,切换排序" type="warning" />
  97. <div class="sort-node-body-box list-group header">
  98. <div class="list-group-item">
  99. <div class="index-box">
  100. 序号
  101. </div>
  102. <div class="title-box">
  103. 任务人
  104. </div>
  105. <div class="icon-box">
  106. 排序
  107. </div>
  108. </div>
  109. </div>
  110. <Draggable
  111. :list="checkboxUserList" class="sort-node-body-box list-group" ghost-class="ghost" item-key="id"
  112. @end="sortNodeDrag = false" @start="sortNodeDrag = true"
  113. >
  114. <template #item="{ element, index }">
  115. <div class="list-group-item">
  116. <div class="index-box">
  117. {{ index + 1 }}
  118. </div>
  119. <div class="title-box">
  120. {{ setCheckboxUserName(element) }}
  121. </div>
  122. <div class="icon-box">
  123. <span class="icon" @click="downSortClick(index)">
  124. <HcIcon name="arrow-down" ui="text-lg" />
  125. </span>
  126. <span class="icon" @click="upSortClick(index)">
  127. <HcIcon name="arrow-up" ui="text-lg" />
  128. </span>
  129. </div>
  130. </div>
  131. </template>
  132. </Draggable>
  133. <template #footer>
  134. <div class="dialog-footer">
  135. <el-button size="large" @click="sequenceModal = false">
  136. 取消
  137. </el-button>
  138. <el-button hc-btn type="primary" @click="sequenceModal = false">
  139. 确认
  140. </el-button>
  141. </div>
  142. </template>
  143. </el-dialog>
  144. </div>
  145. </template>
  146. <script setup>
  147. import { onMounted, ref, watch } from 'vue'
  148. import tasksFlowApi from '~api/tasks/flow'
  149. import { deepClone, getArrValue } from 'js-fast-way'
  150. import { checkCustomFlowUserIsEVisaPermissions, checkCustomFlowUserIsEVisaPermissionsquery } from '~api/other'
  151. import Draggable from 'vuedraggable'
  152. //参数
  153. const props = defineProps({
  154. ui: {
  155. type: String,
  156. default: '',
  157. },
  158. //选中的用户数组
  159. users: {
  160. type: String,
  161. default: '',
  162. },
  163. projectId: {
  164. type: [String, Number],
  165. default: '',
  166. },
  167. contractId: {
  168. type: [String, Number],
  169. default: '',
  170. },
  171. type: { //first,log,wbs
  172. type: [String, Number],
  173. default: '',
  174. },
  175. typeData: {
  176. type: [String, Number, Array, Object],
  177. default: '',
  178. },
  179. classifyType: {
  180. type: [String, Number],
  181. default: '',
  182. },
  183. tableOwner: {
  184. type: [String, Number],
  185. default: '',
  186. },
  187. nodeId: {
  188. type: [String, Number],
  189. default: '', //选中节点nodeid
  190. },
  191. infoIds:{
  192. type: [String, Number],
  193. default: '', //上报任务ID
  194. },
  195. })
  196. //事件
  197. const emit = defineEmits(['change'])
  198. //变量
  199. const showModal = ref(false)
  200. const sequenceModal = ref(false)
  201. const checkboxUserList = ref([])
  202. const UserDataList = ref([])
  203. const projectId = ref(props.projectId)
  204. const contractId = ref(props.contractId)
  205. const isTypes = ref(props.type)
  206. const typeDatas = ref(props.typeData)
  207. const classifyType = ref(props.classifyType)
  208. const tableOwner = ref(props.tableOwner)
  209. const nodeId = ref(props.nodeId)
  210. const infoIds = ref(props.infoIds)
  211. //树数据
  212. const ElTreeProps = { children: 'childRoleList', label: 'roleName' }
  213. const ElTreeData = ref([{
  214. roleName: '全部人员',
  215. roleId: 0,
  216. childRoleList: [],
  217. signPfxFileList: [],
  218. }])
  219. const isShowTree = ref(true)
  220. //监听
  221. watch(() => [
  222. props.users,
  223. props.projectId,
  224. props.contractId,
  225. props.type,
  226. props.typeData,
  227. props.classifyType,
  228. props.tableOwner,
  229. props.nodeId,
  230. props.infoIds,
  231. ], ([users, pid, cid, type, data, cla, tab, noid, infoid]) => {
  232. projectId.value = pid
  233. contractId.value = cid
  234. isTypes.value = type
  235. typeDatas.value = data
  236. setUserDataList(users)
  237. classifyType.value = cla
  238. tableOwner.value = tab
  239. nodeId.value = noid
  240. infoIds.value = infoid
  241. })
  242. //渲染完成
  243. onMounted(() => {
  244. setUserDataList(props.users)
  245. queryAllRoleList()
  246. })
  247. //处理用户数据
  248. const setUserDataList = (users) => {
  249. if (users) {
  250. const usersArr = users.split(',')
  251. UserDataList.value = usersArr
  252. checkboxUserList.value = usersArr
  253. } else {
  254. UserDataList.value = []
  255. checkboxUserList.value = []
  256. }
  257. }
  258. //展开弹窗
  259. const showModalClick = () => {
  260. showModal.value = true
  261. }
  262. //获取系统所有角色划分
  263. const signUserList = ref([])
  264. const queryAllRoleList = async () => {
  265. isShowTree.value = false
  266. const { error, code, data } = await tasksFlowApi.queryAllRoleList({
  267. contractId: contractId.value,
  268. })
  269. isShowTree.value = true
  270. //处理数据
  271. if (!error && code === 200) {
  272. let signList = [], dataArr = getArrValue(data)
  273. ElTreeData.value[0].childRoleList = dataArr
  274. if (dataArr.length > 0) {
  275. dataArr.forEach(item => {
  276. signList = signList.concat(item.signPfxFileList)
  277. })
  278. }
  279. ElTreeData.value[0].signPfxFileList = signList
  280. signUserList.value = signList
  281. } else {
  282. signUserList.value = []
  283. ElTreeData.value[0].childRoleList = []
  284. ElTreeData.value[0].signPfxFileList = []
  285. }
  286. }
  287. //树被点击
  288. const ElTreeNodeClick = (data) => {
  289. signUserList.value = getArrValue(data?.signPfxFileList)
  290. }
  291. //处理已选择的用户问题
  292. const setCheckboxUserName = (item) => {
  293. if (item) {
  294. const itemArr = item.split('-')
  295. if (itemArr.length > 0 && itemArr[0]) {
  296. return itemArr[0]
  297. } else {
  298. return ''
  299. }
  300. } else {
  301. return ''
  302. }
  303. }
  304. //删除已选择的用户
  305. const delCheckboxUser = (index) => {
  306. checkboxUserList.value.splice(index, 1)
  307. }
  308. //排序
  309. const sortNodeDrag = ref(false)
  310. //向下
  311. const downSortClick = (index) => {
  312. const indexs = index + 1
  313. const data = checkboxUserList.value
  314. if (indexs !== data.length) {
  315. const tmp = data.splice(indexs, 1)
  316. checkboxUserList.value.splice(index, 0, tmp[0])
  317. } else {
  318. window?.$message?.warning('已经处于置底,无法下移')
  319. }
  320. }
  321. //向上
  322. const upSortClick = (index) => {
  323. const data = checkboxUserList.value || []
  324. if (index !== 0) {
  325. const tmp = data.splice(index - 1, 1)
  326. checkboxUserList.value.splice(index, 0, tmp[0])
  327. } else {
  328. window?.$message?.warning('已经处于置顶,无法上移')
  329. }
  330. }
  331. //确认选择
  332. const sureSignUserLoading = ref(false)
  333. const sureSignUserClick = () => {
  334. let type = isTypes.value, flowJson = {}, newUser = [], newUserId = [], users = ''
  335. const dataList = deepClone(checkboxUserList.value)
  336. UserDataList.value = dataList
  337. if (dataList.length > 0) {
  338. sureSignUserLoading.value = true
  339. //判断类型
  340. if (type === 'first') {
  341. flowJson['firstId'] = typeDatas.value
  342. } else if (type === 'log') {
  343. flowJson['theLogPrimaryKeyId'] = typeDatas.value
  344. } else if (type === 'wbs') {
  345. flowJson['privatePKeyId'] = typeDatas.value
  346. } else if (type === 'query') {
  347. flowJson['privatePKeyId'] = typeDatas.value
  348. }
  349. //封装数据
  350. dataList.forEach(item => {
  351. const itemArr = item.split('-')
  352. if (itemArr.length > 0 && itemArr[0]) {
  353. users = users ? `${users},${item}` : item
  354. newUser.push({
  355. userId: itemArr[1],
  356. userName: itemArr[0],
  357. })
  358. newUserId.push(itemArr[1])
  359. }
  360. })
  361. //效验人员
  362. if (type === 'first' || type === 'log' || type === 'wbs') {
  363. getCheckCustomFlowUserIsEVisaPermissions(flowJson, newUser, newUserId, users)
  364. } else if (type === 'query') {
  365. getCheckCustomFlowUserIsEVisaPermissionsquery(flowJson, newUser, newUserId, users)
  366. } else {
  367. showModal.value = false
  368. sureSignUserLoading.value = false
  369. emit('change', newUser, newUserId, users)
  370. }
  371. } else {
  372. window.$message?.warning('请先选择任务人员,或点击取消')
  373. }
  374. }
  375. //检查所选的流程环节处理人是否具有审批权限(三大填报页、日志列表的批量上报、首件列表的批量上报)
  376. const getCheckCustomFlowUserIsEVisaPermissions = async (flowJson, newUser, newUserId, users) => {
  377. const { error, code, data } = await checkCustomFlowUserIsEVisaPermissions({
  378. projectId: projectId.value,
  379. contractId: contractId.value,
  380. customFlowUserList: newUserId,
  381. ...flowJson,
  382. classifyType:classifyType.value,
  383. tableOwner:tableOwner.value,
  384. nodeId:nodeId.value,
  385. })
  386. //处理数据
  387. sureSignUserLoading.value = false
  388. if (!error && code === 200 && data === true) {
  389. showModal.value = false
  390. emit('change', newUser, newUserId, users)
  391. } else {
  392. emit('change', [], [], '')
  393. }
  394. }
  395. //资料查询页面
  396. const getCheckCustomFlowUserIsEVisaPermissionsquery = async (flowJson, newUser, newUserId, users) => {
  397. const { error, code, data } = await checkCustomFlowUserIsEVisaPermissionsquery({
  398. projectId: projectId.value,
  399. contractId: contractId.value,
  400. customFlowUserList: newUserId,
  401. ...flowJson,
  402. nodeId:nodeId.value,
  403. classifyType:classifyType.value,
  404. tableOwner:tableOwner.value,
  405. infoIds:infoIds.value,
  406. })
  407. //处理数据
  408. sureSignUserLoading.value = false
  409. if (!error && code === 200 && data === true) {
  410. showModal.value = false
  411. emit('change', newUser, newUserId, users)
  412. } else {
  413. emit('change', [], [], '')
  414. }
  415. }
  416. </script>
  417. <style lang="scss" scoped>
  418. @import './style.scss';
  419. </style>
  420. <style lang="scss">
  421. .hc-tasks-user .tasks-user-box .tag-user-list {
  422. .el-tag {
  423. --el-icon-size: 14px;
  424. padding: 0 10px;
  425. height: 26px;
  426. margin: 4px 0;
  427. }
  428. }
  429. .hc-tasks-user-modal-content-box {
  430. .checkbox-li .el-checkbox {
  431. width: 100%;
  432. .el-checkbox__input {
  433. position: absolute;
  434. right: 0;
  435. .el-checkbox__inner {
  436. width: 18px;
  437. height: 18px;
  438. &:after {
  439. height: 9px;
  440. left: 6px;
  441. top: 2px;
  442. }
  443. }
  444. }
  445. .el-checkbox__label {
  446. flex: 1;
  447. padding-left: 0;
  448. padding-right: 20px;
  449. }
  450. }
  451. .user-list {
  452. .el-tag {
  453. margin-right: 10px;
  454. margin-top: 12px;
  455. }
  456. }
  457. }
  458. </style>