index.vue 6.0 KB

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