index.vue 14 KB

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