index.vue 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. <script lang="ts" setup>
  2. import type { VbenFormProps } from '@vben/common-ui';
  3. import type { RoleGroupEntity } from '@vben/types';
  4. import type { VxeGridListeners, VxeGridProps } from '#/adapter/vxe-table';
  5. import { h, onMounted, ref } from 'vue';
  6. import { Page, useVbenModal } from '@vben/common-ui';
  7. import {
  8. MdiDelete,
  9. MdiDetail,
  10. MdiEdit,
  11. MdiPasswordVerified,
  12. } from '@vben/icons';
  13. import { ElMessage, ElMessageBox, ElTag } from 'element-plus';
  14. import { useVbenVxeGrid } from '#/adapter/vxe-table';
  15. import { deleteAccountApi, getAccountWorkerListApi } from '#/api/account';
  16. import { getRoleListApi } from '#/api/role';
  17. import { $t } from '#/locales';
  18. import ChangePasswordForm from './change-password-form.vue';
  19. import AccountForm from './form.vue';
  20. const changePasswordFormRef = ref<InstanceType<
  21. typeof ChangePasswordForm
  22. > | null>(null);
  23. const formOptions: VbenFormProps = {
  24. // 默认展开
  25. collapsed: true,
  26. // 控制表单是否显示折叠按钮
  27. showCollapseButton: true,
  28. // 按下回车时是否提交表单
  29. submitOnEnter: true,
  30. schema: [
  31. {
  32. component: 'Input',
  33. fieldName: 'accountname',
  34. label: '账号',
  35. componentProps: {
  36. placeholder: $t('ui.placeholder.input'),
  37. allowClear: true,
  38. },
  39. },
  40. {
  41. component: 'Select',
  42. fieldName: 'accountstatus',
  43. label: '账号状态',
  44. componentProps: {
  45. placeholder: $t('ui.placeholder.select'),
  46. allowClear: true,
  47. options: [
  48. { label: '可用', value: 1 },
  49. { label: '不可用', value: 0 },
  50. ],
  51. },
  52. },
  53. ],
  54. wrapperClass: 'grid-cols-1 md:grid-cols-3 lg:grid-cols-5',
  55. };
  56. const gridOptions: VxeGridProps<any> = {
  57. toolbarConfig: {
  58. custom: true,
  59. export: true,
  60. refresh: true,
  61. zoom: true,
  62. },
  63. height: 'auto',
  64. exportConfig: {},
  65. pagerConfig: {},
  66. rowConfig: {
  67. isHover: true,
  68. },
  69. stripe: true,
  70. proxyConfig: {
  71. response: {
  72. result: 'Data',
  73. total: 'Total',
  74. },
  75. ajax: {
  76. query: async ({ page }, formValues) => {
  77. return await getAccountWorkerListApi({
  78. pageindex: page.currentPage,
  79. rows: page.pageSize,
  80. ...formValues,
  81. });
  82. },
  83. },
  84. },
  85. columns: [
  86. { title: '账号', field: 'accountname' },
  87. {
  88. title: '账号状态',
  89. field: 'accountstatus',
  90. slots: {
  91. default: ({ row }) => {
  92. const status = row.accountstatus;
  93. return h(
  94. ElTag,
  95. {
  96. type: status === 1 ? 'success' : 'danger',
  97. effect: 'dark',
  98. size: 'small',
  99. round: true,
  100. },
  101. () => (status === 1 ? '可用' : '不可用'),
  102. );
  103. },
  104. },
  105. },
  106. { title: '备注', field: 'accountbz', sortable: true },
  107. {
  108. title: '角色组',
  109. field: 'accountgrouplist',
  110. sortable: true,
  111. slots: {
  112. default: ({ row }) => {
  113. return formatRoleNames(row.accountgrouplist);
  114. },
  115. },
  116. },
  117. { title: '创建人', field: 'accountcreateuser', sortable: true },
  118. { title: '开通时间', field: 'accountcreatedate', sortable: true },
  119. // { title: '到期时间', field: 'accountenddate' },
  120. // { title: '更新时间', field: 'accountupdate' },
  121. // { title: '更新人', field: 'accountupuser' },
  122. { title: '关联职员', field: 'worker_xm', sortable: true },
  123. {
  124. title: '操作',
  125. field: 'action',
  126. fixed: 'right',
  127. slots: { default: 'action' },
  128. width: 180,
  129. },
  130. ],
  131. };
  132. const gridEvents: VxeGridListeners<any> = {
  133. cellDblclick: ({ row }) => {
  134. handleDetail(row);
  135. },
  136. };
  137. const [Grid, gridApi] = useVbenVxeGrid({
  138. gridEvents,
  139. gridOptions,
  140. formOptions,
  141. });
  142. const [Modal, modalApi] = useVbenModal({
  143. fullscreenButton: false,
  144. closeOnClickModal: false,
  145. closeOnPressEscape: false,
  146. connectedComponent: AccountForm,
  147. });
  148. // 角色数据映射
  149. const roleMap = ref<Map<string, string>>(new Map());
  150. // 获取角色列表并创建ID到名称的映射
  151. async function fetchRoleList() {
  152. try {
  153. const res = await getRoleListApi({
  154. pageindex: 1,
  155. rows: 1000,
  156. });
  157. if (res && res.Data) {
  158. const map = new Map<string, string>();
  159. res.Data.filter((item: RoleGroupEntity) => item.available === 1).forEach(
  160. (item: RoleGroupEntity) => {
  161. map.set(item.id.toString(), item.title);
  162. },
  163. );
  164. roleMap.value = map;
  165. }
  166. } catch (error) {
  167. console.error('获取角色列表失败', error);
  168. }
  169. }
  170. // 将角色ID转换为角色名称
  171. function formatRoleNames(roleIds: string): string {
  172. if (!roleIds) return '';
  173. const ids = roleIds.split(',').filter(Boolean);
  174. const names = ids.map((id) => roleMap.value.get(id) || id).filter(Boolean);
  175. return names.join(', ');
  176. }
  177. // 初始化时获取角色列表
  178. onMounted(() => {
  179. fetchRoleList();
  180. });
  181. /* 创建 */
  182. function handleCreate() {
  183. modalApi.setState({ showCancelButton: true });
  184. modalApi.setData({ formType: 'create' }).open();
  185. }
  186. /* 编辑 */
  187. function handleEdit(row: any) {
  188. modalApi.setState({ showCancelButton: true });
  189. modalApi.setData({ formType: 'edit', row }).open();
  190. }
  191. /* 修改密码 */
  192. function handleChangePassword(row: any) {
  193. changePasswordFormRef.value?.openModal(row);
  194. }
  195. /* 详情 */
  196. function handleDetail(row: any) {
  197. modalApi.setState({ showCancelButton: false });
  198. modalApi.setData({ formType: 'detail', row }).open();
  199. }
  200. /* 删除 */
  201. async function handleDelete(row: any) {
  202. try {
  203. await ElMessageBox.confirm('确认要删除该账号吗?', '提示', {
  204. confirmButtonText: '确定',
  205. cancelButtonText: '取消',
  206. type: 'warning',
  207. });
  208. await deleteAccountApi({ 'accountid.value': row.accountid });
  209. ElMessage.success('删除成功');
  210. gridApi.reload();
  211. } catch (error) {
  212. console.error(error);
  213. }
  214. }
  215. function handleFinish() {
  216. gridApi.reload();
  217. }
  218. </script>
  219. <template>
  220. <Page auto-content-height>
  221. <Grid table-title="账号列表">
  222. <template #toolbar-tools>
  223. <el-button type="primary" @click="handleCreate"> 新增 </el-button>
  224. </template>
  225. <template #action="{ row }">
  226. <el-tooltip
  227. class="box-item"
  228. effect="dark"
  229. content="详情"
  230. placement="top"
  231. >
  232. <el-button
  233. round
  234. @click="() => handleDetail(row)"
  235. :icon="MdiDetail"
  236. class="!p-2"
  237. />
  238. </el-tooltip>
  239. <el-tooltip
  240. class="box-item"
  241. effect="dark"
  242. content="编辑"
  243. placement="top"
  244. >
  245. <el-button
  246. round
  247. @click="() => handleEdit(row)"
  248. :icon="MdiEdit"
  249. class="!p-2"
  250. />
  251. </el-tooltip>
  252. <el-tooltip
  253. class="box-item"
  254. effect="dark"
  255. content="修改密码"
  256. placement="top"
  257. >
  258. <el-button
  259. round
  260. @click="
  261. () =>
  262. handleChangePassword({
  263. accountid: row.accountid,
  264. })
  265. "
  266. :icon="MdiPasswordVerified"
  267. class="!p-2"
  268. />
  269. </el-tooltip>
  270. <el-tooltip
  271. class="box-item"
  272. effect="dark"
  273. content="删除"
  274. placement="top"
  275. >
  276. <el-button
  277. round
  278. @click="() => handleDelete(row)"
  279. :icon="MdiDelete"
  280. class="!p-2"
  281. />
  282. </el-tooltip>
  283. </template>
  284. </Grid>
  285. <Modal @finish="handleFinish" />
  286. <ChangePasswordForm ref="changePasswordFormRef" @finish="handleFinish" />
  287. </Page>
  288. </template>