Pārlūkot izejas kodu

feat: 完善基本模块

赖奇 1 gadu atpakaļ
vecāks
revīzija
2a77673292
39 mainītis faili ar 1986 papildinājumiem un 673 dzēšanām
  1. 1 1
      apps/web-ele/auto-imports.d.ts
  2. 8 0
      apps/web-ele/components.d.ts
  3. 55 0
      apps/web-ele/src/api/account/index.ts
  4. 7 0
      apps/web-ele/src/api/coupon/coupon1.ts
  5. 54 0
      apps/web-ele/src/api/dict/index.ts
  6. 33 0
      apps/web-ele/src/api/log/index.ts
  7. 54 0
      apps/web-ele/src/api/menu/index.ts
  8. 7 0
      apps/web-ele/src/api/orders/index.ts
  9. 7 0
      apps/web-ele/src/api/product/index.ts
  10. 54 0
      apps/web-ele/src/api/role/index.ts
  11. 7 0
      apps/web-ele/src/api/scqy/index.ts
  12. 7 0
      apps/web-ele/src/api/user/index.ts
  13. 44 12
      apps/web-ele/src/views/coupon-manage/form.vue
  14. 45 9
      apps/web-ele/src/views/coupon-manage/index.vue
  15. 27 3
      apps/web-ele/src/views/customer-manage/index.vue
  16. 8 0
      apps/web-ele/src/views/examine-manage/examine-coupon/form.vue
  17. 46 7
      apps/web-ele/src/views/examine-manage/examine-coupon/index.vue
  18. 5 5
      apps/web-ele/src/views/examine-manage/examine-subsidy/index.vue
  19. 48 4
      apps/web-ele/src/views/order-manage/index.vue
  20. 27 3
      apps/web-ele/src/views/product-manage/index.vue
  21. 27 3
      apps/web-ele/src/views/scqy-manage/index.vue
  22. 117 107
      apps/web-ele/src/views/system-manage/data-dictionary/form.vue
  23. 110 37
      apps/web-ele/src/views/system-manage/data-dictionary/index.vue
  24. 166 82
      apps/web-ele/src/views/system-manage/menu-manage/form.vue
  25. 121 36
      apps/web-ele/src/views/system-manage/menu-manage/index.vue
  26. 100 0
      apps/web-ele/src/views/system-manage/operation-logs/detail.vue
  27. 80 54
      apps/web-ele/src/views/system-manage/operation-logs/index.vue
  28. 90 115
      apps/web-ele/src/views/system-manage/role-manage/form.vue
  29. 89 40
      apps/web-ele/src/views/system-manage/role-manage/index.vue
  30. 131 112
      apps/web-ele/src/views/system-manage/user-manage/form.vue
  31. 89 39
      apps/web-ele/src/views/system-manage/user-manage/index.vue
  32. 37 4
      apps/web-ele/src/views/system-manage/worker-manage/form.vue
  33. 1 0
      packages/icons/src/iconify/index.ts
  34. 48 0
      packages/types/src/account.ts
  35. 54 0
      packages/types/src/dict.ts
  36. 5 0
      packages/types/src/index.ts
  37. 42 0
      packages/types/src/log.ts
  38. 90 0
      packages/types/src/menu.ts
  39. 45 0
      packages/types/src/role.ts

+ 1 - 1
apps/web-ele/auto-imports.d.ts

@@ -6,5 +6,5 @@
 // biome-ignore lint: disable
 export {}
 declare global {
-
+  const ElTag: (typeof import('element-plus/es'))['ElTag'];
 }

+ 8 - 0
apps/web-ele/components.d.ts

@@ -8,7 +8,15 @@ export {};
 declare module 'vue' {
   export interface GlobalComponents {
     ElButton: typeof import('element-plus/es')['ElButton']
+    ElDescriptions: typeof import('element-plus/es')['ElDescriptions']
+    ElDescriptionsItem: typeof import('element-plus/es')['ElDescriptionsItem']
+    ElDivider: typeof import('element-plus/es')['ElDivider']
+    ElInput: typeof import('element-plus/es')['ElInput']
+    ElTag: typeof import('element-plus/es')['ElTag']
     RouterLink: typeof import('vue-router')['RouterLink']
     RouterView: typeof import('vue-router')['RouterView']
   }
+  export interface ComponentCustomProperties {
+    vLoading: typeof import('element-plus/es')['ElLoadingDirective']
+  }
 }

+ 55 - 0
apps/web-ele/src/api/account/index.ts

@@ -0,0 +1,55 @@
+import type { AccountEntity, PageConfig } from '@vben/types';
+
+import { parseQueryValues } from '@vben/utils';
+
+import { requestClient } from '#/api/request';
+
+interface AccountPartialEntity
+  extends Partial<Omit<AccountEntity, 'accountname'>> {
+  accountname?: string;
+}
+
+interface AccountQueryParams extends AccountPartialEntity, PageConfig {}
+
+/**
+ * 账号信息_列表
+ */
+export async function getAccountListApi(params: AccountQueryParams) {
+  return requestClient.post<any>('/api/query/list?pagevalue=68', {
+    ...params,
+  });
+}
+
+/**
+ * 账号信息_详情
+ */
+export async function getAccountDetailApi(data: { accountid: string }) {
+  return requestClient.post<any>(
+    '/api/query/view?pagevalue=69',
+    {
+      ...parseQueryValues(data),
+    },
+    { formatData: true }, // 格式化返回数据
+  );
+}
+
+/**
+ * 账号信息_新增
+ */
+export async function addAccountApi(data: AccountEntity) {
+  return requestClient.post<any>('/api/add?pagevalue=70', { ...data });
+}
+
+/**
+ * 账号信息_编辑
+ */
+export async function editAccountApi(data: AccountEntity) {
+  return requestClient.post<any>('/api/up?pagevalue=71', { ...data });
+}
+
+/**
+ * 账号信息_删除
+ */
+export async function deleteAccountApi(data: { 'accountid.value': string }) {
+  return requestClient.post<any>('/api/del?pagevalue=72', { ...data });
+}

+ 7 - 0
apps/web-ele/src/api/coupon/coupon1.ts

@@ -46,3 +46,10 @@ export async function addCoupon1Api(data: Coupon1Entity) {
 export async function editCoupon1Api(data: Coupon1Entity) {
   return requestClient.post<any>('/api/up?pagevalue=36', { ...data });
 }
+
+/**
+ * 优惠券信息_删除
+ */
+export async function deleteCoupon1Api(data: { 'couponid.value': string }) {
+  return requestClient.post<any>('/api/del?pagevalue=37', { ...data });
+}

+ 54 - 0
apps/web-ele/src/api/dict/index.ts

@@ -0,0 +1,54 @@
+import type { DictEntity, PageConfig } from '@vben/types';
+
+import { parseQueryValues } from '@vben/utils';
+
+import { requestClient } from '#/api/request';
+
+interface DictPartialEntity extends Partial<Omit<DictEntity, 'title'>> {
+  title?: string;
+}
+
+interface DictQueryParams extends DictPartialEntity, PageConfig {}
+
+/**
+ * 字典信息_列表
+ */
+export async function getDictListApi(params: DictQueryParams) {
+  return requestClient.post<any>('/api/query/list?pagevalue=73', {
+    ...params,
+  });
+}
+
+/**
+ * 字典信息_详情
+ */
+export async function getDictDetailApi(data: { id: number }) {
+  return requestClient.post<any>(
+    '/api/query/view?pagevalue=74',
+    {
+      ...parseQueryValues(data),
+    },
+    { formatData: true },
+  );
+}
+
+/**
+ * 字典信息_新增
+ */
+export async function addDictApi(data: DictEntity) {
+  return requestClient.post<any>('/api/add?pagevalue=75', { ...data });
+}
+
+/**
+ * 字典信息_编辑
+ */
+export async function editDictApi(data: DictEntity) {
+  return requestClient.post<any>('/api/up?pagevalue=76', { ...data });
+}
+
+/**
+ * 字典信息_删除
+ */
+export async function deleteDictApi(data: { 'id.value': number }) {
+  return requestClient.post<any>('/api/del?pagevalue=77', { ...data });
+}

+ 33 - 0
apps/web-ele/src/api/log/index.ts

@@ -0,0 +1,33 @@
+import type { LogEntity, PageConfig } from '@vben/types';
+
+import { parseQueryValues } from '@vben/utils';
+
+import { requestClient } from '#/api/request';
+
+interface LogPartialEntity extends Partial<Omit<LogEntity, 'id'>> {
+  id?: number;
+}
+
+interface LogQueryParams extends LogPartialEntity, PageConfig {}
+
+/**
+ * 日志信息_列表
+ */
+export async function getLogListApi(params: LogQueryParams) {
+  return requestClient.post<any>('/api/query/list?pagevalue=78', {
+    ...params,
+  });
+}
+
+/**
+ * 日志信息_详情
+ */
+export async function getLogDetailApi(data: { id: number }) {
+  return requestClient.post<any>(
+    '/api/query/view?pagevalue=79',
+    {
+      ...parseQueryValues(data),
+    },
+    { formatData: true },
+  );
+}

+ 54 - 0
apps/web-ele/src/api/menu/index.ts

@@ -0,0 +1,54 @@
+import type { MenuEntity, PageConfig } from '@vben/types';
+
+import { parseQueryValues } from '@vben/utils';
+
+import { requestClient } from '#/api/request';
+
+interface MenuPartialEntity extends Partial<Omit<MenuEntity, 'menu_name'>> {
+  menu_name?: string;
+}
+
+interface MenuQueryParams extends MenuPartialEntity, PageConfig {}
+
+/**
+ * 菜单信息_列表
+ */
+export async function getMenuListApi(params: MenuQueryParams) {
+  return requestClient.post<any>('/api/query/list?pagevalue=83', {
+    ...params,
+  });
+}
+
+/**
+ * 菜单信息_详情
+ */
+export async function getMenuDetailApi(data: { menu_id: number }) {
+  return requestClient.post<any>(
+    '/api/query/view?pagevalue=84',
+    {
+      ...parseQueryValues(data),
+    },
+    { formatData: true },
+  );
+}
+
+/**
+ * 菜单信息_新增
+ */
+export async function addMenuApi(data: MenuEntity) {
+  return requestClient.post<any>('/api/add?pagevalue=85', { ...data });
+}
+
+/**
+ * 菜单信息_编辑
+ */
+export async function editMenuApi(data: MenuEntity) {
+  return requestClient.post<any>('/api/up?pagevalue=86', { ...data });
+}
+
+/**
+ * 菜单信息_删除
+ */
+export async function deleteMenuApi(data: { 'menu_id.value': number }) {
+  return requestClient.post<any>('/api/del?pagevalue=87', { ...data });
+}

+ 7 - 0
apps/web-ele/src/api/orders/index.ts

@@ -46,3 +46,10 @@ export async function addOrdersApi(data: OrdersEntity) {
 export async function editOrdersApi(data: OrdersEntity) {
   return requestClient.post<any>('/api/up?pagevalue=54', { ...data });
 }
+
+/**
+ * 订单信息_删除
+ */
+export async function deleteOrdersApi(data: { 'ordersid.value': string }) {
+  return requestClient.post<any>('/api/del?pagevalue=55', { ...data });
+}

+ 7 - 0
apps/web-ele/src/api/product/index.ts

@@ -46,3 +46,10 @@ export async function addProductApi(data: ProductEntity) {
 export async function editProductApi(data: ProductEntity) {
   return requestClient.post<any>('/api/up?pagevalue=26', { ...data });
 }
+
+/**
+ * 产品信息_删除
+ */
+export async function deleteProductApi(data: { 'productsid.value': string }) {
+  return requestClient.post<any>('/api/del?pagevalue=27', { ...data });
+}

+ 54 - 0
apps/web-ele/src/api/role/index.ts

@@ -0,0 +1,54 @@
+import type { PageConfig, RoleGroupEntity } from '@vben/types';
+
+import { parseQueryValues } from '@vben/utils';
+
+import { requestClient } from '#/api/request';
+
+interface RolePartialEntity extends Partial<Omit<RoleGroupEntity, 'title'>> {
+  title?: string;
+}
+
+interface RoleQueryParams extends PageConfig, RolePartialEntity {}
+
+/**
+ * 角色信息_列表
+ */
+export async function getRoleListApi(params: RoleQueryParams) {
+  return requestClient.post<any>('/api/query/list?pagevalue=88', {
+    ...params,
+  });
+}
+
+/**
+ * 角色信息_详情
+ */
+export async function getRoleDetailApi(data: { id: number }) {
+  return requestClient.post<any>(
+    '/api/query/view?pagevalue=89',
+    {
+      ...parseQueryValues(data),
+    },
+    { formatData: true },
+  );
+}
+
+/**
+ * 角色信息_新增
+ */
+export async function addRoleApi(data: RoleGroupEntity) {
+  return requestClient.post<any>('/api/add?pagevalue=90', { ...data });
+}
+
+/**
+ * 角色信息_编辑
+ */
+export async function editRoleApi(data: RoleGroupEntity) {
+  return requestClient.post<any>('/api/up?pagevalue=91', { ...data });
+}
+
+/**
+ * 角色信息_删除
+ */
+export async function deleteRoleApi(data: { 'id.value': number }) {
+  return requestClient.post<any>('/api/del?pagevalue=92', { ...data });
+}

+ 7 - 0
apps/web-ele/src/api/scqy/index.ts

@@ -45,3 +45,10 @@ export async function addScqyApi(data: ScqyEntity) {
 export async function editScqyApi(data: ScqyEntity) {
   return requestClient.post<any>('/api/up?pagevalue=31', { ...data });
 }
+
+/**
+ * 生产企业信息_删除
+ */
+export async function deleteScqyApi(data: { 'scqyinfoid.value': string }) {
+  return requestClient.post<any>('/api/del?pagevalue=32', { ...data });
+}

+ 7 - 0
apps/web-ele/src/api/user/index.ts

@@ -49,3 +49,10 @@ export async function addCustomerApi(data: CustomerEntity) {
 export async function editCustomerApi(data: CustomerEntity) {
   return requestClient.post<any>('/api/up?pagevalue=21', { ...data });
 }
+
+/**
+ * 客户信息_删除
+ */
+export async function deleteCustomerApi(data: { 'usersid.value': string }) {
+  return requestClient.post<any>('/api/del?pagevalue=22', { ...data });
+}

+ 44 - 12
apps/web-ele/src/views/coupon-manage/form.vue

@@ -13,6 +13,7 @@ import {
   editCoupon1Api,
   getCoupon1DetailApi,
 } from '#/api/coupon/coupon1';
+import { getProductListApi } from '#/api/product';
 import { $t } from '#/locales';
 
 const emit = defineEmits(['finish']);
@@ -27,6 +28,27 @@ const titleMap = {
 
 const getTitle = computed(() => titleMap[formType.value]);
 
+const productOptions = ref<{ label: string; value: string }[]>([]);
+
+// 获取产品列表
+const fetchProductOptions = async () => {
+  try {
+    const response = await getProductListApi({
+      pageindex: 1,
+      rows: 100,
+    });
+
+    if (response && response.Data && Array.isArray(response.Data)) {
+      productOptions.value = response.Data.map((item: any) => ({
+        label: item.productsname || '未命名产品',
+        value: item.productsid || '',
+      })).filter((item: any) => item.value);
+    }
+  } catch (error) {
+    console.error('获取产品列表失败', error);
+  }
+};
+
 const [BaseForm, baseFormApi] = useVbenForm({
   showDefaultActions: false,
   // 所有表单项共用,可单独在表单内覆盖
@@ -45,7 +67,7 @@ const [BaseForm, baseFormApi] = useVbenForm({
     {
       component: 'Input',
       fieldName: 'couponmc',
-      label: '优惠券名称',
+      label: '名称',
       componentProps: {
         placeholder: $t('ui.placeholder.input'),
         allowClear: true,
@@ -53,24 +75,29 @@ const [BaseForm, baseFormApi] = useVbenForm({
       rules: z.string().min(1, { message: '请输入优惠券名称' }),
     },
     {
-      component: 'Input',
+      component: 'Select',
       fieldName: 'couponproductids',
-      label: '优惠券可用产品',
+      label: '可用产品',
       componentProps: {
-        placeholder: $t('ui.placeholder.input'),
-        allowClear: true,
+        placeholder: '请选择可用产品',
+        options: productOptions,
+        clearable: true,
+        filterable: true,
+        noDataText: '暂无产品数据',
+        style: { width: '100%' },
       },
-      rules: z.string().min(1, { message: '请输入优惠券可用产品' }),
+      rules: z.string().min(1, { message: '请选择优惠券可用产品' }),
     },
     {
-      component: 'Input',
+      component: 'Switch',
       fieldName: 'couponsfky',
-      label: '优惠券是否可用',
+      label: '是否可用',
       componentProps: {
-        placeholder: $t('ui.placeholder.input'),
-        allowClear: true,
+        activeValue: 1,
+        inactiveValue: 0,
       },
-      rules: z.string().min(1, { message: '请输入优惠券是否可用' }),
+      defaultValue: 1,
+      rules: z.string().min(1, { message: '请选择是否可用' }),
     },
   ],
 });
@@ -113,14 +140,19 @@ const [Modal, modalApi] = useVbenModal({
   async onOpenChange(isOpen) {
     if (isOpen) {
       data.value = modalApi.getData();
-
       formType.value = data.value.formType;
 
       baseFormApi.setState({
         commonConfig: { disabled: formType.value === 'detail' },
       });
 
+      // 获取产品列表
+      await fetchProductOptions();
+
       if (data.value.formType === 'create') {
+        baseFormApi.setValues({
+          couponsfky: 1,
+        });
         return;
       }
 

+ 45 - 9
apps/web-ele/src/views/coupon-manage/index.vue

@@ -4,10 +4,12 @@ import type { VbenFormProps } from '@vben/common-ui';
 import type { VxeGridProps } from '#/adapter/vxe-table';
 
 import { Page, useVbenModal } from '@vben/common-ui';
-import { MdiDetail, MdiEdit } from '@vben/icons';
+import { MdiDelete, MdiDetail, MdiEdit } from '@vben/icons';
+
+import { ElMessage, ElMessageBox } from 'element-plus';
 
 import { useVbenVxeGrid } from '#/adapter/vxe-table';
-import { getCoupon1ListApi } from '#/api/coupon/coupon1';
+import { deleteCoupon1Api, getCoupon1ListApi } from '#/api/coupon/coupon1';
 import { $t } from '#/locales';
 
 import Coupon1Form from './form.vue';
@@ -67,18 +69,22 @@ const gridOptions: VxeGridProps<any> = {
 
   columns: [
     { title: '优惠券名称', field: 'couponmc' },
-    { title: '优惠券可用产品', field: 'couponproductids' },
-    { title: '优惠券是否可用', field: 'couponsfky' },
-    { title: '优惠券创建时间', field: 'couponcreatedate' },
-    { title: '优惠券创建人', field: 'couponcreateuser' },
-    { title: '优惠券更新时间', field: 'couponupdate' },
-    { title: '优惠券更新人', field: 'couponupuser' },
+    { title: '可用产品', field: 'couponproductids' },
+    {
+      title: '是否可用',
+      field: 'couponsfky',
+      slots: { default: 'couponsfky' },
+    },
+    { title: '创建时间', field: 'couponcreatedate' },
+    { title: '创建人', field: 'couponcreateuser' },
+    { title: '更新时间', field: 'couponupdate' },
+    // { title: '优惠券更新人', field: 'couponupuser' },
     {
       title: '操作',
       field: 'action',
       fixed: 'right',
       slots: { default: 'action' },
-      width: 140,
+      width: 150,
     },
   ],
 };
@@ -107,6 +113,22 @@ function handleDetail(row: any) {
   modalApi.setData({ formType: 'detail', row }).open();
 }
 
+/* 删除 */
+async function handleDelete(row: any) {
+  try {
+    await ElMessageBox.confirm('确认要删除该优惠券吗?', '提示', {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+      type: 'warning',
+    });
+    await deleteCoupon1Api({ 'couponid.value': row.couponid });
+    ElMessage.success('删除成功');
+    gridApi.reload();
+  } catch (error) {
+    console.error(error);
+  }
+}
+
 function handleFinish() {
   gridApi.reload();
 }
@@ -118,6 +140,14 @@ function handleFinish() {
       <template #toolbar-tools>
         <el-button type="primary" @click="handleCreate"> 新增 </el-button>
       </template>
+      <template #couponsfky="{ row }">
+        <el-tag
+          :type="row.couponsfky === 1 ? 'success' : 'danger'"
+          effect="light"
+        >
+          {{ row.couponsfky === 1 ? '可用' : '不可用' }}
+        </el-tag>
+      </template>
       <template #action="{ row }">
         <el-button
           round
@@ -131,6 +161,12 @@ function handleFinish() {
           :icon="MdiEdit"
           class="!p-2"
         />
+        <el-button
+          round
+          @click="() => handleDelete(row)"
+          :icon="MdiDelete"
+          class="!p-2"
+        />
       </template>
     </Grid>
     <Modal @finish="handleFinish" />

+ 27 - 3
apps/web-ele/src/views/customer-manage/index.vue

@@ -4,11 +4,13 @@ import type { VbenFormProps } from '@vben/common-ui';
 import type { VxeGridProps } from '#/adapter/vxe-table';
 
 import { Page, useVbenModal } from '@vben/common-ui';
-import { MdiDetail, MdiEdit } from '@vben/icons';
+import { MdiDelete, MdiDetail, MdiEdit } from '@vben/icons';
 import { parseQueryValues } from '@vben/utils';
 
+import { ElMessage, ElMessageBox } from 'element-plus';
+
 import { useVbenVxeGrid } from '#/adapter/vxe-table';
-import { getCustomerListApi } from '#/api/user';
+import { deleteCustomerApi, getCustomerListApi } from '#/api/user';
 import { $t } from '#/locales';
 
 import CustomerForm from './form.vue';
@@ -108,7 +110,7 @@ const gridOptions: VxeGridProps<any> = {
       field: 'action',
       fixed: 'right',
       slots: { default: 'action' },
-      width: 140,
+      width: 150,
     },
   ],
 };
@@ -140,6 +142,22 @@ function handleDetail(row: any) {
 function handleFinish() {
   gridApi.reload();
 }
+
+/* 删除 */
+async function handleDelete(row: any) {
+  try {
+    await ElMessageBox.confirm('确认要删除该客户吗?', '提示', {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+      type: 'warning',
+    });
+    await deleteCustomerApi({ 'usersid.value': row.usersid });
+    ElMessage.success('删除成功');
+    gridApi.reload();
+  } catch (error) {
+    console.error(error);
+  }
+}
 </script>
 
 <template>
@@ -161,6 +179,12 @@ function handleFinish() {
           :icon="MdiEdit"
           class="!p-2"
         />
+        <el-button
+          round
+          @click="() => handleDelete(row)"
+          :icon="MdiDelete"
+          class="!p-2"
+        />
       </template>
     </Grid>
     <Modal @finish="handleFinish" />

+ 8 - 0
apps/web-ele/src/views/examine-manage/examine-coupon/form.vue

@@ -5,6 +5,7 @@ import { computed, ref } from 'vue';
 
 import { useVbenModal } from '@vben/common-ui';
 
+import dayjs from 'dayjs';
 import { ElMessage } from 'element-plus';
 
 import { useVbenForm, z } from '#/adapter/form';
@@ -59,9 +60,13 @@ const [BaseForm, baseFormApi] = useVbenForm({
       component: 'DatePicker',
       fieldName: 'coupon2reviewdatetime',
       label: '审核时间',
+      defaultValue: dayjs().format('YYYY-MM-DD HH:mm:ss'),
       componentProps: {
         placeholder: $t('ui.placeholder.select'),
         allowClear: true,
+        type: 'datetime',
+        valueFormat: 'YYYY-MM-DD HH:mm:ss',
+        style: { width: '100%' },
       },
       rules: z.string().min(1, { message: '请选择审核时间' }),
     },
@@ -163,6 +168,9 @@ const [Modal, modalApi] = useVbenModal({
       });
 
       if (data.value.formType === 'create') {
+        baseFormApi.setValues({
+          coupon2reviewdatetime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
+        });
         return;
       }
 

+ 46 - 7
apps/web-ele/src/views/examine-manage/examine-coupon/index.vue

@@ -3,9 +3,13 @@ import type { VbenFormProps } from '@vben/common-ui';
 
 import type { VxeGridProps } from '#/adapter/vxe-table';
 
+import { h } from 'vue';
+
 import { Page, useVbenModal } from '@vben/common-ui';
 import { MdiDetail, MdiEdit } from '@vben/icons';
 
+import { ElTag } from 'element-plus';
+
 import { useVbenVxeGrid } from '#/adapter/vxe-table';
 import { getCoupon2ListApi } from '#/api/coupon/coupon2';
 import { $t } from '#/locales';
@@ -71,8 +75,43 @@ const gridOptions: VxeGridProps<any> = {
     { title: '申请时间', field: 'coupon2adddatetime' },
     { title: '审核时间', field: 'coupon2reviewdatetime' },
     { title: '申请人ID', field: 'coupon2userid' },
-    { title: '优惠券状态', field: 'coupon2sype' },
-    { title: '使用状态', field: 'coupon2isused' },
+    {
+      title: '优惠券状态',
+      field: 'coupon2sype',
+      slots: {
+        default: ({ row }) => {
+          const type = row.coupon2sype as 0 | 1 | 2;
+          const typeMap = {
+            0: { text: '申请中', type: 'info' },
+            1: { text: '审核通过', type: 'success' },
+            2: { text: '审核失败', type: 'danger' },
+          } as const;
+          return h(
+            ElTag,
+            { type: typeMap[type]?.type },
+            () => typeMap[type]?.text,
+          );
+        },
+      },
+    },
+    {
+      title: '使用状态',
+      field: 'coupon2isused',
+      slots: {
+        default: ({ row }) => {
+          const type = row.coupon2isused as 0 | 1;
+          const typeMap = {
+            0: { text: '未使用', type: 'info' },
+            1: { text: '已使用', type: 'success' },
+          } as const;
+          return h(
+            ElTag,
+            { type: typeMap[type]?.type },
+            () => typeMap[type]?.text,
+          );
+        },
+      },
+    },
     { title: '可用产品', field: 'coupon2productids' },
     { title: '关联主券ID', field: 'coupon2coupon1id' },
     {
@@ -95,9 +134,9 @@ const [Modal, modalApi] = useVbenModal({
 });
 
 /* 创建 */
-function handleCreate() {
-  modalApi.setData({ formType: 'create' }).open();
-}
+// function handleCreate() {
+//   modalApi.setData({ formType: 'create' }).open();
+// }
 
 /* 编辑 */
 function handleEdit(row: any) {
@@ -117,9 +156,9 @@ function handleFinish() {
 <template>
   <Page auto-content-height>
     <Grid table-title="优惠券列表">
-      <template #toolbar-tools>
+      <!-- <template #toolbar-tools>
         <el-button type="primary" @click="handleCreate"> 新增 </el-button>
-      </template>
+      </template> -->
       <template #action="{ row }">
         <el-button
           round

+ 5 - 5
apps/web-ele/src/views/examine-manage/examine-subsidy/index.vue

@@ -91,9 +91,9 @@ const [Modal, modalApi] = useVbenModal({
 });
 
 /* 创建 */
-function handleCreate() {
-  modalApi.setData({ formType: 'create' }).open();
-}
+// function handleCreate() {
+//   modalApi.setData({ formType: 'create' }).open();
+// }
 
 /* 编辑 */
 function handleEdit(row: any) {
@@ -113,9 +113,9 @@ function handleFinish() {
 <template>
   <Page auto-content-height>
     <Grid table-title="补贴申请列表">
-      <template #toolbar-tools>
+      <!-- <template #toolbar-tools>
         <el-button type="primary" @click="handleCreate"> 新增 </el-button>
-      </template>
+      </template> -->
       <template #action="{ row }">
         <el-button
           round

+ 48 - 4
apps/web-ele/src/views/order-manage/index.vue

@@ -3,11 +3,15 @@ import type { VbenFormProps } from '@vben/common-ui';
 
 import type { VxeGridProps } from '#/adapter/vxe-table';
 
+import { h } from 'vue';
+
 import { Page, useVbenModal } from '@vben/common-ui';
-import { MdiDetail, MdiEdit } from '@vben/icons';
+import { MdiDelete, MdiDetail, MdiEdit } from '@vben/icons';
+
+import { ElMessage, ElMessageBox, ElTag } from 'element-plus';
 
 import { useVbenVxeGrid } from '#/adapter/vxe-table';
-import { getOrdersListApi } from '#/api/orders';
+import { deleteOrdersApi, getOrdersListApi } from '#/api/orders';
 import { $t } from '#/locales';
 
 import OrdersForm from './form.vue';
@@ -75,14 +79,32 @@ const gridOptions: VxeGridProps<any> = {
     { title: '订单优惠后金额', field: 'ordersdiscountprice' },
     { title: '优惠金额', field: 'ordersyhprice' },
     { title: '优惠卷id', field: 'orderscouponid' },
-    { title: '订单状态', field: 'ordersorderstatus' },
+    {
+      title: '订单状态',
+      field: 'ordersorderstatus',
+      slots: {
+        default: ({ row }) => {
+          const type = row.ordersorderstatus as 0 | 1 | 2;
+          const typeMap = {
+            0: { text: '待审核', type: 'info' },
+            1: { text: '已支付', type: 'success' },
+            2: { text: '已完成', type: 'warning' },
+          } as const;
+          return h(
+            ElTag,
+            { type: typeMap[type]?.type },
+            () => typeMap[type]?.text,
+          );
+        },
+      },
+    },
     { title: '下单时间', field: 'ordersorderdate' },
     {
       title: '操作',
       field: 'action',
       fixed: 'right',
       slots: { default: 'action' },
-      width: 140,
+      width: 150,
     },
   ],
 };
@@ -114,6 +136,22 @@ function handleDetail(row: any) {
 function handleFinish() {
   gridApi.reload();
 }
+
+/* 删除 */
+async function handleDelete(row: any) {
+  try {
+    await ElMessageBox.confirm('确认要删除该订单吗?', '提示', {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+      type: 'warning',
+    });
+    await deleteOrdersApi({ 'ordersid.value': row.ordersid });
+    ElMessage.success('删除成功');
+    gridApi.reload();
+  } catch (error) {
+    console.error(error);
+  }
+}
 </script>
 
 <template>
@@ -135,6 +173,12 @@ function handleFinish() {
           :icon="MdiEdit"
           class="!p-2"
         />
+        <el-button
+          round
+          @click="() => handleDelete(row)"
+          :icon="MdiDelete"
+          class="!p-2"
+        />
       </template>
     </Grid>
     <Modal @finish="handleFinish" />

+ 27 - 3
apps/web-ele/src/views/product-manage/index.vue

@@ -4,10 +4,12 @@ import type { VbenFormProps } from '@vben/common-ui';
 import type { VxeGridProps } from '#/adapter/vxe-table';
 
 import { Page, useVbenModal } from '@vben/common-ui';
-import { MdiDetail, MdiEdit } from '@vben/icons';
+import { MdiDelete, MdiDetail, MdiEdit } from '@vben/icons';
+
+import { ElMessage, ElMessageBox } from 'element-plus';
 
 import { useVbenVxeGrid } from '#/adapter/vxe-table';
-import { getProductListApi } from '#/api/product';
+import { deleteProductApi, getProductListApi } from '#/api/product';
 import { $t } from '#/locales';
 
 import ProductForm from './form.vue';
@@ -90,7 +92,7 @@ const gridOptions: VxeGridProps<any> = {
       field: 'action',
       fixed: 'right',
       slots: { default: 'action' },
-      width: 140,
+      width: 150,
     },
   ],
 };
@@ -126,6 +128,22 @@ function formatMoney(row: any) {
 function handleFinish() {
   gridApi.reload();
 }
+
+/* 删除 */
+async function handleDelete(row: any) {
+  try {
+    await ElMessageBox.confirm('确认要删除该产品吗?', '提示', {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+      type: 'warning',
+    });
+    await deleteProductApi({ 'productsid.value': row.productsid });
+    ElMessage.success('删除成功');
+    gridApi.reload();
+  } catch (error) {
+    console.error(error);
+  }
+}
 </script>
 
 <template>
@@ -147,6 +165,12 @@ function handleFinish() {
           :icon="MdiEdit"
           class="!p-2"
         />
+        <el-button
+          round
+          @click="() => handleDelete(row)"
+          :icon="MdiDelete"
+          class="!p-2"
+        />
       </template>
     </Grid>
     <Modal @finish="handleFinish" />

+ 27 - 3
apps/web-ele/src/views/scqy-manage/index.vue

@@ -4,10 +4,12 @@ import type { VbenFormProps } from '@vben/common-ui';
 import type { VxeGridProps } from '#/adapter/vxe-table';
 
 import { Page, useVbenModal } from '@vben/common-ui';
-import { MdiDetail, MdiEdit } from '@vben/icons';
+import { MdiDelete, MdiDetail, MdiEdit } from '@vben/icons';
+
+import { ElMessage, ElMessageBox } from 'element-plus';
 
 import { useVbenVxeGrid } from '#/adapter/vxe-table';
-import { getScqyListApi } from '#/api/scqy';
+import { deleteScqyApi, getScqyListApi } from '#/api/scqy';
 import { $t } from '#/locales';
 
 import ScqyForm from './form.vue';
@@ -77,7 +79,7 @@ const gridOptions: VxeGridProps<any> = {
       field: 'action',
       fixed: 'right',
       slots: { default: 'action' },
-      width: 140,
+      width: 150,
     },
   ],
 };
@@ -109,6 +111,22 @@ function handleDetail(row: any) {
 function handleFinish() {
   gridApi.reload();
 }
+
+/* 删除 */
+async function handleDelete(row: any) {
+  try {
+    await ElMessageBox.confirm('确认要删除该生产企业吗?', '提示', {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+      type: 'warning',
+    });
+    await deleteScqyApi({ 'scqyinfoid.value': row.scqyinfoid });
+    ElMessage.success('删除成功');
+    gridApi.reload();
+  } catch (error) {
+    console.error(error);
+  }
+}
 </script>
 
 <template>
@@ -130,6 +148,12 @@ function handleFinish() {
           :icon="MdiEdit"
           class="!p-2"
         />
+        <el-button
+          round
+          @click="() => handleDelete(row)"
+          :icon="MdiDelete"
+          class="!p-2"
+        />
       </template>
     </Grid>
     <Modal @finish="handleFinish" />

+ 117 - 107
apps/web-ele/src/views/system-manage/data-dictionary/form.vue

@@ -1,180 +1,190 @@
 <script lang="ts" setup>
+import type { DictEntity } from '@vben/types';
+
 import { computed, ref } from 'vue';
 
 import { useVbenModal } from '@vben/common-ui';
 
+import { ElMessage } from 'element-plus';
+
 import { useVbenForm, z } from '#/adapter/form';
-// import { getCustomerDetailApi } from '#/api/customer-manage';
+import { addDictApi, editDictApi, getDictDetailApi } from '#/api/dict';
 
+const emit = defineEmits(['finish']);
 const data = ref();
+const formType = ref<'create' | 'detail' | 'edit'>('create');
+
+const titleMap = {
+  create: '新增配置',
+  detail: '配置详情',
+  edit: '编辑配置',
+} as const;
 
-const getTitle = computed(() => (data.value?.create ? '新增客户' : '编辑客户'));
+const getTitle = computed(() => titleMap[formType.value]);
 
 const [BaseForm, baseFormApi] = useVbenForm({
   showDefaultActions: false,
   // 所有表单项共用,可单独在表单内覆盖
   commonConfig: {
-    labelWidth: 120,
+    labelWidth: 130,
     // 所有表单项
     componentProps: {
       class: 'w-full',
     },
   },
+  wrapperClass: 'grid-cols-1 lg:grid-cols-2',
   schema: [
-    // { title: '用户名称', field: 'usersname' },
-    // { title: '用户性质', field: 'usersnature' },
-    // { title: '用户证件号码', field: 'usersidcardnumber' },
-    // { title: '用户开户银行名称', field: 'usersbankname' },
-    // { title: '用户开户银行账号', field: 'usersbanknumber' },
-    // { title: '用户手机号', field: 'usersphone' },
-    // { title: '用户邮箱', field: 'usersemail' },
-    // { title: '用户地址', field: 'usersaddress' },
-    // { title: '用户联系手机号', field: 'userscontactphone' },
-    // { title: '用户联系邮箱', field: 'userscontactemail' },
-    // { title: '用户联系地址', field: 'userscontactaddress' },
-    {
-      component: 'Input',
-      fieldName: 'usersname',
-      label: '用户名称',
-      componentProps: {
-        placeholder: '请输入用户名称',
-        allowClear: true,
-      },
-      rules: z.string().min(1, { message: '请输入用户名称' }),
-    },
     {
       component: 'Input',
-      fieldName: 'usersnature',
-      label: '用户性质',
+      fieldName: 'title',
+      label: '配置名称',
+      rules: z.string().min(1, '请输入配置名称'),
       componentProps: {
-        placeholder: '请输入用户性质',
-        allowClear: true,
+        placeholder: '请输入配置名称',
       },
-      rules: z.number().min(1, { message: '请输入用户性质' }),
     },
     {
       component: 'Input',
-      fieldName: 'usersidcardnumber',
-      label: '用户证件号码',
+      fieldName: 'groupname',
+      label: '组名称',
       componentProps: {
-        placeholder: '请输入用户证件号码',
-        allowClear: true,
+        placeholder: '请输入组名称',
       },
-      rules: z.string().min(1, { message: '请输入用户证件号码' }),
     },
+    // {
+    //   component: 'InputNumber',
+    //   fieldName: 'baseid',
+    //   label: '上级',
+    //   defaultValue: 0,
+    //   componentProps: {
+    //     placeholder: '请输入上级ID',
+    //     min: 0,
+    //   },
+    // },
     {
-      component: 'Input',
-      fieldName: 'usersbankname',
-      label: '用户开户银行名称',
+      component: 'Switch',
+      fieldName: 'available',
+      label: '状态',
+      defaultValue: 1,
       componentProps: {
-        placeholder: '请输入用户开户银行名称',
-        allowClear: true,
+        activeValue: 1,
+        inactiveValue: 0,
+        activeText: '可用',
+        inactiveText: '不可用',
       },
-      rules: z.string().min(1, { message: '请输入用户开户银行名称' }),
     },
+    // {
+    //   component: 'Switch',
+    //   fieldName: 'ispublic',
+    //   label: '前端可用',
+    //   defaultValue: 0,
+    //   componentProps: {
+    //     activeValue: 1,
+    //     inactiveValue: 0,
+    //     activeText: '是',
+    //     inactiveText: '否',
+    //   },
+    // },
+    // {
+    //   component: 'InputNumber',
+    //   fieldName: 'ranknum',
+    //   label: '排序值',
+    //   defaultValue: 0,
+    //   componentProps: {
+    //     placeholder: '请输入排序值',
+    //     min: 0,
+    //   },
+    // },
     {
       component: 'Input',
-      fieldName: 'usersbanknumber',
-      label: '用户开户银行账号',
+      fieldName: 'substance',
+      label: '配置值',
+      rules: z.string().min(1, '请输入配置值'),
       componentProps: {
-        placeholder: '请输入用户开户银行账号',
-        allowClear: true,
+        type: 'textarea',
+        placeholder: '请输入配置值',
+        rows: 4,
       },
-      rules: z.string().min(1, { message: '请输入用户开户银行账号' }),
-    },
-    {
-      component: 'Input',
-      fieldName: 'usersphone',
-      label: '用户手机号',
-      componentProps: {
-        placeholder: '请输入用户手机号',
-        allowClear: true,
+      wrapperProps: {
+        class: 'col-span-2',
       },
-      rules: z.string().min(1, { message: '请输入用户手机号' }),
     },
     {
       component: 'Input',
-      fieldName: 'usersemail',
-      label: '用户邮箱',
+      fieldName: 'describes',
+      label: '描述',
       componentProps: {
-        placeholder: '请输入用户邮箱',
-        allowClear: true,
+        type: 'textarea',
+        placeholder: '请输入描述',
+        rows: 3,
       },
-      rules: z.string().min(1, { message: '请输入用户邮箱' }),
-    },
-    {
-      component: 'Input',
-      fieldName: 'usersaddress',
-      label: '用户地址',
-      componentProps: {
-        placeholder: '请输入用户地址',
-        allowClear: true,
+      wrapperProps: {
+        class: 'col-span-2',
       },
-      rules: z.string().min(1, { message: '请输入用户地址' }),
-    },
-    {
-      component: 'Input',
-      fieldName: 'userscontactphone',
-      label: '用户联系手机号',
-      componentProps: {
-        placeholder: '请输入用户联系手机号',
-        allowClear: true,
-      },
-      rules: z.string().min(1, { message: '请输入用户联系手机号' }),
-    },
-    {
-      component: 'Input',
-      fieldName: 'userscontactemail',
-      label: '用户联系邮箱',
-      componentProps: {
-        placeholder: '请输入用户联系邮箱',
-        allowClear: true,
-      },
-      rules: z.string().min(1, { message: '请输入用户联系邮箱' }),
-    },
-    {
-      component: 'Input',
-      fieldName: 'userscontactaddress',
-      label: '用户联系地址',
-      componentProps: {
-        placeholder: '请输入用户联系地址',
-        allowClear: true,
-      },
-      rules: z.string().min(1, { message: '请输入用户联系地址' }),
     },
   ],
 });
 
 const [Modal, modalApi] = useVbenModal({
+  class: 'w-8/12',
   onCancel() {
     modalApi.close();
   },
   async onConfirm() {
     // 校验输入的数据
+    const formValues = await baseFormApi.getValues();
     const validate = await baseFormApi.validate();
     if (!validate.valid) {
       return;
     }
 
-    modalApi.close();
-    // const values = await baseFormApi.getValues();
+    try {
+      const apiMap = {
+        create: () => addDictApi(formValues as unknown as DictEntity),
+        edit: () =>
+          editDictApi({
+            ...formValues,
+            'id.value': data.value.row.id,
+          } as unknown as DictEntity),
+      };
 
-    // console.log(Object.keys(values));
+      if (formType.value === 'detail') {
+        modalApi.close();
+        return;
+      }
+
+      await apiMap[formType.value]();
+      ElMessage.success('操作成功');
+      emit('finish');
+      modalApi.close();
+    } catch {}
   },
   async onOpenChange(isOpen) {
     if (isOpen) {
       data.value = modalApi.getData();
 
-      if (data.value.create) {
+      formType.value = data.value.formType;
+
+      baseFormApi.setState({
+        commonConfig: { disabled: formType.value === 'detail' },
+      });
+
+      if (data.value.formType === 'create') {
+        // 新增时设置默认值
+        baseFormApi.setFieldValue('available', 1);
+        baseFormApi.setFieldValue('ispublic', 0);
+        baseFormApi.setFieldValue('baseid', 0);
+        baseFormApi.setFieldValue('ranknum', 0);
         return;
       }
 
       try {
-        // modalApi.setState({ loading: true });
-        // const detailData = await getCustomerDetailApi({
-        //   usersid: data.value.row.usersid,
-        // });
-        // baseFormApi.setValues(detailData);
+        modalApi.setState({ loading: true });
+        const detailData = await getDictDetailApi({
+          id: data.value.row.id,
+        });
+
+        baseFormApi.setValues(detailData);
       } catch {
         // console.log(error);
       }

+ 110 - 37
apps/web-ele/src/views/system-manage/data-dictionary/index.vue

@@ -3,14 +3,18 @@ import type { VbenFormProps } from '@vben/common-ui';
 
 import type { VxeGridProps } from '#/adapter/vxe-table';
 
+import { h } from 'vue';
+
 import { Page, useVbenModal } from '@vben/common-ui';
-import { MdiDetail, MdiEdit } from '@vben/icons';
+import { MdiDelete, MdiDetail, MdiEdit } from '@vben/icons';
+
+import { ElMessage, ElMessageBox, ElTag } from 'element-plus';
 
 import { useVbenVxeGrid } from '#/adapter/vxe-table';
-// import { getCustomerListApi } from '#/api/customer-manage';
+import { deleteDictApi, getDictListApi } from '#/api/dict';
 import { $t } from '#/locales';
 
-import CustomerForm from './form.vue';
+import DictForm from './form.vue';
 
 const formOptions: VbenFormProps = {
   // 默认展开
@@ -22,8 +26,8 @@ const formOptions: VbenFormProps = {
   schema: [
     {
       component: 'Input',
-      fieldName: 'usersname',
-      label: '用户名称',
+      fieldName: 'title',
+      label: '配置名称',
       componentProps: {
         placeholder: $t('ui.placeholder.input'),
         allowClear: true,
@@ -31,21 +35,34 @@ const formOptions: VbenFormProps = {
     },
     {
       component: 'Input',
-      fieldName: 'usersphone',
-      label: '用户手机号',
+      fieldName: 'groupname',
+      label: '组名称',
       componentProps: {
         placeholder: $t('ui.placeholder.input'),
         allowClear: true,
       },
     },
+    {
+      component: 'Select',
+      fieldName: 'available',
+      label: '状态',
+      componentProps: {
+        placeholder: $t('ui.placeholder.select'),
+        allowClear: true,
+        options: [
+          { label: '可用', value: 1 },
+          { label: '不可用', value: 0 },
+        ],
+      },
+    },
   ],
+  wrapperClass: 'grid-cols-1 md:grid-cols-3 lg:grid-cols-5',
 };
 
 const gridOptions: VxeGridProps<any> = {
   toolbarConfig: {
     custom: true,
     export: true,
-    // import: true,
     refresh: true,
     zoom: true,
   },
@@ -62,68 +79,118 @@ const gridOptions: VxeGridProps<any> = {
       result: 'Data',
       total: 'Total',
     },
-    // ajax: {
-    //   query: async ({ page }, formValues) => {
-    //     return await getCustomerListApi({
-    //       pageindex: page.currentPage,
-    //       rows: page.pageSize,
-    //       ...formValues,
-    //     });
-    //   },
-    // },
+    ajax: {
+      query: async ({ page }, formValues) => {
+        return await getDictListApi({
+          pageindex: page.currentPage,
+          rows: page.pageSize,
+          ...formValues,
+        });
+      },
+    },
   },
 
   columns: [
-    { title: '用户名称', field: 'usersname' },
-    { title: '用户性质', field: 'usersnature' },
-    { title: '用户证件号码', field: 'usersidcardnumber' },
-    { title: '用户开户银行名称', field: 'usersbankname' },
-    { title: '用户开户银行账号', field: 'usersbanknumber' },
-    { title: '用户手机号', field: 'usersphone' },
-    { title: '用户邮箱', field: 'usersemail' },
-    { title: '用户地址', field: 'usersaddress' },
-    { title: '用户联系手机号', field: 'userscontactphone' },
-    { title: '用户联系邮箱', field: 'userscontactemail' },
-    { title: '用户联系地址', field: 'userscontactaddress' },
+    { title: '配置名称', field: 'title' },
+    { title: '组名称', field: 'groupname' },
+    { title: '配置值', field: 'substance' },
+    {
+      title: '状态',
+      field: 'available',
+      slots: {
+        default: ({ row }) => {
+          const status = row.available;
+          return h(
+            ElTag,
+            {
+              type: status === 1 ? 'success' : 'danger',
+              effect: 'dark',
+              size: 'small',
+              round: true,
+            },
+            () => (status === 1 ? '可用' : '不可用'),
+          );
+        },
+      },
+    },
+    { title: '描述', field: 'describes' },
+    // {
+    //   title: '前端可用',
+    //   field: 'ispublic',
+    //   slots: {
+    //     default: ({ row }) => {
+    //       const status = row.ispublic;
+    //       return h(
+    //         ElTag,
+    //         {
+    //           type: status === 1 ? 'success' : 'info',
+    //           effect: 'light',
+    //           size: 'small',
+    //         },
+    //         () => (status === 1 ? '是' : '否'),
+    //       );
+    //     },
+    //   },
+    // },
+    // { title: '排序值', field: 'ranknum' },
     {
       title: '操作',
       field: 'action',
       fixed: 'right',
       slots: { default: 'action' },
-      width: 140,
+      width: 150,
     },
   ],
 };
 
-const [Grid] = useVbenVxeGrid({ gridOptions, formOptions });
+const [Grid, gridApi] = useVbenVxeGrid({ gridOptions, formOptions });
 
 const [Modal, modalApi] = useVbenModal({
   fullscreenButton: false,
   closeOnClickModal: false,
   closeOnPressEscape: false,
-  connectedComponent: CustomerForm,
+  connectedComponent: DictForm,
 });
 
 /* 创建 */
 function handleCreate() {
-  modalApi.setData({ create: true }).open();
+  modalApi.setData({ formType: 'create' }).open();
 }
 
 /* 编辑 */
 function handleEdit(row: any) {
-  modalApi.setData({ row }).open();
+  modalApi.setData({ formType: 'edit', row }).open();
 }
 
 /* 详情 */
 function handleDetail(row: any) {
-  modalApi.setData({ row }).open();
-  // router.push(`/system/users/detail/${row.userName}`);
+  modalApi.setData({ formType: 'detail', row }).open();
+}
+
+/* 删除 */
+async function handleDelete(row: any) {
+  try {
+    await ElMessageBox.confirm('确认要删除该配置吗?', '提示', {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+      type: 'warning',
+    });
+    await deleteDictApi({ 'id.value': row.id });
+    ElMessage.success('删除成功');
+    gridApi.reload();
+  } catch (error) {
+    console.error(error);
+  }
+}
+
+function handleFinish() {
+  gridApi.reload();
 }
 </script>
 
 <template>
   <Page auto-content-height>
-    <Grid table-title="字典列表">
+    <Grid table-title="数据字典列表">
       <template #toolbar-tools>
         <el-button type="primary" @click="handleCreate"> 新增 </el-button>
       </template>
@@ -140,8 +207,14 @@ function handleDetail(row: any) {
           :icon="MdiEdit"
           class="!p-2"
         />
+        <el-button
+          round
+          @click="() => handleDelete(row)"
+          :icon="MdiDelete"
+          class="!p-2"
+        />
       </template>
     </Grid>
-    <Modal />
+    <Modal @finish="handleFinish" />
   </Page>
 </template>

+ 166 - 82
apps/web-ele/src/views/system-manage/menu-manage/form.vue

@@ -1,180 +1,264 @@
 <script lang="ts" setup>
+import type { MenuEntity } from '@vben/types';
+
 import { computed, ref } from 'vue';
 
 import { useVbenModal } from '@vben/common-ui';
 
+import { ElMessage } from 'element-plus';
+
 import { useVbenForm, z } from '#/adapter/form';
-// import { getCustomerDetailApi } from '#/api/customer-manage';
+import {
+  addMenuApi,
+  editMenuApi,
+  getMenuDetailApi,
+  getMenuListApi,
+} from '#/api/menu';
 
+const emit = defineEmits(['finish']);
 const data = ref();
+const formType = ref<'create' | 'detail' | 'edit'>('create');
+const parentMenus = ref<{ label: string; value: number }[]>([]);
+
+const titleMap = {
+  create: '新增菜单',
+  detail: '菜单详情',
+  edit: '编辑菜单',
+} as const;
 
-const getTitle = computed(() => (data.value?.create ? '新增客户' : '编辑客户'));
+const getTitle = computed(() => titleMap[formType.value]);
+
+// 获取父级菜单列表
+async function fetchParentMenus() {
+  try {
+    const res = await getMenuListApi({
+      pageindex: 1,
+      rows: 1000,
+      menu_type: 1, // 只获取目录类型的菜单作为父级
+    });
+
+    if (res && res.Data) {
+      parentMenus.value = res.Data.map((item: MenuEntity) => ({
+        label: item.menu_name,
+        value: item.menu_id,
+      }));
+      // 添加一个根菜单选项
+      parentMenus.value.unshift({ label: '根菜单', value: 0 });
+    }
+  } catch (error) {
+    console.error('获取父级菜单失败', error);
+  }
+}
 
 const [BaseForm, baseFormApi] = useVbenForm({
   showDefaultActions: false,
   // 所有表单项共用,可单独在表单内覆盖
   commonConfig: {
-    labelWidth: 120,
+    labelWidth: 130,
     // 所有表单项
     componentProps: {
       class: 'w-full',
     },
   },
+  wrapperClass: 'grid-cols-1 lg:grid-cols-2',
   schema: [
-    // { title: '用户名称', field: 'usersname' },
-    // { title: '用户性质', field: 'usersnature' },
-    // { title: '用户证件号码', field: 'usersidcardnumber' },
-    // { title: '用户开户银行名称', field: 'usersbankname' },
-    // { title: '用户开户银行账号', field: 'usersbanknumber' },
-    // { title: '用户手机号', field: 'usersphone' },
-    // { title: '用户邮箱', field: 'usersemail' },
-    // { title: '用户地址', field: 'usersaddress' },
-    // { title: '用户联系手机号', field: 'userscontactphone' },
-    // { title: '用户联系邮箱', field: 'userscontactemail' },
-    // { title: '用户联系地址', field: 'userscontactaddress' },
     {
       component: 'Input',
-      fieldName: 'usersname',
-      label: '用户名称',
+      fieldName: 'menu_name',
+      label: '菜单名称',
+      rules: z.string().min(1, '请输入菜单名称'),
       componentProps: {
-        placeholder: '请输入用户名称',
-        allowClear: true,
+        placeholder: '请输入菜单名称',
       },
-      rules: z.string().min(1, { message: '请输入用户名称' }),
     },
     {
-      component: 'Input',
-      fieldName: 'usersnature',
-      label: '用户性质',
+      component: 'Select',
+      fieldName: 'menu_type',
+      label: '菜单类型',
+      rules: z.number().min(1, '请选择菜单类型'),
       componentProps: {
-        placeholder: '请输入用户性质',
-        allowClear: true,
+        placeholder: '请选择菜单类型',
+        options: [
+          { label: '目录', value: 1 },
+          { label: '菜单', value: 2 },
+          { label: '按钮', value: 3 },
+          { label: 'API接口', value: 4 },
+        ],
       },
-      rules: z.number().min(1, { message: '请输入用户性质' }),
     },
+    // {
+    //   component: 'Input',
+    //   fieldName: 'menu_sort',
+    //   label: '菜单分类',
+    //   componentProps: {
+    //     placeholder: '请输入菜单分类',
+    //   },
+    // },
     {
       component: 'Input',
-      fieldName: 'usersidcardnumber',
-      label: '用户证件号码',
+      fieldName: 'menu_key',
+      label: '菜单标识',
       componentProps: {
-        placeholder: '请输入用户证件号码',
-        allowClear: true,
+        placeholder: '请输入菜单标识',
       },
-      rules: z.string().min(1, { message: '请输入用户证件号码' }),
     },
     {
-      component: 'Input',
-      fieldName: 'usersbankname',
-      label: '用户开户银行名称',
+      component: 'Select',
+      fieldName: 'parent_id',
+      label: '父级菜单',
+      defaultValue: 0,
       componentProps: {
-        placeholder: '请输入用户开户银行名称',
-        allowClear: true,
+        placeholder: '请选择父级菜单',
+        options: parentMenus,
       },
-      rules: z.string().min(1, { message: '请输入用户开户银行名称' }),
     },
     {
-      component: 'Input',
-      fieldName: 'usersbanknumber',
-      label: '用户开户银行账号',
+      component: 'InputNumber',
+      fieldName: 'order_num',
+      label: '显示顺序',
+      defaultValue: 0,
       componentProps: {
-        placeholder: '请输入用户开户银行账号',
-        allowClear: true,
+        placeholder: '请输入显示顺序',
+        min: 0,
       },
-      rules: z.string().min(1, { message: '请输入用户开户银行账号' }),
     },
     {
       component: 'Input',
-      fieldName: 'usersphone',
-      label: '用户手机号',
+      fieldName: 'path',
+      label: '路径',
       componentProps: {
-        placeholder: '请输入用户手机号',
-        allowClear: true,
+        placeholder: '请输入路径',
       },
-      rules: z.string().min(1, { message: '请输入用户手机号' }),
     },
     {
       component: 'Input',
-      fieldName: 'usersemail',
-      label: '用户邮箱',
+      fieldName: 'component',
+      label: '组件',
       componentProps: {
-        placeholder: '请输入用户邮箱',
-        allowClear: true,
+        placeholder: '请输入组件',
       },
-      rules: z.string().min(1, { message: '请输入用户邮箱' }),
     },
     {
       component: 'Input',
-      fieldName: 'usersaddress',
-      label: '用户地址',
+      fieldName: 'icon',
+      label: '图标',
       componentProps: {
-        placeholder: '请输入用户地址',
-        allowClear: true,
+        placeholder: '请输入图标',
       },
-      rules: z.string().min(1, { message: '请输入用户地址' }),
     },
     {
       component: 'Input',
-      fieldName: 'userscontactphone',
-      label: '用户联系手机号',
+      fieldName: 'perms',
+      label: '权限标识',
       componentProps: {
-        placeholder: '请输入用户联系手机号',
-        allowClear: true,
+        placeholder: '请输入权限标识',
       },
-      rules: z.string().min(1, { message: '请输入用户联系手机号' }),
     },
     {
-      component: 'Input',
-      fieldName: 'userscontactemail',
-      label: '用户联系邮箱',
+      component: 'Switch',
+      fieldName: 'visible',
+      label: '菜单状态',
+      defaultValue: 0,
       componentProps: {
-        placeholder: '请输入用户联系邮箱',
-        allowClear: true,
+        activeValue: 0,
+        inactiveValue: 1,
+        activeText: '显示',
+        inactiveText: '隐藏',
+      },
+    },
+    {
+      component: 'Switch',
+      fieldName: 'no_cache',
+      label: '是否缓存',
+      defaultValue: 0,
+      componentProps: {
+        activeValue: 1,
+        inactiveValue: 0,
+        activeText: '是',
+        inactiveText: '否',
       },
-      rules: z.string().min(1, { message: '请输入用户联系邮箱' }),
     },
     {
       component: 'Input',
-      fieldName: 'userscontactaddress',
-      label: '用户联系地址',
+      fieldName: 'remark',
+      label: '备注',
       componentProps: {
-        placeholder: '请输入用户联系地址',
-        allowClear: true,
+        type: 'textarea',
+        placeholder: '请输入备注',
+        rows: 3,
+      },
+      // @ts-ignore wrapperProps属性在运行时有效,但类型定义中缺失
+      wrapperProps: {
+        class: 'col-span-2',
       },
-      rules: z.string().min(1, { message: '请输入用户联系地址' }),
     },
   ],
 });
 
 const [Modal, modalApi] = useVbenModal({
+  class: 'w-8/12',
   onCancel() {
     modalApi.close();
   },
   async onConfirm() {
     // 校验输入的数据
+    const formValues = await baseFormApi.getValues();
     const validate = await baseFormApi.validate();
     if (!validate.valid) {
       return;
     }
 
-    modalApi.close();
-    // const values = await baseFormApi.getValues();
+    try {
+      const apiMap = {
+        create: () => addMenuApi(formValues as unknown as MenuEntity),
+        edit: () =>
+          editMenuApi({
+            ...formValues,
+            'menu_id.value': data.value.row.menu_id,
+          } as unknown as MenuEntity),
+      };
 
-    // console.log(Object.keys(values));
+      if (formType.value === 'detail') {
+        modalApi.close();
+        return;
+      }
+
+      await apiMap[formType.value]();
+      ElMessage.success('操作成功');
+      emit('finish');
+      modalApi.close();
+    } catch {}
   },
   async onOpenChange(isOpen) {
     if (isOpen) {
       data.value = modalApi.getData();
 
-      if (data.value.create) {
+      formType.value = data.value.formType;
+
+      // 获取父级菜单列表
+      await fetchParentMenus();
+
+      baseFormApi.setState({
+        commonConfig: { disabled: formType.value === 'detail' },
+      });
+
+      if (data.value.formType === 'create') {
+        // 新增时设置默认值
+        baseFormApi.setFieldValue('visible', 0);
+        baseFormApi.setFieldValue('no_cache', 0);
+        baseFormApi.setFieldValue('parent_id', 0);
+        baseFormApi.setFieldValue('order_num', 0);
+        baseFormApi.setFieldValue('menu_type', 1);
         return;
       }
 
       try {
-        // modalApi.setState({ loading: true });
-        // const detailData = await getCustomerDetailApi({
-        //   usersid: data.value.row.usersid,
-        // });
-        // baseFormApi.setValues(detailData);
+        modalApi.setState({ loading: true });
+        const detailData = await getMenuDetailApi({
+          menu_id: data.value.row.menu_id,
+        });
+
+        baseFormApi.setValues(detailData);
       } catch {
         // console.log(error);
       }

+ 121 - 36
apps/web-ele/src/views/system-manage/menu-manage/index.vue

@@ -3,14 +3,18 @@ import type { VbenFormProps } from '@vben/common-ui';
 
 import type { VxeGridProps } from '#/adapter/vxe-table';
 
+import { h } from 'vue';
+
 import { Page, useVbenModal } from '@vben/common-ui';
-import { MdiDetail, MdiEdit } from '@vben/icons';
+import { MdiDelete, MdiDetail, MdiEdit } from '@vben/icons';
+
+import { ElMessage, ElMessageBox, ElTag } from 'element-plus';
 
 import { useVbenVxeGrid } from '#/adapter/vxe-table';
-// import { getCustomerListApi } from '#/api/customer-manage';
+import { deleteMenuApi, getMenuListApi } from '#/api/menu';
 import { $t } from '#/locales';
 
-import CustomerForm from './form.vue';
+import MenuForm from './form.vue';
 
 const formOptions: VbenFormProps = {
   // 默认展开
@@ -22,8 +26,8 @@ const formOptions: VbenFormProps = {
   schema: [
     {
       component: 'Input',
-      fieldName: 'usersname',
-      label: '用户名称',
+      fieldName: 'menu_name',
+      label: '菜单名称',
       componentProps: {
         placeholder: $t('ui.placeholder.input'),
         allowClear: true,
@@ -31,21 +35,36 @@ const formOptions: VbenFormProps = {
     },
     {
       component: 'Input',
-      fieldName: 'usersphone',
-      label: '用户手机号',
+      fieldName: 'menu_sort',
+      label: '菜单分类',
       componentProps: {
         placeholder: $t('ui.placeholder.input'),
         allowClear: true,
       },
     },
+    {
+      component: 'Select',
+      fieldName: 'menu_type',
+      label: '菜单类型',
+      componentProps: {
+        placeholder: $t('ui.placeholder.select'),
+        allowClear: true,
+        options: [
+          { label: '目录', value: 1 },
+          { label: '菜单', value: 2 },
+          { label: '按钮', value: 3 },
+          { label: 'API接口', value: 4 },
+        ],
+      },
+    },
   ],
+  wrapperClass: 'grid-cols-1 md:grid-cols-3 lg:grid-cols-5',
 };
 
 const gridOptions: VxeGridProps<any> = {
   toolbarConfig: {
     custom: true,
     export: true,
-    // import: true,
     refresh: true,
     zoom: true,
   },
@@ -62,62 +81,122 @@ const gridOptions: VxeGridProps<any> = {
       result: 'Data',
       total: 'Total',
     },
-    // ajax: {
-    //   query: async ({ page }, formValues) => {
-    //     return await getCustomerListApi({
-    //       pageindex: page.currentPage,
-    //       rows: page.pageSize,
-    //       ...formValues,
-    //     });
-    //   },
-    // },
+    ajax: {
+      query: async ({ page }, formValues) => {
+        return await getMenuListApi({
+          pageindex: page.currentPage,
+          rows: page.pageSize,
+          ...formValues,
+        });
+      },
+    },
   },
 
   columns: [
-    { title: '用户名称', field: 'usersname' },
-    { title: '用户性质', field: 'usersnature' },
-    { title: '用户证件号码', field: 'usersidcardnumber' },
-    { title: '用户开户银行名称', field: 'usersbankname' },
-    { title: '用户开户银行账号', field: 'usersbanknumber' },
-    { title: '用户手机号', field: 'usersphone' },
-    { title: '用户邮箱', field: 'usersemail' },
-    { title: '用户地址', field: 'usersaddress' },
-    { title: '用户联系手机号', field: 'userscontactphone' },
-    { title: '用户联系邮箱', field: 'userscontactemail' },
-    { title: '用户联系地址', field: 'userscontactaddress' },
+    { title: '菜单名称', field: 'menu_name' },
+    // { title: '菜单分类', field: 'menu_sort' },
+    {
+      title: '菜单类型',
+      field: 'menu_type',
+      slots: {
+        default: ({ row }) => {
+          const type = row.menu_type;
+          const typeMap = {
+            1: { text: '目录', type: 'primary' },
+            2: { text: '菜单', type: 'success' },
+            3: { text: '按钮', type: 'warning' },
+            4: { text: 'API接口', type: 'info' },
+          };
+          return h(
+            ElTag,
+            {
+              // @ts-ignore 运行时类型安全,但TypeScript无法正确推断
+              type: typeMap[type]?.type || 'info',
+              effect: 'light',
+              size: 'small',
+            },
+            // @ts-ignore 运行时类型安全,但TypeScript无法正确推断
+            () => typeMap[type]?.text || '未知',
+          );
+        },
+      },
+    },
+    { title: '菜单标识', field: 'menu_key' },
+    { title: '路径', field: 'path' },
+    { title: '组件', field: 'component' },
+    { title: '图标', field: 'icon' },
+    {
+      title: '状态',
+      field: 'visible',
+      slots: {
+        default: ({ row }) => {
+          const status = row.visible;
+          return h(
+            ElTag,
+            {
+              type: status === 0 ? 'success' : 'danger',
+              effect: 'dark',
+              size: 'small',
+              round: true,
+            },
+            () => (status === 0 ? '显示' : '隐藏'),
+          );
+        },
+      },
+    },
+    { title: '排序', field: 'order_num' },
     {
       title: '操作',
       field: 'action',
       fixed: 'right',
       slots: { default: 'action' },
-      width: 140,
+      width: 150,
     },
   ],
 };
 
-const [Grid] = useVbenVxeGrid({ gridOptions, formOptions });
+const [Grid, gridApi] = useVbenVxeGrid({ gridOptions, formOptions });
 
 const [Modal, modalApi] = useVbenModal({
   fullscreenButton: false,
   closeOnClickModal: false,
   closeOnPressEscape: false,
-  connectedComponent: CustomerForm,
+  connectedComponent: MenuForm,
 });
 
 /* 创建 */
 function handleCreate() {
-  modalApi.setData({ create: true }).open();
+  modalApi.setData({ formType: 'create' }).open();
 }
 
 /* 编辑 */
 function handleEdit(row: any) {
-  modalApi.setData({ row }).open();
+  modalApi.setData({ formType: 'edit', row }).open();
 }
 
 /* 详情 */
 function handleDetail(row: any) {
-  modalApi.setData({ row }).open();
-  // router.push(`/system/users/detail/${row.userName}`);
+  modalApi.setData({ formType: 'detail', row }).open();
+}
+
+/* 删除 */
+async function handleDelete(row: any) {
+  try {
+    await ElMessageBox.confirm('确认要删除该菜单吗?', '提示', {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+      type: 'warning',
+    });
+    await deleteMenuApi({ 'menu_id.value': row.menu_id });
+    ElMessage.success('删除成功');
+    gridApi.reload();
+  } catch (error) {
+    console.error(error);
+  }
+}
+
+function handleFinish() {
+  gridApi.reload();
 }
 </script>
 
@@ -140,8 +219,14 @@ function handleDetail(row: any) {
           :icon="MdiEdit"
           class="!p-2"
         />
+        <el-button
+          round
+          @click="() => handleDelete(row)"
+          :icon="MdiDelete"
+          class="!p-2"
+        />
       </template>
     </Grid>
-    <Modal />
+    <Modal @finish="handleFinish" />
   </Page>
 </template>

+ 100 - 0
apps/web-ele/src/views/system-manage/operation-logs/detail.vue

@@ -0,0 +1,100 @@
+<script setup lang="ts">
+import type { LogEntity } from '@vben/types';
+
+import { computed, ref } from 'vue';
+
+import { useVbenModal } from '@vben/common-ui';
+
+import { getLogDetailApi } from '#/api/log';
+
+const data = ref();
+const logDetail = ref<LogEntity | null>(null);
+const loading = ref(false);
+
+const getTitle = computed(() => '日志详情');
+
+const [Modal, modalApi] = useVbenModal({
+  class: 'w-10/12',
+  async onOpenChange(isOpen) {
+    if (isOpen) {
+      data.value = modalApi.getData();
+      await fetchLogDetail();
+    }
+  },
+});
+
+async function fetchLogDetail() {
+  if (!data.value?.row?.id) return;
+
+  try {
+    loading.value = true;
+    const res = await getLogDetailApi({
+      id: data.value.row.id,
+    });
+    logDetail.value = res;
+  } catch (error) {
+    console.error('获取日志详情失败', error);
+  } finally {
+    loading.value = false;
+  }
+}
+</script>
+
+<template>
+  <Modal :title="getTitle">
+    <div v-loading="loading" class="p-4">
+      <el-descriptions v-if="logDetail" :column="2" border class="mb-4">
+        <el-descriptions-item label="流水号">
+          {{ logDetail.id }}
+        </el-descriptions-item>
+        <el-descriptions-item label="方法名">
+          {{ logDetail.method }}
+        </el-descriptions-item>
+        <el-descriptions-item label="终端">
+          {{ logDetail.terminal }}
+        </el-descriptions-item>
+        <el-descriptions-item label="IP地址">
+          {{ logDetail.ip }}
+        </el-descriptions-item>
+        <el-descriptions-item label="执行时间(ms)">
+          {{ logDetail.extime }}
+        </el-descriptions-item>
+        <el-descriptions-item label="账号">
+          {{ logDetail.account }}
+        </el-descriptions-item>
+        <el-descriptions-item label="生成时间">
+          {{ logDetail.createtime }}
+        </el-descriptions-item>
+        <el-descriptions-item label="模式">
+          {{ logDetail.mode }}
+        </el-descriptions-item>
+      </el-descriptions>
+
+      <el-divider content-position="left">请求地址</el-divider>
+      <el-input
+        type="textarea"
+        :model-value="logDetail?.url || ''"
+        :rows="2"
+        readonly
+        class="mb-4"
+      />
+
+      <el-divider content-position="left">接收内容</el-divider>
+      <el-input
+        type="textarea"
+        :model-value="logDetail?.sendcontent || ''"
+        :rows="8"
+        readonly
+        class="mb-4"
+      />
+
+      <el-divider content-position="left">返回内容</el-divider>
+      <el-input
+        type="textarea"
+        :model-value="logDetail?.getcontent || ''"
+        :rows="8"
+        readonly
+      />
+    </div>
+  </Modal>
+</template>

+ 80 - 54
apps/web-ele/src/views/system-manage/operation-logs/index.vue

@@ -3,14 +3,18 @@ import type { VbenFormProps } from '@vben/common-ui';
 
 import type { VxeGridProps } from '#/adapter/vxe-table';
 
+import { h } from 'vue';
+
 import { Page, useVbenModal } from '@vben/common-ui';
-import { MdiDetail, MdiEdit } from '@vben/icons';
+import { MdiDetail } from '@vben/icons';
+
+import { ElTag } from 'element-plus';
 
 import { useVbenVxeGrid } from '#/adapter/vxe-table';
-// import { getCustomerListApi } from '#/api/customer-manage';
+import { getLogListApi } from '#/api/log';
 import { $t } from '#/locales';
 
-import CustomerForm from './form.vue';
+import LogDetail from './detail.vue';
 
 const formOptions: VbenFormProps = {
   // 默认展开
@@ -22,8 +26,8 @@ const formOptions: VbenFormProps = {
   schema: [
     {
       component: 'Input',
-      fieldName: 'usersname',
-      label: '用户名称',
+      fieldName: 'method',
+      label: '方法名',
       componentProps: {
         placeholder: $t('ui.placeholder.input'),
         allowClear: true,
@@ -31,21 +35,40 @@ const formOptions: VbenFormProps = {
     },
     {
       component: 'Input',
-      fieldName: 'usersphone',
-      label: '用户手机号',
+      fieldName: 'terminal',
+      label: '终端',
       componentProps: {
         placeholder: $t('ui.placeholder.input'),
         allowClear: true,
       },
     },
+    {
+      component: 'Input',
+      fieldName: 'account',
+      label: '账号',
+      componentProps: {
+        placeholder: $t('ui.placeholder.input'),
+        allowClear: true,
+      },
+    },
+    {
+      component: 'DatePicker',
+      fieldName: 'createtime',
+      label: '生成时间',
+      componentProps: {
+        type: 'datetime',
+        placeholder: '请选择时间',
+        valueFormat: 'YYYY-MM-DD HH:mm:ss',
+      },
+    },
   ],
+  wrapperClass: 'grid-cols-1 md:grid-cols-3 lg:grid-cols-5',
 };
 
 const gridOptions: VxeGridProps<any> = {
   toolbarConfig: {
     custom: true,
     export: true,
-    // import: true,
     refresh: true,
     zoom: true,
   },
@@ -62,71 +85,80 @@ const gridOptions: VxeGridProps<any> = {
       result: 'Data',
       total: 'Total',
     },
-    // ajax: {
-    //   query: async ({ page }, formValues) => {
-    //     return await getCustomerListApi({
-    //       pageindex: page.currentPage,
-    //       rows: page.pageSize,
-    //       ...formValues,
-    //     });
-    //   },
-    // },
+    ajax: {
+      query: async ({ page }, formValues) => {
+        return await getLogListApi({
+          pageindex: page.currentPage,
+          rows: page.pageSize,
+          ...formValues,
+        });
+      },
+    },
   },
 
   columns: [
-    { title: '用户名称', field: 'usersname' },
-    { title: '用户性质', field: 'usersnature' },
-    { title: '用户证件号码', field: 'usersidcardnumber' },
-    { title: '用户开户银行名称', field: 'usersbankname' },
-    { title: '用户开户银行账号', field: 'usersbanknumber' },
-    { title: '用户手机号', field: 'usersphone' },
-    { title: '用户邮箱', field: 'usersemail' },
-    { title: '用户地址', field: 'usersaddress' },
-    { title: '用户联系手机号', field: 'userscontactphone' },
-    { title: '用户联系邮箱', field: 'userscontactemail' },
-    { title: '用户联系地址', field: 'userscontactaddress' },
+    { title: '流水号', field: 'id' },
+    { title: '方法名', field: 'method' },
+    { title: '终端', field: 'terminal' },
+    {
+      title: '执行时间(ms)',
+      field: 'extime',
+      slots: {
+        default: ({ row }) => {
+          const time = row.extime;
+          let type = 'success';
+          if (time > 1000) {
+            type = 'danger';
+          } else if (time > 500) {
+            type = 'warning';
+          }
+          return h(
+            ElTag,
+            {
+              type,
+              effect: 'light',
+              size: 'small',
+            },
+            () => time,
+          );
+        },
+      },
+    },
+    { title: 'IP地址', field: 'ip' },
+    { title: '账号', field: 'account' },
+    { title: '生成时间', field: 'createtime' },
     {
       title: '操作',
       field: 'action',
       fixed: 'right',
       slots: { default: 'action' },
-      width: 140,
+      width: 80,
     },
   ],
 };
 
-const [Grid] = useVbenVxeGrid({ gridOptions, formOptions });
+const [Grid, gridApi] = useVbenVxeGrid({ gridOptions, formOptions });
 
 const [Modal, modalApi] = useVbenModal({
-  fullscreenButton: false,
+  fullscreenButton: true,
   closeOnClickModal: false,
   closeOnPressEscape: false,
-  connectedComponent: CustomerForm,
+  connectedComponent: LogDetail,
 });
 
-/* 创建 */
-function handleCreate() {
-  modalApi.setData({ create: true }).open();
-}
-
-/* 编辑 */
-function handleEdit(row: any) {
-  modalApi.setData({ row }).open();
-}
-
 /* 详情 */
 function handleDetail(row: any) {
   modalApi.setData({ row }).open();
-  // router.push(`/system/users/detail/${row.userName}`);
+}
+
+function handleFinish() {
+  gridApi.reload();
 }
 </script>
 
 <template>
   <Page auto-content-height>
-    <Grid table-title="日志列表">
-      <template #toolbar-tools>
-        <el-button type="primary" @click="handleCreate"> 新增 </el-button>
-      </template>
+    <Grid table-title="操作日志列表">
       <template #action="{ row }">
         <el-button
           round
@@ -134,14 +166,8 @@ function handleDetail(row: any) {
           :icon="MdiDetail"
           class="!p-2"
         />
-        <el-button
-          round
-          @click="() => handleEdit(row)"
-          :icon="MdiEdit"
-          class="!p-2"
-        />
       </template>
     </Grid>
-    <Modal />
+    <Modal @finish="handleFinish" />
   </Page>
 </template>

+ 90 - 115
apps/web-ele/src/views/system-manage/role-manage/form.vue

@@ -1,14 +1,26 @@
 <script lang="ts" setup>
+import type { RoleGroupEntity } from '@vben/types';
+
 import { computed, ref } from 'vue';
 
 import { useVbenModal } from '@vben/common-ui';
 
+import { ElMessage } from 'element-plus';
+
 import { useVbenForm, z } from '#/adapter/form';
-// import { getCustomerDetailApi } from '#/api/customer-manage';
+import { addRoleApi, editRoleApi, getRoleDetailApi } from '#/api/role';
 
+const emit = defineEmits(['finish']);
 const data = ref();
+const formType = ref<'create' | 'detail' | 'edit'>('create');
+
+const titleMap = {
+  create: '新增角色',
+  detail: '角色详情',
+  edit: '编辑角色',
+} as const;
 
-const getTitle = computed(() => (data.value?.create ? '新增客户' : '编辑客户'));
+const getTitle = computed(() => titleMap[formType.value]);
 
 const [BaseForm, baseFormApi] = useVbenForm({
   showDefaultActions: false,
@@ -20,163 +32,126 @@ const [BaseForm, baseFormApi] = useVbenForm({
       class: 'w-full',
     },
   },
+  wrapperClass: 'grid-cols-1 lg:grid-cols-2',
   schema: [
-    // { title: '用户名称', field: 'usersname' },
-    // { title: '用户性质', field: 'usersnature' },
-    // { title: '用户证件号码', field: 'usersidcardnumber' },
-    // { title: '用户开户银行名称', field: 'usersbankname' },
-    // { title: '用户开户银行账号', field: 'usersbanknumber' },
-    // { title: '用户手机号', field: 'usersphone' },
-    // { title: '用户邮箱', field: 'usersemail' },
-    // { title: '用户地址', field: 'usersaddress' },
-    // { title: '用户联系手机号', field: 'userscontactphone' },
-    // { title: '用户联系邮箱', field: 'userscontactemail' },
-    // { title: '用户联系地址', field: 'userscontactaddress' },
-    {
-      component: 'Input',
-      fieldName: 'usersname',
-      label: '用户名称',
-      componentProps: {
-        placeholder: '请输入用户名称',
-        allowClear: true,
-      },
-      rules: z.string().min(1, { message: '请输入用户名称' }),
-    },
-    {
-      component: 'Input',
-      fieldName: 'usersnature',
-      label: '用户性质',
-      componentProps: {
-        placeholder: '请输入用户性质',
-        allowClear: true,
-      },
-      rules: z.number().min(1, { message: '请输入用户性质' }),
-    },
-    {
-      component: 'Input',
-      fieldName: 'usersidcardnumber',
-      label: '用户证件号码',
-      componentProps: {
-        placeholder: '请输入用户证件号码',
-        allowClear: true,
-      },
-      rules: z.string().min(1, { message: '请输入用户证件号码' }),
-    },
     {
       component: 'Input',
-      fieldName: 'usersbankname',
-      label: '用户开户银行名称',
+      fieldName: 'title',
+      label: '角色名称',
+      rules: z.string().min(1, '请输入角色名称'),
       componentProps: {
-        placeholder: '请输入用户开户银行名称',
-        allowClear: true,
+        placeholder: '请输入角色名称',
       },
-      rules: z.string().min(1, { message: '请输入用户开户银行名称' }),
     },
+    // {
+    //   component: 'InputNumber',
+    //   fieldName: 'group_sort',
+    //   label: '排序',
+    //   defaultValue: 0,
+    //   componentProps: {
+    //     placeholder: '请输入排序值',
+    //     min: 0,
+    //   },
+    // },
     {
-      component: 'Input',
-      fieldName: 'usersbanknumber',
-      label: '用户开户银行账号',
-      componentProps: {
-        placeholder: '请输入用户开户银行账号',
-        allowClear: true,
-      },
-      rules: z.string().min(1, { message: '请输入用户开户银行账号' }),
-    },
-    {
-      component: 'Input',
-      fieldName: 'usersphone',
-      label: '用户手机号',
+      component: 'Switch',
+      fieldName: 'available',
+      label: '状态',
+      defaultValue: 0,
       componentProps: {
-        placeholder: '请输入用户手机号',
-        allowClear: true,
+        activeValue: 0,
+        inactiveValue: 1,
+        activeText: '启用',
+        inactiveText: '禁用',
       },
-      rules: z.string().min(1, { message: '请输入用户手机号' }),
     },
     {
       component: 'Input',
-      fieldName: 'usersemail',
-      label: '用户邮箱',
+      fieldName: 'details',
+      label: '描述',
       componentProps: {
-        placeholder: '请输入用户邮箱',
-        allowClear: true,
+        type: 'textarea',
+        placeholder: '请输入角色描述',
+        rows: 4,
       },
-      rules: z.string().min(1, { message: '请输入用户邮箱' }),
     },
     {
       component: 'Input',
-      fieldName: 'usersaddress',
-      label: '用户地址',
+      fieldName: 'popedom',
+      label: '权限设置',
       componentProps: {
-        placeholder: '请输入用户地址',
-        allowClear: true,
+        type: 'textarea',
+        placeholder: '请输入权限设置',
+        rows: 4,
       },
-      rules: z.string().min(1, { message: '请输入用户地址' }),
-    },
-    {
-      component: 'Input',
-      fieldName: 'userscontactphone',
-      label: '用户联系手机号',
-      componentProps: {
-        placeholder: '请输入用户联系手机号',
-        allowClear: true,
-      },
-      rules: z.string().min(1, { message: '请输入用户联系手机号' }),
-    },
-    {
-      component: 'Input',
-      fieldName: 'userscontactemail',
-      label: '用户联系邮箱',
-      componentProps: {
-        placeholder: '请输入用户联系邮箱',
-        allowClear: true,
-      },
-      rules: z.string().min(1, { message: '请输入用户联系邮箱' }),
-    },
-    {
-      component: 'Input',
-      fieldName: 'userscontactaddress',
-      label: '用户联系地址',
-      componentProps: {
-        placeholder: '请输入用户联系地址',
-        allowClear: true,
-      },
-      rules: z.string().min(1, { message: '请输入用户联系地址' }),
+      // @ts-ignore ifShow属性在运行时有效,但类型定义中缺失
+      ifShow: ({ formType }: { formType: string }) => formType !== 'create',
     },
   ],
 });
 
 const [Modal, modalApi] = useVbenModal({
+  class: 'w-8/12',
   onCancel() {
     modalApi.close();
   },
   async onConfirm() {
     // 校验输入的数据
+    const formValues = await baseFormApi.getValues();
     const validate = await baseFormApi.validate();
     if (!validate.valid) {
       return;
     }
 
-    modalApi.close();
-    // const values = await baseFormApi.getValues();
+    try {
+      const apiMap = {
+        create: () => addRoleApi(formValues as unknown as RoleGroupEntity),
+        edit: () =>
+          editRoleApi({
+            ...formValues,
+            'id.value': data.value.row.id,
+          } as unknown as RoleGroupEntity),
+      };
 
-    // console.log(Object.keys(values));
+      if (formType.value === 'detail') {
+        modalApi.close();
+        return;
+      }
+
+      await apiMap[formType.value]();
+      ElMessage.success('操作成功');
+      emit('finish');
+      modalApi.close();
+    } catch (error) {
+      console.error('操作失败', error);
+    }
   },
   async onOpenChange(isOpen) {
     if (isOpen) {
       data.value = modalApi.getData();
 
-      if (data.value.create) {
+      formType.value = data.value.formType;
+
+      baseFormApi.setState({
+        commonConfig: { disabled: formType.value === 'detail' },
+      });
+
+      if (data.value.formType === 'create') {
+        // 新增时设置默认值
+        baseFormApi.setFieldValue('available', 1);
+        baseFormApi.setFieldValue('group_sort', 0);
         return;
       }
 
       try {
-        // modalApi.setState({ loading: true });
-        // const detailData = await getCustomerDetailApi({
-        //   usersid: data.value.row.usersid,
-        // });
-        // baseFormApi.setValues(detailData);
-      } catch {
-        // console.log(error);
+        modalApi.setState({ loading: true });
+        const detailData = await getRoleDetailApi({
+          id: data.value.row.id,
+        });
+
+        baseFormApi.setValues(detailData);
+      } catch (error) {
+        console.error('获取角色详情失败', error);
       }
 
       modalApi.setState({ loading: false });

+ 89 - 40
apps/web-ele/src/views/system-manage/role-manage/index.vue

@@ -1,17 +1,23 @@
 <script lang="ts" setup>
 import type { VbenFormProps } from '@vben/common-ui';
+import type { RoleGroupEntity } from '@vben/types';
 
 import type { VxeGridProps } from '#/adapter/vxe-table';
 
+import { h } from 'vue';
+
 import { Page, useVbenModal } from '@vben/common-ui';
-import { MdiDetail, MdiEdit } from '@vben/icons';
+import { MdiDelete, MdiDetail, MdiEdit } from '@vben/icons';
+
+import { ElMessage, ElMessageBox, ElTag } from 'element-plus';
 
 import { useVbenVxeGrid } from '#/adapter/vxe-table';
-// import { getCustomerListApi } from '#/api/customer-manage';
+import { deleteRoleApi, getRoleListApi } from '#/api/role';
 import { $t } from '#/locales';
 
-import CustomerForm from './form.vue';
+import RoleForm from './form.vue';
 
+// 表单配置
 const formOptions: VbenFormProps = {
   // 默认展开
   collapsed: true,
@@ -22,30 +28,35 @@ const formOptions: VbenFormProps = {
   schema: [
     {
       component: 'Input',
-      fieldName: 'usersname',
-      label: '用户名称',
+      fieldName: 'title',
+      label: '角色名称',
       componentProps: {
         placeholder: $t('ui.placeholder.input'),
         allowClear: true,
       },
     },
     {
-      component: 'Input',
-      fieldName: 'usersphone',
-      label: '用户手机号',
+      component: 'Select',
+      fieldName: 'available',
+      label: '状态',
       componentProps: {
-        placeholder: $t('ui.placeholder.input'),
+        placeholder: $t('ui.placeholder.select'),
         allowClear: true,
+        options: [
+          { label: '启用', value: 0 },
+          { label: '禁用', value: 1 },
+        ],
       },
     },
   ],
+  wrapperClass: 'grid-cols-1 md:grid-cols-3 lg:grid-cols-5',
 };
 
+// 表格配置
 const gridOptions: VxeGridProps<any> = {
   toolbarConfig: {
     custom: true,
     export: true,
-    // import: true,
     refresh: true,
     zoom: true,
   },
@@ -62,62 +73,94 @@ const gridOptions: VxeGridProps<any> = {
       result: 'Data',
       total: 'Total',
     },
-    // ajax: {
-    //   query: async ({ page }, formValues) => {
-    //     return await getCustomerListApi({
-    //       pageindex: page.currentPage,
-    //       rows: page.pageSize,
-    //       ...formValues,
-    //     });
-    //   },
-    // },
+    ajax: {
+      query: async ({ page }, formValues) => {
+        return await getRoleListApi({
+          pageindex: page.currentPage,
+          rows: page.pageSize,
+          ...formValues,
+        });
+      },
+    },
   },
 
   columns: [
-    { title: '用户名称', field: 'usersname' },
-    { title: '用户性质', field: 'usersnature' },
-    { title: '用户证件号码', field: 'usersidcardnumber' },
-    { title: '用户开户银行名称', field: 'usersbankname' },
-    { title: '用户开户银行账号', field: 'usersbanknumber' },
-    { title: '用户手机号', field: 'usersphone' },
-    { title: '用户邮箱', field: 'usersemail' },
-    { title: '用户地址', field: 'usersaddress' },
-    { title: '用户联系手机号', field: 'userscontactphone' },
-    { title: '用户联系邮箱', field: 'userscontactemail' },
-    { title: '用户联系地址', field: 'userscontactaddress' },
+    // { title: '角色ID', field: 'id', width: 80 },
+    { title: '角色名称', field: 'title', minWidth: 120 },
+    // { title: '排序', field: 'group_sort', width: 80 },
+    {
+      title: '状态',
+      field: 'available',
+      width: 100,
+      slots: {
+        default: ({ row }) => {
+          return h(
+            ElTag,
+            {
+              type: row.available === 0 ? 'success' : 'info',
+            },
+            {
+              default: () => (row.available === 0 ? '启用' : '禁用'),
+            },
+          );
+        },
+      },
+    },
+    { title: '描述', field: 'details', minWidth: 150 },
+    { title: '创建时间', field: 'group_createdate', width: 160 },
+    // { title: '更新时间', field: 'group_update', width: 160 },
     {
       title: '操作',
       field: 'action',
       fixed: 'right',
       slots: { default: 'action' },
-      width: 140,
+      width: 150,
     },
   ],
 };
 
-const [Grid] = useVbenVxeGrid({ gridOptions, formOptions });
+const [Grid, gridApi] = useVbenVxeGrid({ gridOptions, formOptions });
 
 const [Modal, modalApi] = useVbenModal({
   fullscreenButton: false,
   closeOnClickModal: false,
   closeOnPressEscape: false,
-  connectedComponent: CustomerForm,
+  connectedComponent: RoleForm,
 });
 
 /* 创建 */
 function handleCreate() {
-  modalApi.setData({ create: true }).open();
+  modalApi.setData({ formType: 'create' }).open();
 }
 
 /* 编辑 */
-function handleEdit(row: any) {
-  modalApi.setData({ row }).open();
+function handleEdit(row: RoleGroupEntity) {
+  modalApi.setData({ formType: 'edit', row }).open();
 }
 
 /* 详情 */
-function handleDetail(row: any) {
-  modalApi.setData({ row }).open();
-  // router.push(`/system/users/detail/${row.userName}`);
+function handleDetail(row: RoleGroupEntity) {
+  modalApi.setData({ formType: 'detail', row }).open();
+}
+
+/* 删除 */
+async function handleDelete(row: RoleGroupEntity) {
+  try {
+    await ElMessageBox.confirm('确认要删除该角色吗?', '提示', {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+      type: 'warning',
+    });
+    await deleteRoleApi({ 'id.value': row.id });
+    ElMessage.success('删除成功');
+    gridApi.reload();
+  } catch (error) {
+    console.error(error);
+  }
+}
+
+function handleFinish() {
+  gridApi.reload();
 }
 </script>
 
@@ -140,8 +183,14 @@ function handleDetail(row: any) {
           :icon="MdiEdit"
           class="!p-2"
         />
+        <el-button
+          round
+          @click="() => handleDelete(row)"
+          :icon="MdiDelete"
+          class="!p-2"
+        />
       </template>
     </Grid>
-    <Modal />
+    <Modal @finish="handleFinish" />
   </Page>
 </template>

+ 131 - 112
apps/web-ele/src/views/system-manage/user-manage/form.vue

@@ -1,180 +1,199 @@
-<script lang="ts" setup>
-import { computed, ref } from 'vue';
+<script setup lang="ts">
+import type { AccountEntity, WorkerEntity } from '@vben/types';
+
+import { computed, onMounted, ref } from 'vue';
 
 import { useVbenModal } from '@vben/common-ui';
 
+import { ElMessage } from 'element-plus';
+
 import { useVbenForm, z } from '#/adapter/form';
-// import { getCustomerDetailApi } from '#/api/customer-manage';
+import {
+  addAccountApi,
+  editAccountApi,
+  getAccountDetailApi,
+} from '#/api/account';
+import { getWorkerListApi } from '#/api/worker';
 
+const emit = defineEmits(['finish']);
 const data = ref();
+const formType = ref<'create' | 'detail' | 'edit'>('create');
+const workerOptions = ref<{ label: string; value: string }[]>([]);
+
+// 获取职员列表
+async function fetchWorkerOptions() {
+  try {
+    const res = await getWorkerListApi({
+      pageindex: 1,
+      rows: 1000,
+    });
+
+    if (res && res.Data) {
+      workerOptions.value = res.Data.map((item: WorkerEntity) => ({
+        label: `${item.worker_xm}(${item.worker_gh})`,
+        value: item.worker_id,
+      }));
+    }
+  } catch (error) {
+    console.error('获取职员列表失败', error);
+  }
+}
+
+// 初始化时获取职员列表
+onMounted(() => {
+  fetchWorkerOptions();
+});
+
+const titleMap = {
+  create: '新增账号',
+  detail: '账号详情',
+  edit: '编辑账号',
+} as const;
 
-const getTitle = computed(() => (data.value?.create ? '新增客户' : '编辑客户'));
+const getTitle = computed(() => titleMap[formType.value]);
 
 const [BaseForm, baseFormApi] = useVbenForm({
   showDefaultActions: false,
   // 所有表单项共用,可单独在表单内覆盖
   commonConfig: {
-    labelWidth: 120,
+    labelWidth: 130,
     // 所有表单项
     componentProps: {
       class: 'w-full',
     },
   },
+  wrapperClass: 'grid-cols-1 lg:grid-cols-2',
   schema: [
-    // { title: '用户名称', field: 'usersname' },
-    // { title: '用户性质', field: 'usersnature' },
-    // { title: '用户证件号码', field: 'usersidcardnumber' },
-    // { title: '用户开户银行名称', field: 'usersbankname' },
-    // { title: '用户开户银行账号', field: 'usersbanknumber' },
-    // { title: '用户手机号', field: 'usersphone' },
-    // { title: '用户邮箱', field: 'usersemail' },
-    // { title: '用户地址', field: 'usersaddress' },
-    // { title: '用户联系手机号', field: 'userscontactphone' },
-    // { title: '用户联系邮箱', field: 'userscontactemail' },
-    // { title: '用户联系地址', field: 'userscontactaddress' },
-    {
-      component: 'Input',
-      fieldName: 'usersname',
-      label: '用户名称',
-      componentProps: {
-        placeholder: '请输入用户名称',
-        allowClear: true,
-      },
-      rules: z.string().min(1, { message: '请输入用户名称' }),
-    },
-    {
-      component: 'Input',
-      fieldName: 'usersnature',
-      label: '用户性质',
-      componentProps: {
-        placeholder: '请输入用户性质',
-        allowClear: true,
-      },
-      rules: z.number().min(1, { message: '请输入用户性质' }),
-    },
     {
       component: 'Input',
-      fieldName: 'usersidcardnumber',
-      label: '用户证件号码',
+      fieldName: 'accountname',
+      label: '账号',
+      rules: z.string().min(1, '请输入账号'),
       componentProps: {
-        placeholder: '请输入用户证件号码',
-        allowClear: true,
+        placeholder: '请输入账号',
       },
-      rules: z.string().min(1, { message: '请输入用户证件号码' }),
     },
+    // {
+    //   component: 'Input',
+    //   fieldName: 'accountpwd',
+    //   label: '密码',
+    //   rules: z.string().min(1, '请输入密码'),
+    //   componentProps: {
+    //     type: 'password',
+    //     placeholder: '请输入密码',
+    //     showPassword: true,
+    //   },
+    // },
     {
-      component: 'Input',
-      fieldName: 'usersbankname',
-      label: '用户开户银行名称',
+      component: 'Switch',
+      fieldName: 'accountstatus',
+      label: '账号状态',
+      defaultValue: 1,
       componentProps: {
-        placeholder: '请输入用户开户银行名称',
-        allowClear: true,
+        activeValue: 1,
+        inactiveValue: 0,
+        activeText: '可用',
+        inactiveText: '不可用',
       },
-      rules: z.string().min(1, { message: '请输入用户开户银行名称' }),
     },
     {
       component: 'Input',
-      fieldName: 'usersbanknumber',
-      label: '用户开户银行账号',
+      fieldName: 'accountgrouplist',
+      label: '角色组',
+      rules: z.string().min(1, '请输入角色组'),
       componentProps: {
-        placeholder: '请输入用户开户银行账号',
-        allowClear: true,
+        placeholder: '请输入角色组',
       },
-      rules: z.string().min(1, { message: '请输入用户开户银行账号' }),
     },
+    // {
+    //   component: 'Input',
+    //   fieldName: 'accountpopedom',
+    //   label: '单一权限',
+    //   componentProps: {
+    //     placeholder: '请输入单一权限',
+    //   },
+    // },
     {
-      component: 'Input',
-      fieldName: 'usersphone',
-      label: '用户手机号',
+      component: 'Select',
+      fieldName: 'accountworkerid',
+      label: '关联职员',
+      rules: z.string().min(1, '请选择关联职员'),
       componentProps: {
-        placeholder: '请输入用户手机号',
-        allowClear: true,
+        placeholder: '请选择关联职员',
+        options: workerOptions,
+        filterable: true,
+        clearable: true,
       },
-      rules: z.string().min(1, { message: '请输入用户手机号' }),
     },
     {
       component: 'Input',
-      fieldName: 'usersemail',
-      label: '用户邮箱',
+      fieldName: 'accountbz',
+      label: '备注',
       componentProps: {
-        placeholder: '请输入用户邮箱',
-        allowClear: true,
+        type: 'textarea',
+        placeholder: '请输入备注',
       },
-      rules: z.string().min(1, { message: '请输入用户邮箱' }),
-    },
-    {
-      component: 'Input',
-      fieldName: 'usersaddress',
-      label: '用户地址',
-      componentProps: {
-        placeholder: '请输入用户地址',
-        allowClear: true,
-      },
-      rules: z.string().min(1, { message: '请输入用户地址' }),
-    },
-    {
-      component: 'Input',
-      fieldName: 'userscontactphone',
-      label: '用户联系手机号',
-      componentProps: {
-        placeholder: '请输入用户联系手机号',
-        allowClear: true,
-      },
-      rules: z.string().min(1, { message: '请输入用户联系手机号' }),
-    },
-    {
-      component: 'Input',
-      fieldName: 'userscontactemail',
-      label: '用户联系邮箱',
-      componentProps: {
-        placeholder: '请输入用户联系邮箱',
-        allowClear: true,
-      },
-      rules: z.string().min(1, { message: '请输入用户联系邮箱' }),
-    },
-    {
-      component: 'Input',
-      fieldName: 'userscontactaddress',
-      label: '用户联系地址',
-      componentProps: {
-        placeholder: '请输入用户联系地址',
-        allowClear: true,
-      },
-      rules: z.string().min(1, { message: '请输入用户联系地址' }),
     },
   ],
 });
 
 const [Modal, modalApi] = useVbenModal({
+  class: 'w-7/12',
   onCancel() {
     modalApi.close();
   },
   async onConfirm() {
     // 校验输入的数据
+    const formValues = await baseFormApi.getValues();
     const validate = await baseFormApi.validate();
     if (!validate.valid) {
       return;
     }
 
-    modalApi.close();
-    // const values = await baseFormApi.getValues();
+    try {
+      const apiMap = {
+        create: () => addAccountApi(formValues as unknown as AccountEntity),
+        edit: () =>
+          editAccountApi({
+            ...formValues,
+            'accountid.value': data.value.row.accountid,
+          } as unknown as AccountEntity),
+      };
 
-    // console.log(Object.keys(values));
+      if (formType.value === 'detail') {
+        modalApi.close();
+        return;
+      }
+
+      await apiMap[formType.value]();
+      ElMessage.success('操作成功');
+      emit('finish');
+      modalApi.close();
+    } catch {}
   },
   async onOpenChange(isOpen) {
     if (isOpen) {
       data.value = modalApi.getData();
 
-      if (data.value.create) {
+      formType.value = data.value.formType;
+
+      baseFormApi.setState({
+        commonConfig: { disabled: formType.value === 'detail' },
+      });
+
+      if (data.value.formType === 'create') {
+        // 新增时设置默认值
+        baseFormApi.setFieldValue('accountstatus', 1);
         return;
       }
 
       try {
-        // modalApi.setState({ loading: true });
-        // const detailData = await getCustomerDetailApi({
-        //   usersid: data.value.row.usersid,
-        // });
-        // baseFormApi.setValues(detailData);
+        modalApi.setState({ loading: true });
+        const detailData = await getAccountDetailApi({
+          accountid: data.value.row.accountid,
+        });
+
+        baseFormApi.setValues(detailData);
       } catch {
         // console.log(error);
       }

+ 89 - 39
apps/web-ele/src/views/system-manage/user-manage/index.vue

@@ -3,14 +3,18 @@ import type { VbenFormProps } from '@vben/common-ui';
 
 import type { VxeGridProps } from '#/adapter/vxe-table';
 
+import { h } from 'vue';
+
 import { Page, useVbenModal } from '@vben/common-ui';
-import { MdiDetail, MdiEdit } from '@vben/icons';
+import { MdiDelete, MdiDetail, MdiEdit } from '@vben/icons';
+
+import { ElMessage, ElMessageBox, ElTag } from 'element-plus';
 
 import { useVbenVxeGrid } from '#/adapter/vxe-table';
-// import { getCustomerListApi } from '#/api/customer-manage';
+import { deleteAccountApi, getAccountListApi } from '#/api/account';
 import { $t } from '#/locales';
 
-import CustomerForm from './form.vue';
+import AccountForm from './form.vue';
 
 const formOptions: VbenFormProps = {
   // 默认展开
@@ -22,30 +26,34 @@ const formOptions: VbenFormProps = {
   schema: [
     {
       component: 'Input',
-      fieldName: 'usersname',
-      label: '用户名称',
+      fieldName: 'accountname',
+      label: '账号',
       componentProps: {
         placeholder: $t('ui.placeholder.input'),
         allowClear: true,
       },
     },
     {
-      component: 'Input',
-      fieldName: 'usersphone',
-      label: '用户手机号',
+      component: 'Select',
+      fieldName: 'accountstatus',
+      label: '账号状态',
       componentProps: {
-        placeholder: $t('ui.placeholder.input'),
+        placeholder: $t('ui.placeholder.select'),
         allowClear: true,
+        options: [
+          { label: '可用', value: 1 },
+          { label: '不可用', value: 0 },
+        ],
       },
     },
   ],
+  wrapperClass: 'grid-cols-1 md:grid-cols-3 lg:grid-cols-5',
 };
 
 const gridOptions: VxeGridProps<any> = {
   toolbarConfig: {
     custom: true,
     export: true,
-    // import: true,
     refresh: true,
     zoom: true,
   },
@@ -62,68 +70,104 @@ const gridOptions: VxeGridProps<any> = {
       result: 'Data',
       total: 'Total',
     },
-    // ajax: {
-    //   query: async ({ page }, formValues) => {
-    //     return await getCustomerListApi({
-    //       pageindex: page.currentPage,
-    //       rows: page.pageSize,
-    //       ...formValues,
-    //     });
-    //   },
-    // },
+    ajax: {
+      query: async ({ page }, formValues) => {
+        return await getAccountListApi({
+          pageindex: page.currentPage,
+          rows: page.pageSize,
+          ...formValues,
+        });
+      },
+    },
   },
 
   columns: [
-    { title: '用户名称', field: 'usersname' },
-    { title: '用户性质', field: 'usersnature' },
-    { title: '用户证件号码', field: 'usersidcardnumber' },
-    { title: '用户开户银行名称', field: 'usersbankname' },
-    { title: '用户开户银行账号', field: 'usersbanknumber' },
-    { title: '用户手机号', field: 'usersphone' },
-    { title: '用户邮箱', field: 'usersemail' },
-    { title: '用户地址', field: 'usersaddress' },
-    { title: '用户联系手机号', field: 'userscontactphone' },
-    { title: '用户联系邮箱', field: 'userscontactemail' },
-    { title: '用户联系地址', field: 'userscontactaddress' },
+    { title: '账号', field: 'accountname' },
+    {
+      title: '账号状态',
+      field: 'accountstatus',
+      slots: {
+        default: ({ row }) => {
+          const status = row.accountstatus;
+          return h(
+            ElTag,
+            {
+              type: status === 1 ? 'success' : 'danger',
+              effect: 'dark',
+              size: 'small',
+              round: true,
+            },
+            () => (status === 1 ? '可用' : '不可用'),
+          );
+        },
+      },
+    },
+    { title: '备注', field: 'accountbz' },
+    { title: '角色组', field: 'accountgrouplist' },
+    { title: '创建人', field: 'accountcreateuser' },
+    { title: '开通时间', field: 'accountcreatedate' },
+    // { title: '到期时间', field: 'accountenddate' },
+    // { title: '更新时间', field: 'accountupdate' },
+    // { title: '更新人', field: 'accountupuser' },
+    { title: '关联职员id', field: 'accountworkerid' },
     {
       title: '操作',
       field: 'action',
       fixed: 'right',
       slots: { default: 'action' },
-      width: 140,
+      width: 150,
     },
   ],
 };
 
-const [Grid] = useVbenVxeGrid({ gridOptions, formOptions });
+const [Grid, gridApi] = useVbenVxeGrid({ gridOptions, formOptions });
 
 const [Modal, modalApi] = useVbenModal({
   fullscreenButton: false,
   closeOnClickModal: false,
   closeOnPressEscape: false,
-  connectedComponent: CustomerForm,
+  connectedComponent: AccountForm,
 });
 
 /* 创建 */
 function handleCreate() {
-  modalApi.setData({ create: true }).open();
+  modalApi.setData({ formType: 'create' }).open();
 }
 
 /* 编辑 */
 function handleEdit(row: any) {
-  modalApi.setData({ row }).open();
+  modalApi.setData({ formType: 'edit', row }).open();
 }
 
 /* 详情 */
 function handleDetail(row: any) {
-  modalApi.setData({ row }).open();
-  // router.push(`/system/users/detail/${row.userName}`);
+  modalApi.setData({ formType: 'detail', row }).open();
+}
+
+/* 删除 */
+async function handleDelete(row: any) {
+  try {
+    await ElMessageBox.confirm('确认要删除该账号吗?', '提示', {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+      type: 'warning',
+    });
+    await deleteAccountApi({ 'accountid.value': row.accountid });
+    ElMessage.success('删除成功');
+    gridApi.reload();
+  } catch (error) {
+    console.error(error);
+  }
+}
+
+function handleFinish() {
+  gridApi.reload();
 }
 </script>
 
 <template>
   <Page auto-content-height>
-    <Grid table-title="用户列表">
+    <Grid table-title="账号列表">
       <template #toolbar-tools>
         <el-button type="primary" @click="handleCreate"> 新增 </el-button>
       </template>
@@ -140,8 +184,14 @@ function handleDetail(row: any) {
           :icon="MdiEdit"
           class="!p-2"
         />
+        <el-button
+          round
+          @click="() => handleDelete(row)"
+          :icon="MdiDelete"
+          class="!p-2"
+        />
       </template>
     </Grid>
-    <Modal />
+    <Modal @finish="handleFinish" />
   </Page>
 </template>

+ 37 - 4
apps/web-ele/src/views/system-manage/worker-manage/form.vue

@@ -1,18 +1,45 @@
 <script lang="ts" setup>
-import type { WorkerEntity } from '@vben/types';
+import type { CustomerEntity, WorkerEntity } from '@vben/types';
 
-import { computed, ref } from 'vue';
+import { computed, onMounted, ref } from 'vue';
 
 import { useVbenModal } from '@vben/common-ui';
 
 import { ElMessage } from 'element-plus';
 
 import { useVbenForm, z } from '#/adapter/form';
+import { getCustomerListApi } from '#/api/user';
 import { addWorkerApi, editWorkerApi, getWorkerDetailApi } from '#/api/worker';
 
 const emit = defineEmits(['finish']);
 const data = ref();
 const formType = ref<'create' | 'detail' | 'edit'>('create');
+const channelOptions = ref<{ label: string; value: string }[]>([]);
+
+// 获取渠道列表
+async function fetchChannelOptions() {
+  try {
+    const res = await getCustomerListApi({
+      pageindex: 1,
+      rows: 1000,
+      'usersnature.value': '渠道', // 只获取用户性质为"渠道"的数据
+    });
+
+    if (res && res.Data) {
+      channelOptions.value = res.Data.map((item: CustomerEntity) => ({
+        label: item.usersname,
+        value: item.usersid,
+      }));
+    }
+  } catch (error) {
+    console.error('获取渠道列表失败', error);
+  }
+}
+
+// 初始化时获取渠道列表
+onMounted(() => {
+  fetchChannelOptions();
+});
 
 const titleMap = {
   create: '新增职员',
@@ -131,9 +158,15 @@ const [BaseForm, baseFormApi] = useVbenForm({
       label: '紧急联系电话',
     },
     {
-      component: 'Input',
+      component: 'Select',
       fieldName: 'worker_userid',
-      label: '关联渠道id',
+      label: '关联渠道',
+      componentProps: {
+        placeholder: '请选择关联渠道',
+        options: channelOptions,
+        filterable: true,
+        clearable: true,
+      },
     },
   ],
 });

+ 1 - 0
packages/icons/src/iconify/index.ts

@@ -14,6 +14,7 @@ export const MdiQqchat = createIconifyIcon('mdi:qqchat');
 
 export const MdiOnepassword = createIconifyIcon('mdi:onepassword');
 
+// add
 export const MdiEdit = createIconifyIcon('mdi:pencil');
 
 export const MdiDelete = createIconifyIcon('mdi:delete');

+ 48 - 0
packages/types/src/account.ts

@@ -0,0 +1,48 @@
+/** 账号 */
+// CREATE TABLE `account` (
+//   `accountid` varchar(50) NOT NULL COMMENT '账号id',
+//   `accountname` varchar(50) NOT NULL COMMENT '账号(禁止编辑)',
+//   `accountpwd` varchar(50) NOT NULL COMMENT '密码',
+//   `accountstatus` int(11) NOT NULL COMMENT '账号是否可用',
+//   `accountbz` varchar(50) DEFAULT NULL COMMENT '备注',
+//   `accountgrouplist` varchar(50) DEFAULT NULL COMMENT '角色组',
+//   `accountpopedom` text COMMENT '单一权限',
+//   `accountcreateuser` varchar(50) DEFAULT NULL COMMENT '账号创建人',
+//   `accountcreatedate` datetime DEFAULT NULL COMMENT '账号开通时间',
+//   `accountenddate` datetime DEFAULT NULL COMMENT '账号到期时间',
+//   `accountupdate` datetime DEFAULT NULL COMMENT '账号更新时间',
+//   `accountupuser` varchar(50) DEFAULT NULL COMMENT '账号更新人',
+//   `accountworkerid` varchar(50) DEFAULT NULL COMMENT '关联职员id',
+//   PRIMARY KEY (`accountid`)
+// ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='账号';
+
+interface AccountEntity {
+  /** 账号id */
+  accountid: string;
+  /** 账号(禁止编辑) */
+  accountname: string;
+  /** 密码 */
+  accountpwd: string;
+  /** 账号是否可用 */
+  accountstatus: number;
+  /** 备注 */
+  accountbz: string;
+  /** 角色组 */
+  accountgrouplist: string;
+  /** 单一权限 */
+  accountpopedom: string;
+  /** 账号创建人 */
+  accountcreateuser: string;
+  /** 账号开通时间 */
+  accountcreatedate: string;
+  /** 账号到期时间 */
+  accountenddate: string;
+  /** 账号更新时间 */
+  accountupdate: string;
+  /** 账号更新人 */
+  accountupuser: string;
+  /** 关联职员id */
+  accountworkerid: string;
+}
+
+export type { AccountEntity };

+ 54 - 0
packages/types/src/dict.ts

@@ -0,0 +1,54 @@
+/** 系统配置表 */
+// CREATE TABLE `configuration` (
+//   `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '配置id(禁止插入)',
+//   `baseid` int(11) NOT NULL COMMENT '上级',
+//   `groupname` varchar(255) DEFAULT NULL COMMENT '组名称',
+//   `title` varchar(255) NOT NULL COMMENT '配置名称',
+//   `substance` longtext NOT NULL COMMENT '配置值',
+//   `available` tinyint(2) NOT NULL COMMENT '0不可用,1可用',
+//   `describes` varchar(255) DEFAULT NULL COMMENT '描述',
+//   `ispublic` tinyint(2) NOT NULL COMMENT '是否前端可用',
+//   `option1` varchar(255) DEFAULT NULL COMMENT '预留参数1',
+//   `option2` varchar(255) DEFAULT NULL COMMENT '预留参数2',
+//   `option3` varchar(255) DEFAULT NULL COMMENT '预留参数3',
+//   `option4` varchar(255) DEFAULT NULL COMMENT '预留参数4',
+//   `option5` varchar(255) DEFAULT NULL COMMENT '预留参数5',
+//   `option6` varchar(255) DEFAULT NULL COMMENT '预留参数6',
+//   `ranknum` int(11) DEFAULT NULL COMMENT '排序值',
+//   PRIMARY KEY (`id`)
+// ) ENGINE=InnoDB AUTO_INCREMENT=120 DEFAULT CHARSET=utf8mb4 COMMENT='系统配置表';
+
+interface DictEntity {
+  /** 配置id(禁止插入) */
+  id: number;
+  /** 上级 */
+  baseid: number;
+  /** 组名称 */
+  groupname: string;
+  /** 配置名称 */
+  title: string;
+  /** 配置值 */
+  substance: string;
+  /** 0不可用,1可用 */
+  available: number;
+  /** 描述 */
+  describes: string;
+  /** 是否前端可用 */
+  ispublic: number;
+  /** 预留参数1 */
+  option1: string;
+  /** 预留参数2 */
+  option2: string;
+  /** 预留参数3 */
+  option3: string;
+  /** 预留参数4 */
+  option4: string;
+  /** 预留参数5 */
+  option5: string;
+  /** 预留参数6 */
+  option6: string;
+  /** 排序值 */
+  ranknum: number;
+}
+
+export type { DictEntity };

+ 5 - 0
packages/types/src/index.ts

@@ -1,8 +1,13 @@
+export type * from './account';
 export type * from './base';
 export type * from './coupon1';
 export type * from './coupon2';
+export type * from './dict';
+export type * from './log';
+export type * from './menu';
 export type * from './orders';
 export type * from './product';
+export type * from './role';
 export type * from './scqy';
 export type * from './subsidyapplications';
 export type * from './user';

+ 42 - 0
packages/types/src/log.ts

@@ -0,0 +1,42 @@
+/** 接口日志 */
+// CREATE TABLE `managelog` (
+//   `id` int(20) NOT NULL AUTO_INCREMENT COMMENT ' 流水号(降序)(禁止插入)(列表显示)',
+//   `method` varchar(255) DEFAULT NULL COMMENT '方法名(不可编辑)(查询条件)(列表显示)',
+//   `url` longtext COMMENT '地址(不可编辑)',
+//   `mode` varchar(255) DEFAULT NULL COMMENT '模式(不可编辑)',
+//   `terminal` varchar(255) DEFAULT NULL COMMENT '终端(不可编辑)(查询条件)(列表显示)',
+//   `sendcontent` longtext COMMENT '接收内容(不可编辑)(列表显示)',
+//   `getcontent` longtext COMMENT '返回内容(不可编辑)',
+//   `ip` varchar(255) DEFAULT NULL COMMENT 'ip地址(不可编辑)(列表显示)',
+//   `extime` double DEFAULT NULL COMMENT '执行时间毫秒(不可编辑)',
+//   `account` varchar(255) DEFAULT NULL COMMENT '帐号(不可编辑)(查询条件)(列表显示)',
+//   `createtime` datetime DEFAULT NULL COMMENT '生成时间(不可编辑)(查询条件)(列表显示)',
+//   PRIMARY KEY (`id`)
+// ) ENGINE=InnoDB AUTO_INCREMENT=5808 DEFAULT CHARSET=utf8mb4 COMMENT='接口日志';
+
+interface LogEntity {
+  /** 流水号(降序)(禁止插入)(列表显示) */
+  id: number;
+  /** 方法名(不可编辑)(查询条件)(列表显示) */
+  method: string;
+  /** 地址(不可编辑) */
+  url: string;
+  /** 模式(不可编辑) */
+  mode: string;
+  /** 终端(不可编辑)(查询条件)(列表显示) */
+  terminal: string;
+  /** 接收内容(不可编辑)(列表显示) */
+  sendcontent: string;
+  /** 返回内容(不可编辑) */
+  getcontent: string;
+  /** ip地址(不可编辑)(列表显示) */
+  ip: string;
+  /** 执行时间毫秒(不可编辑) */
+  extime: number;
+  /** 帐号(不可编辑)(查询条件)(列表显示) */
+  account: string;
+  /** 生成时间(不可编辑)(查询条件)(列表显示) */
+  createtime: string;
+}
+
+export type { LogEntity };

+ 90 - 0
packages/types/src/menu.ts

@@ -0,0 +1,90 @@
+/** 菜单 */
+// CREATE TABLE `menu` (
+//   `menu_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '菜单id(查询条件)(禁止插入)',
+//   `menu_sort` varchar(200) DEFAULT NULL COMMENT '菜单归属分类',
+//   `menu_name` varchar(50) DEFAULT NULL COMMENT '菜单名称',
+//   `menu_key` varchar(50) DEFAULT NULL COMMENT '菜单标识',
+//   `component` varchar(50) DEFAULT NULL COMMENT '菜单布局',
+//   `active_menu` varchar(50) DEFAULT NULL COMMENT '当前激活的菜单路由',
+//   `parent_id` int(11) DEFAULT NULL COMMENT '父级id(查询条件)',
+//   `target` int(11) DEFAULT NULL COMMENT '打开方式',
+//   `order_num` int(11) DEFAULT NULL COMMENT '显示顺序(升序)',
+//   `menu_type` int(11) DEFAULT NULL COMMENT '菜单类型',
+//   `visible` int(11) DEFAULT NULL COMMENT '菜单状态',
+//   `perms` varchar(100) DEFAULT NULL COMMENT '权限标识',
+//   `icon` varchar(100) DEFAULT NULL COMMENT '菜单图标',
+//   `path` varchar(255) DEFAULT NULL COMMENT '链接',
+//   `redirect` varchar(255) DEFAULT NULL COMMENT '重定向',
+//   `hiddewn_children` int(11) DEFAULT NULL COMMENT '强制菜单显示为item而不是subitem',
+//   `hidden_header` int(11) DEFAULT NULL COMMENT '特殊隐藏pageheader组件中的页面带的面包屑和页面标题栏',
+//   `create_by` varchar(32) DEFAULT NULL COMMENT '创建人(查询条件)(禁止编辑)',
+//   `create_time` datetime DEFAULT NULL COMMENT '创建时间(查询条件)(禁止编辑)',
+//   `update_by` varchar(32) DEFAULT NULL COMMENT '更新人(禁止添加)',
+//   `update_time` datetime DEFAULT NULL COMMENT '更新时间(禁止添加)',
+//   `menu_delcode` tinyint(2) NOT NULL COMMENT '删除标记(禁止插入)(禁止前端编辑)',
+//   `remark` text COMMENT '菜单备注',
+//   `no_cache` int(11) DEFAULT NULL COMMENT '是否缓存',
+//   `api_parameter` text COMMENT '权限参数限制',
+//   `api_url` varchar(255) DEFAULT NULL COMMENT '接口地址',
+//   `api_method` varchar(50) DEFAULT NULL COMMENT '接口请求类型',
+//   PRIMARY KEY (`menu_id`)
+// ) ENGINE=InnoDB AUTO_INCREMENT=68 DEFAULT CHARSET=utf8mb4 COMMENT='菜单';
+
+interface MenuEntity {
+  /** 菜单id(查询条件)(禁止插入) */
+  menu_id: number;
+  /** 菜单归属分类 */
+  menu_sort: string;
+  /** 菜单名称 */
+  menu_name: string;
+  /** 菜单标识 */
+  menu_key: string;
+  /** 菜单布局 */
+  component: string;
+  /** 当前激活的菜单路由 */
+  active_menu: string;
+  /** 父级id(查询条件) */
+  parent_id: number;
+  /** 打开方式 */
+  target: number;
+  /** 显示顺序(升序) */
+  order_num: number;
+  /** 菜单类型 */
+  menu_type: number;
+  /** 菜单状态 */
+  visible: number;
+  /** 权限标识 */
+  perms: string;
+  /** 菜单图标 */
+  icon: string;
+  /** 链接 */
+  path: string;
+  /** 重定向 */
+  redirect: string;
+  /** 强制菜单显示为item而不是subitem */
+  hiddewn_children: number;
+  /** 特殊隐藏pageheader组件中的页面带的面包屑和页面标题栏 */
+  hidden_header: number;
+  /** 创建人(查询条件)(禁止编辑) */
+  create_by: string;
+  /** 创建时间(查询条件)(禁止编辑) */
+  create_time: string;
+  /** 更新人(禁止添加) */
+  update_by: string;
+  /** 更新时间(禁止添加) */
+  update_time: string;
+  /** 删除标记(禁止插入)(禁止前端编辑) */
+  menu_delcode: number;
+  /** 菜单备注 */
+  remark: string;
+  /** 是否缓存 */
+  no_cache: number;
+  /** 权限参数限制 */
+  api_parameter: string;
+  /** 接口地址 */
+  api_url: string;
+  /** 接口请求类型 */
+  api_method: string;
+}
+
+export type { MenuEntity };

+ 45 - 0
packages/types/src/role.ts

@@ -0,0 +1,45 @@
+/** 角色组 */
+// CREATE TABLE `sysusergroup` (
+//   `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '管理员权限组id(禁止插入)',
+//   `title` varchar(255) DEFAULT NULL COMMENT '权限组名称',
+//   `group_sort` varchar(50) DEFAULT NULL COMMENT '权限组类型',
+//   `subjectid` varchar(50) DEFAULT NULL COMMENT '关联主体id',
+//   `details` varchar(255) DEFAULT NULL COMMENT '权限功能描述',
+//   `popedom` longtext COMMENT '权限内容',
+//   `available` tinyint(2) DEFAULT NULL COMMENT '可用状态',
+//   `group_createuser` varchar(32) DEFAULT NULL COMMENT '创建人',
+//   `group_createdate` datetime DEFAULT NULL COMMENT '创建时间',
+//   `group_update` datetime DEFAULT NULL COMMENT '更新时间',
+//   `group_updateuser` varchar(32) DEFAULT NULL COMMENT '更新人',
+//   `group_delcode` tinyint(2) NOT NULL COMMENT '删除标记',
+//   PRIMARY KEY (`id`)
+// ) ENGINE=InnoDB AUTO_INCREMENT=49 DEFAULT CHARSET=utf8mb4 COMMENT='角色组';
+
+interface RoleGroupEntity {
+  /** 管理员权限组id(禁止插入) */
+  id: number;
+  /** 权限组名称 */
+  title: string;
+  /** 权限组类型 */
+  group_sort: string;
+  /** 关联主体id */
+  subjectid: string;
+  /** 权限功能描述 */
+  details: string;
+  /** 权限内容 */
+  popedom: string;
+  /** 可用状态 */
+  available: number;
+  /** 创建人 */
+  group_createuser: string;
+  /** 创建时间 */
+  group_createdate: string;
+  /** 更新时间 */
+  group_update: string;
+  /** 更新人 */
+  group_updateuser: string;
+  /** 删除标记 */
+  group_delcode: number;
+}
+
+export type { RoleGroupEntity };