UserGroup.vue 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. <template>
  2. <div class="user-group">
  3. <Search />
  4. <div class="user-list">
  5. <BasicTable
  6. :columns="userGroupCol"
  7. :data-source="userListData"
  8. :row-key="(row) => row.id"
  9. :action-column="actionColumn"
  10. :pagination="{
  11. total: total,
  12. pageSize: pagesize,
  13. currentPage: page,
  14. hideOnSinglePage: !userListData,
  15. }"
  16. :tableSetting="{
  17. size: false,
  18. redo: false,
  19. fullscreen: false,
  20. striped: false,
  21. setting: false,
  22. }"
  23. :striped="true"
  24. ref="tableRef"
  25. @page-num-change="handlePageNumChange"
  26. @page-size-change="handlePageSizeChange"
  27. >
  28. <template #tableTitle>
  29. <el-button type="primary" @click="handleCreateGroup" v-permission="{ action: [PERM_NOTICE.PERSONNEL_ADD] }">
  30. <img src="./img/create.png" style="margin-right: 8px" />新建人员分组
  31. </el-button>
  32. </template>
  33. <template #empty>
  34. <div class="empty-content flex flex-col items-center">
  35. <span class="empty-text">暂无数据</span>
  36. </div>
  37. </template>
  38. </BasicTable>
  39. <el-dialog
  40. v-model="errorVisible"
  41. title="无法删除"
  42. width="420"
  43. class="errorDialog"
  44. align-center
  45. :show-close="false"
  46. :close-on-click-modal="false"
  47. >
  48. <div class="title">该分组在“推送对象”中已被引用,如需删除,请先解除引用关系。</div>
  49. <div class="list">
  50. <div
  51. v-for="(item, index) in visibleRefGroup"
  52. :key="index"
  53. style="display: flex; align-items: center"
  54. >
  55. <span class="dot"></span>{{ getLabel(item.messageType) }}
  56. </div>
  57. </div>
  58. <div v-if="refGroup && refGroup.length > 3" @click="showAll = !showAll" class="more-button">
  59. {{ showAll ? '收起' : '更多' }}
  60. </div>
  61. <el-button type="primary" @click="errorVisible = false"> 已知晓 </el-button>
  62. </el-dialog>
  63. <el-drawer
  64. v-model="drawer"
  65. :title="drawerTitle"
  66. size="450"
  67. :close-on-click-modal="false"
  68. :destroy-on-close="true"
  69. >
  70. <GroupBoard @close="drawer = false" :drawer-title="drawerTitle" :form-data="formData!" />
  71. </el-drawer>
  72. </div>
  73. </div>
  74. </template>
  75. <script lang="ts" setup>
  76. import Search from './components/Search.vue';
  77. import GroupBoard from './components/GroupBoard.vue';
  78. import { h, ref, reactive, onMounted, computed } from 'vue';
  79. import { BasicTable, TableActionIcons, BasicColumn } from '@/components/Table';
  80. import { userGroupCol } from './overviewColumns';
  81. import userGroupList from './store/index';
  82. import { storeToRefs } from 'pinia';
  83. const userGroup = userGroupList();
  84. const { userListData, total, page, pagesize } = storeToRefs(userGroup);
  85. const { getUserGroup } = userGroup;
  86. import { verifyUserGroup, deleteUserGroup, getUserGroupDetail } from '@/api/message/person-group';
  87. import { FormData } from './type';
  88. import viewIcon from '@/assets/images/reportmessage/view.png';
  89. import editIcon from '@/assets/images/reportmessage/edit.png';
  90. import deleteIcon from '@/assets/images/reportmessage/delete.png';
  91. import { ElMessage, ElMessageBox } from 'element-plus';
  92. import { messageTypeName } from '@/views/message/constant';
  93. import { PERM_NOTICE } from '@/types/permission/constants';
  94. import { useUserStore } from '@/store/modules/user';
  95. const userStore = useUserStore();
  96. const drawer = ref(false);
  97. const drawerTitle = ref<string>('新建人员分组');
  98. const handleCreateGroup = () => {
  99. drawer.value = true;
  100. drawerTitle.value = '新建人员分组';
  101. };
  102. const getLabel = (messageType) => {
  103. const messageTypeLabel = messageTypeName.find((item) => item.value === messageType)?.label;
  104. return `${messageTypeLabel}`;
  105. };
  106. const errorVisible = ref<boolean>(false);
  107. const showAll = ref<boolean>(false);
  108. const refGroup = ref<Array<{ type: number; statisticType: number; messageType: number }>>();
  109. const actionColumn: BasicColumn = reactive({
  110. width: 224,
  111. title: '操作',
  112. prop: 'action',
  113. key: 'action',
  114. fixed: 'right',
  115. render(record) {
  116. return h(TableActionIcons as any, {
  117. space: 20,
  118. color: '#629bf9',
  119. iconStyle: 'img',
  120. size: 16,
  121. actionIcons: [
  122. {
  123. label: '查看',
  124. icon: viewIcon,
  125. onClick: handleView.bind(null, record.row),
  126. },
  127. {
  128. label: '编辑',
  129. icon: editIcon,
  130. onClick: handleEdit.bind(null, record.row),
  131. ifShow: userStore.checkPermission(PERM_NOTICE.PERSONNEL_ADD)
  132. },
  133. {
  134. label: '删除',
  135. icon: deleteIcon,
  136. onClick: handleDelete.bind(null, record.row),
  137. ifShow: userStore.checkPermission(PERM_NOTICE.PERSONNEL_DELETE)
  138. },
  139. ],
  140. });
  141. },
  142. });
  143. const handlePageNumChange = (pageNum) => {
  144. page.value = pageNum;
  145. getUserGroup();
  146. };
  147. const handlePageSizeChange = (size) => {
  148. pagesize.value = size;
  149. page.value = 1;
  150. getUserGroup();
  151. };
  152. const formData = ref<FormData>();
  153. const handleView = (record: Recordable) => {
  154. drawer.value = true;
  155. drawerTitle.value = '查看人员分组';
  156. getUserGroupDetail(record.id).then((res) => {
  157. formData.value = res;
  158. });
  159. };
  160. const handleEdit = (record: Recordable) => {
  161. drawer.value = true;
  162. drawerTitle.value = '编辑人员分组';
  163. getUserGroupDetail(record.id).then((res) => {
  164. formData.value = res;
  165. });
  166. };
  167. const handleDelete = (record: Recordable) => {
  168. ElMessageBox.confirm('删除之后,该分组将无法恢复', '请确认是否删除', {
  169. confirmButtonText: '确定',
  170. cancelButtonText: '取消',
  171. type: 'warning',
  172. })
  173. .then(() => {
  174. verifyUserGroup(record.id).then((res) => {
  175. const uniqueRes = Array.from(
  176. new Map(res.map((item) => [item.messageType, item])).values(),
  177. ) as any;
  178. refGroup.value = uniqueRes;
  179. if (refGroup.value?.length! > 0) {
  180. errorVisible.value = true;
  181. } else {
  182. deleteUserGroup(record.id).then(() => {
  183. ElMessage.success('删除成功');
  184. getUserGroup();
  185. });
  186. }
  187. });
  188. })
  189. .catch(() => {});
  190. };
  191. const visibleRefGroup = computed(() => {
  192. return showAll.value ? refGroup.value : refGroup.value!.slice(0, 3);
  193. });
  194. onMounted(() => {
  195. getUserGroup();
  196. });
  197. </script>
  198. <style lang="scss" scoped>
  199. .user-group {
  200. position: relative;
  201. height: calc(100vh - 64px - 18px);
  202. background-color: rgba(255, 255, 255, 1);
  203. padding: 21px;
  204. .user-list {
  205. margin-top: 24px;
  206. }
  207. ::v-deep .el-pagination {
  208. position: absolute;
  209. bottom: 35px;
  210. right: 67px;
  211. }
  212. .errorDialog {
  213. .el-button {
  214. position: absolute;
  215. bottom: 5px;
  216. right: 24px;
  217. }
  218. .title {
  219. font-weight: 400;
  220. font-size: 14px;
  221. color: rgba(0, 0, 0, 0.88);
  222. line-height: 22px;
  223. margin-bottom: 8px;
  224. }
  225. .list {
  226. display: flex;
  227. flex-direction: column;
  228. gap: 4px;
  229. font-weight: 400;
  230. font-size: 14px;
  231. color: rgba(0, 0, 0, 0.88);
  232. line-height: 22px;
  233. max-height: 300px;
  234. overflow-y: auto;
  235. margin-bottom: 15px;
  236. .dot {
  237. display: inline-block;
  238. width: 8px;
  239. height: 8px;
  240. background-color: #ff4d4f;
  241. border-radius: 50%;
  242. margin-right: 8px;
  243. }
  244. }
  245. .more-button {
  246. font-weight: 400;
  247. font-size: 14px;
  248. color: #1890ff;
  249. line-height: 20px;
  250. text-decoration: underline;
  251. cursor: pointer;
  252. }
  253. }
  254. ::v-deep .el-drawer__header {
  255. margin: 0;
  256. border-bottom: 1px solid rgba(0, 0, 0, 0.06);
  257. span {
  258. margin-bottom: 20px;
  259. font-weight: 500;
  260. font-size: 16px;
  261. color: rgba(0, 0, 0, 0.88);
  262. line-height: 24px;
  263. }
  264. button {
  265. margin-bottom: 20px;
  266. color: #000000;
  267. }
  268. }
  269. }
  270. </style>