index.vue 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. <template>
  2. <div class="container">
  3. <a-card :bordered="false">
  4. <a-row>
  5. <a-col :flex="1">
  6. <a-form
  7. :model="formModel"
  8. :label-col-props="{ span: 4 }"
  9. :wrapper-col-props="{ span: 18 }"
  10. label-align="left"
  11. >
  12. <a-row :gutter="16">
  13. <a-col :span="6">
  14. <a-form-item
  15. field="name"
  16. :label="t('manage.form.name')"
  17. label-col-flex="50px"
  18. >
  19. <a-input
  20. v-model="formModel.name"
  21. :placeholder="t('manage.form.name')"
  22. allow-clear
  23. />
  24. </a-form-item>
  25. </a-col>
  26. <a-col :span="6">
  27. <a-form-item
  28. field="desc"
  29. :label="t('manage.form.desc')"
  30. label-col-flex="40px"
  31. >
  32. <a-input
  33. v-model="formModel.desc"
  34. :placeholder="t('manage.form.desc')"
  35. allow-clear
  36. />
  37. </a-form-item>
  38. </a-col>
  39. </a-row>
  40. </a-form>
  41. </a-col>
  42. <a-divider :style="{ height: '35px' }" direction="vertical" />
  43. <a-col :flex="'42px'">
  44. <a-space :size="10">
  45. <a-button type="primary" @click="search">
  46. <template #icon>
  47. <icon-search />
  48. </template>
  49. {{ t('searchTable.form.search') }}
  50. </a-button>
  51. <a-button @click="reset">
  52. <template #icon>
  53. <icon-refresh />
  54. </template>
  55. {{ t('searchTable.form.reset') }}
  56. </a-button>
  57. <a-button
  58. type="primary"
  59. @click="
  60. showEditDialog = true;
  61. userId = 0;
  62. "
  63. >
  64. <template #icon>
  65. <icon-plus />
  66. </template>
  67. {{ t('searchTable.form.add') }}
  68. </a-button>
  69. </a-space>
  70. </a-col>
  71. </a-row>
  72. <a-table
  73. class="table-list"
  74. row-key="name"
  75. :loading="loading"
  76. :pagination="pagination"
  77. :columns="cloneColumns"
  78. :data="paginatedData"
  79. :bordered="false"
  80. :size="size"
  81. :scrollbar="true"
  82. @page-change="onPageChange"
  83. >
  84. <template #index="{ rowIndex }">
  85. {{ rowIndex + 1 + (pagination.current - 1) * pagination.pageSize }}
  86. </template>
  87. <template #privilege="{ record }">
  88. {{ getPrivilegeLabel(record.privilege) }}
  89. </template>
  90. <template #optional="{ record }">
  91. <a-button
  92. status="danger"
  93. size="mini"
  94. @click="handleDeleteFun(record.id)"
  95. >
  96. {{ t('searchTable.form.delete') }}
  97. </a-button>
  98. </template>
  99. </a-table>
  100. </a-card>
  101. <EditDialog
  102. v-model="showEditDialog"
  103. :id="userId"
  104. :privilegeList="privilegeList"
  105. @updateList="searchTable"
  106. ></EditDialog>
  107. </div>
  108. </template>
  109. <script lang="ts" setup name="Manage">
  110. import {
  111. ref,
  112. reactive,
  113. shallowRef,
  114. h,
  115. getCurrentInstance,
  116. computed,
  117. } from 'vue';
  118. import { getUserList, fetchDeleteUser } from '@/api/user';
  119. import type { UserData, UserParams } from '@/api/user';
  120. import { SizeProps, Pagination } from '@/types/global';
  121. import BTag from '@/components/business/b-tag/index.vue';
  122. import type { TableColumnData } from '@arco-design/web-vue';
  123. import useLoading from '@/hooks/loading';
  124. import EditDialog from './components/edit.vue';
  125. import { useI18n } from 'vue-i18n';
  126. // import { privilegeList } from '@/utils/const';
  127. import { Modal } from '@arco-design/web-vue';
  128. import type { AdditionalProp } from '@/api/dict';
  129. import useDictList from '@/hooks/dict-list';
  130. const { t } = useI18n();
  131. const { loading, setLoading } = useLoading(true);
  132. const cloneColumns = computed(() => [
  133. {
  134. title: t('searchTable.table.number'),
  135. dataIndex: 'index',
  136. slotName: 'index',
  137. },
  138. {
  139. title: t('manage.form.name'),
  140. dataIndex: 'name',
  141. slotName: 'name',
  142. },
  143. {
  144. title: t('manage.form.desc'),
  145. dataIndex: 'desc',
  146. ellipsis: true,
  147. tooltip: true,
  148. },
  149. {
  150. title: t('manage.form.permission'),
  151. dataIndex: 'privilege',
  152. slotName: 'privilege',
  153. },
  154. {
  155. title: t('searchTable.table.optional'),
  156. align: 'center',
  157. slotName: 'optional',
  158. },
  159. ]);
  160. const basePagination: Pagination = {
  161. current: 1,
  162. pageSize: 20,
  163. };
  164. const pagination = reactive({
  165. ...basePagination,
  166. });
  167. const generateFormModel = () => {
  168. return {
  169. name: '',
  170. desc: '',
  171. privilege: null,
  172. pageIndex: 1,
  173. pageSize: 20,
  174. } as UserParams;
  175. };
  176. const renderData = ref<UserData[]>([] as UserData[]);
  177. const size = ref<SizeProps>('medium');
  178. const formModel = ref<UserParams>(generateFormModel());
  179. const userId = shallowRef<number>(0);
  180. const showEditDialog = shallowRef<boolean>(false);
  181. const this_ = getCurrentInstance()?.appContext.config.globalProperties;
  182. const privilegeList = ref<AdditionalProp[]>([]);
  183. useDictList(['Privilege']).then(res => {
  184. privilegeList.value.push(...res['Privilege']);
  185. });
  186. const search = () => {
  187. searchTable();
  188. };
  189. const reset = () => {
  190. formModel.value = generateFormModel();
  191. };
  192. // 计算分页数据
  193. const paginatedData = computed(() => {
  194. const start = (formModel.value.pageIndex - 1) * formModel.value.pageSize;
  195. return renderData.value.slice(start, start + formModel.value.pageSize);
  196. });
  197. function searchTable() {
  198. setLoading(true);
  199. getUserList(formModel.value)
  200. .then(res => {
  201. formModel.value.pageIndex = 1;
  202. pagination.current = 1;
  203. pagination.total = res.data.length;
  204. renderData.value = res.data;
  205. })
  206. .finally(() => {
  207. setLoading(false);
  208. });
  209. }
  210. searchTable();
  211. const onPageChange = (current: number) => {
  212. formModel.value.pageIndex = current;
  213. pagination.current = current;
  214. // searchTable();
  215. };
  216. const handleDeleteFun = (id: number) => {
  217. Modal.warning({
  218. title: t('modal.warning.title'),
  219. content: t('modal.warning.content'),
  220. okText: t('searchTable.form.confirm'),
  221. onBeforeOk: (done: (closed: boolean) => void) => {
  222. fetchDeleteUser({ id })
  223. .then(res => {
  224. if (res.success) {
  225. this_?.$message.success(t('message.success'));
  226. searchTable();
  227. }
  228. })
  229. .finally(() => {
  230. done(true); // 确定关闭模态框
  231. });
  232. },
  233. });
  234. };
  235. const getPrivilegeLabel = computed(() => {
  236. return (privilegeValue: string | number) => {
  237. const privilege = privilegeList.value.find(
  238. item => item.dictCode === privilegeValue
  239. );
  240. return privilege ? t(privilege.name as string) : '-';
  241. };
  242. });
  243. </script>
  244. <style scoped lang="less">
  245. .container {
  246. padding: 10px;
  247. }
  248. </style>