Browse Source

保存和新增

master
zhanglei 1 week ago
parent
commit
e020e70d10
  1. 2
      config.py
  2. 4
      config.yml
  3. 35
      frontend_vue.py
  4. 16
      templates/vue/api.ts.j2
  5. 81
      templates/vue/index.vue.j2
  6. 4
      templates/vue/router.ts.j2
  7. 4
      utils.py
  8. 2
      vue-vben-admin/apps/web-antd/.env.development
  9. 2
      vue-vben-admin/apps/web-antd/.env.production
  10. 18
      vue-vben-admin/apps/web-antd/src/api/user.ts
  11. 10
      vue-vben-admin/apps/web-antd/src/router/routes/modules/user.ts
  12. 241
      vue-vben-admin/apps/web-antd/src/views/user/data.ts
  13. 258
      vue-vben-admin/apps/web-antd/src/views/user/form.ts
  14. 332
      vue-vben-admin/apps/web-antd/src/views/user/index.vue

2
config.py

@ -24,7 +24,7 @@ DB = {
"host": "192.168.1.80",
"user": "root",
"password": "Khq#P9hZ4L@EwCZw",
"database": "health_ai_b",
"database": "health_ai",
"port": 3728
}

4
config.yml

@ -87,10 +87,12 @@ application:
# ===============================
# vue 应用级配置
# editFields 不编辑,不展示
# ===============================
frontend:
root: F:/zxmgee/codegen/vue-vben-admin
api: apps/web-antd/src/api
views: apps/web-antd/src/views
router: apps/web-antd/src/router/routes/modules
mock: apps/web-antd/mock
mock: apps/web-antd/mock
editFields: "user_id,created_at,created_by,updated_at,updated_by,deleted_flag"

35
frontend_vue.py

@ -1,6 +1,6 @@
import os
from jinja2 import Environment, FileSystemLoader
from db import get_columns
from db import get_table, get_columns
from utils import *
import yaml
@ -21,21 +21,17 @@ def build_fields(table):
cols = get_columns(table)
fields = []
for c in cols:
field = {}
field["name"] = to_camel(c["column_name"])
field["comment"] = c["column_comment"]
field["type"] = c["data_type"]
# ⭐ 在这里调用组件解析
field["component"] = parse_component(c)
fields.append(field)
return fields
def generate(table):
with open("./config.yml", "r", encoding="utf-8") as f:
@ -46,18 +42,20 @@ def generate(table):
VIEW_DIR = cfg["frontend"]["root"]+"/"+cfg["frontend"]["views"]
ROUTER_DIR = cfg["frontend"]["root"]+"/"+cfg["frontend"]["router"]
MOCK_DIR = cfg["frontend"]["root"]+"/"+cfg["frontend"]["mock"]
EDIT_FIELDS = cfg["frontend"]["editFields"]
fields = get_columns(table)
table_info = get_table(table)
entity = table.replace("health_","")
ctx = {
"table":table,
"table_comment":table_info["table_comment"],
"old_table": to_kebab(table),
"entity":entity,
"editFields": to_class_join(EDIT_FIELDS),
"fields":build_fields(table)
}
print(ctx)
render(
"api.ts.j2",
f"{API_DIR}/{entity}.ts",
@ -96,6 +94,21 @@ def generate(table):
)
if __name__ == "__main__":
# ... existing code ...
generate("health_user")
if __name__ == "__main__":
import sys
# 从命令行参数获取表名
if len(sys.argv) > 1:
table_name = sys.argv[1]
print(f"=== 生成前端代码1:{table_name} ===")
generate(table_name)
else:
# 如果没有提供参数,提示用户输入
table_name = input("请输入表名 (例如 health_user): ").strip()
if table_name:
print(f"=== 生成前端代码2:{table_name} ===")
generate(table_name)
else:
print("❌ 未输入表名,退出程序")

16
templates/vue/api.ts.j2

@ -15,7 +15,8 @@ export namespace {{entity}}Api {
* 分页查询
*/
export function page(params: any) {
return requestClient.post(applicationConfig.javaURL+'/{{old_table}}/page', params,{ headers: {'Content-Type': 'application/json', Token: 'ded93460-0cf5-45db-81ae-7608dbd3f51e', version: '1.0.1'}});
return requestClient.post(applicationConfig.javaURL+'/{{old_table}}/page', params,
{ headers: {'Content-Type': 'application/json', Token: 'ded93460-0cf5-45db-81ae-7608dbd3f51e', version: '1.0.1', familyId: 0}});
}
/**
@ -26,10 +27,19 @@ export namespace {{entity}}Api {
}
/**
* 新增 / 修改
* 新增
*/
export function add(data: any) {
return requestClient.post(applicationConfig.javaURL+'/{{old_table}}/add', data,
{ headers: {'Content-Type': 'application/json', Token: 'ded93460-0cf5-45db-81ae-7608dbd3f51e', version: '1.0.1', familyId: 0}});
}
/**
* 修改
*/
export function save(data: any) {
return requestClient.post(applicationConfig.javaURL+'/{{old_table}}', data);
return requestClient.post(applicationConfig.javaURL+'/{{old_table}}/modify', data,
{ headers: {'Content-Type': 'application/json', Token: 'ded93460-0cf5-45db-81ae-7608dbd3f51e', version: '1.0.1', familyId: 0}});
}
/**

81
templates/vue/index.vue.j2

@ -1,6 +1,6 @@
<script setup lang="ts">
/**
* 用户管理页面
* {{entity}}管理页面
*/
import {ref, reactive, onMounted, watch} from 'vue';
import {useVbenVxeGrid} from '#/adapter/vxe-table';
@ -23,7 +23,8 @@ const enumData = reactive({
list: [], // 存储接口返回的原始枚举数据
});
//todo 枚举数据在查询里面不展示的配置
const hiddenColumns = ref(['createdAt', 'updatedBy', 'updatedAt', 'userPassword', 'userId', 'userSys', 'deletedFlag', "userFace"])
const hiddenColumns = ref(['fun_code','graduallyIntervalTime','funMsgTitle','funImg','createdAt', 'updatedBy', 'updatedAt', 'userPassword', 'userId', 'userSys', 'deletedFlag', "userFace"])
const editFields = [{{editFields}}];
// ========== 初始化枚举数据和查询表单 ==========
async function initEnumData() {
@ -31,7 +32,7 @@ async function initEnumData() {
enumData.loading = true;
// 调用枚举列表接口
const res = await userApi.enumList({});
const res = await {{entity}}Api.enumList({});
const enums = res.result || res;
// 保存原始枚举数据
@ -143,7 +144,7 @@ const gridOptions = {
...queryValues,
})
const res = await userApi.page({
const res = await {{entity}}Api.page({
pageNum: page?.currentPage || 1,
pageSize: page?.pageSize || 10,
...queryValues, // 携带查询条件
@ -157,7 +158,7 @@ const gridOptions = {
}
} catch (error) {
console.error('查询用户列表失败:', error)
console.error('查询列表失败:', error)
throw error
}
}
@ -174,7 +175,8 @@ const gridOptions = {
}
const [Grid, gridApi] = useVbenVxeGrid({gridOptions})
// ========== 过滤后的编辑表单 Schema ==========
const editFormSchema = formSchema.filter(item => !editFields.includes(item.fieldName));
// ========== 弹窗配置 ==========
const [Modal, modalApi] = useVbenModal({
centered: true,
@ -197,9 +199,9 @@ const [Modal, modalApi] = useVbenModal({
};
if (isEdit.value && currentRow.value?.id) {
await userApi.save({...submitValues, id: currentRow.value.id});
await {{entity}}Api.save({...submitValues, id: currentRow.value.id});
} else {
await userApi.save(submitValues);
await {{entity}}Api.add(submitValues);
}
modalApi.close();
@ -215,9 +217,26 @@ const [Modal, modalApi] = useVbenModal({
},
})
// ========== 动态计算编辑表单 Schema ==========
// 新增时:过滤掉 id 字段
// 编辑时:包含 id 字段
const getEditFormSchema = () => {
return formSchema.filter(item => {
// 不在 editFields 中的才显示
if (!editFields.includes(item.fieldName)) {
// 新增时排除 id 字段
if (!isEdit.value && item.fieldName === 'id') {
return false;
}
return true;
}
return false;
});
};
// ========== 表单配置 ==========
const [Form, formApi] = useVbenForm({
schema: formSchema,
schema: editFormSchema,
showDefaultActions: false,
wrapperClass: 'grid-cols-1 md:grid-cols-2',
commonConfig: {
@ -228,10 +247,16 @@ const [Form, formApi] = useVbenForm({
},
})
// ========== 打开新增弹窗 ==========
function handleAdd() {
isEdit.value = false;
modalTitle.value = '新增用户';
modalTitle.value = '{{table_comment}}新增';
// 更新表单 schema (不包含 id)
formApi.setState({
schema: getEditFormSchema(),
});
formApi.resetForm();
modalApi.open();
}
@ -240,27 +265,19 @@ function handleAdd() {
function handleEdit(row: any) {
isEdit.value = true;
currentRow.value = row;
modalTitle.value = '编辑用户';
// 设置表单值,过滤掉不必要的字段,并处理日期格式
const formValues = {
id: row.id,
userName: row.userName,
userPhone: row.userPhone,
userRealName: row.userRealName,
userGender: row.userGender,
userPassword: row.userPassword,
userBirthday: row.userBirthday,
userFace: row.userFace,
userEmail: row.userEmail,
userAddress: row.userAddress,
userId: row.userId,
userSys: row.userSys,
userPhoneModel: row.userPhoneModel,
userStatus: row.userStatus,
userCid: row.userCid,
userIp: row.userIp,
};
modalTitle.value = '{{table_comment}}编辑';
// 更新表单 schema (包含 id)
formApi.setState({
schema: getEditFormSchema(),
});
// 设置表单值,只设置 editFields 中包含的字段
const formValues: any = {};
editFormSchema.forEach(item => {
const field = item.fieldName;
if (row[field] !== undefined && row[field] !== null) {
formValues[field] = row[field];
}
});
formApi.setValues(formValues);
modalApi.open();
@ -270,7 +287,7 @@ function handleEdit(row: any) {
function handleDelete(row: any) {
if (!row.id) return;
window.confirm(`确定要删除 "${row.userName}" 吗?`) &&
userApi.remove(row.id).then(() => {
{{entity}}Api.remove(row.id).then(() => {
gridApi.reload();
});
}

4
templates/vue/router.ts.j2

@ -8,7 +8,7 @@ const routes: RouteRecordRaw[] = [
{
path: '/{{entity}}',
name: '{{comment}}模块',
name: '{{table_comment}}模块',
meta: {
icon: 'ic:baseline-view-in-ar',
order: 1000,
@ -18,7 +18,7 @@ const routes: RouteRecordRaw[] = [
children: [
{
meta: {
title: "{{comment}}列表",
title: "{{table_comment}}列表",
},
name: '{{entity}}List',
path: '/{{entity}}',

4
utils.py

@ -16,6 +16,10 @@ def to_m_camel(name):
def to_class(name):
return "".join(p.capitalize() for p in name.split("_"))
def to_class_join(name):
parts = name.split(",")
return "'"+"','".join(to_camel(p) for p in parts)+"'"
def lower_first(s: str) -> str:
if not s:
return s

2
vue-vben-admin/apps/web-antd/.env.development

@ -6,7 +6,7 @@ VITE_BASE=/
# 接口地址
VITE_GLOB_API_URL=/api
# VITE_GLOB_API_URL=http://localhost:8083/api/models
VITE_GLOB_JAVA_API_URL=http://localhost:8083/api/models
VITE_GLOB_JAVA_API_URL=http://192.168.1.47:8083/api/models
# 是否开启 Nitro Mock服务,true 为开启,false 为关闭
VITE_NITRO_MOCK=true

2
vue-vben-admin/apps/web-antd/.env.production

@ -4,7 +4,7 @@ VITE_BASE=/
VITE_GLOB_API_URL=https://mock-napi.vben.pro/api
# VITE_GLOB_API_URL=http://localhost:8083/api/models
VITE_GLOB_JAVA_API_URL=http://localhost:8083/api/models
VITE_GLOB_JAVA_API_URL=http://192.168.1.47:8083/api/models
# 是否开启压缩,可以设置为 none, brotli, gzip
VITE_COMPRESS=none

18
vue-vben-admin/apps/web-antd/src/api/user.ts

@ -15,7 +15,8 @@ export namespace userApi {
*
*/
export function page(params: any) {
return requestClient.post(applicationConfig.javaURL+'/health-user/page', params,{ headers: {'Content-Type': 'application/json', Token: 'ded93460-0cf5-45db-81ae-7608dbd3f51e', version: '1.0.1'}});
return requestClient.post(applicationConfig.javaURL+'/health-user/page', params,
{ headers: {'Content-Type': 'application/json', Token: 'ded93460-0cf5-45db-81ae-7608dbd3f51e', version: '1.0.1', familyId: 0}});
}
/**
@ -39,12 +40,11 @@ export namespace userApi {
return requestClient.delete(applicationConfig.javaURL+'/health-user/' + id);
}
/**
*
*/
export function enumList(params: any) {
return requestClient.post(applicationConfig.javaURL+'/health-enums/optionList', params,{ headers: {'Content-Type': 'application/json', Token: 'ded93460-0cf5-45db-81ae-7608dbd3f51e', version: '1.0.1'}});
}
/**
*
*/
export function enumList(params: any) {
return requestClient.post(applicationConfig.javaURL+'/health-enums/optionList', params,{ headers: {'Content-Type': 'application/json', Token: 'ded93460-0cf5-45db-81ae-7608dbd3f51e', version: '1.0.1'}});
}
}
}

10
vue-vben-admin/apps/web-antd/src/router/routes/modules/user.ts

@ -2,13 +2,13 @@
*
*/
import type {RouteRecordRaw} from 'vue-router';
import type { RouteRecordRaw } from 'vue-router';
const routes: RouteRecordRaw[] = [
{
{
path: '/user',
name: '模块',
name: '用户基础表,用户个人信息模块',
meta: {
icon: 'ic:baseline-view-in-ar',
order: 1000,
@ -18,7 +18,7 @@ const routes: RouteRecordRaw[] = [
children: [
{
meta: {
title: "列表",
title: "用户基础表,用户个人信息列表",
},
name: 'userList',
path: '/user',
@ -28,4 +28,4 @@ const routes: RouteRecordRaw[] = [
}
];
export default routes;
export default routes;

241
vue-vben-admin/apps/web-antd/src/views/user/data.ts

@ -1,241 +0,0 @@
/**
*
*/
import type {VxeGridProps} from '#/adapter/vxe-table';
export const columns: VxeGridProps['columns'] = [
{
// 列标题
title: '主键ID',
// 对应字段
field: 'id',
// 宽度
width: 150,
},
{
// 列标题
title: '账号',
// 对应字段
field: 'userName',
// 宽度
width: 150
},
{
// 列标题
title: '手机号',
// 对应字段
field: 'userPhone',
// 宽度
width: 150
},
{
// 列标题
title: '姓名',
// 对应字段
field: 'userRealName',
// 宽度
width: 150
},
{
// 列标题
title: '性别:0默认保密,1男2女',
// 对应字段
field: 'userGender',
// 宽度
width: 150
},
{
// 列标题
title: '密码',
// 对应字段
field: 'userPassword',
// 宽度
width: 150
},
{
// 列标题
title: '生日',
// 对应字段
field: 'userBirthday',
// 宽度
width: 150
},
{
// 列标题
title: '头像',
// 对应字段
field: 'userFace',
// 宽度
width: 150
},
{
// 列标题
title: '邮箱',
// 对应字段
field: 'userEmail',
// 宽度
width: 150
},
{
// 列标题
title: '创建时间',
// 对应字段
field: 'createdAt',
// 宽度
width: 150
},
{
// 列标题
title: '更新时间',
// 对应字段
field: 'updatedAt',
// 宽度
width: 150
},
{
// 列标题
title: '创建人',
// 对应字段
field: 'createdBy',
// 宽度
width: 150
},
{
// 列标题
title: '更新人',
// 对应字段
field: 'updatedBy',
// 宽度
width: 150
},
{
// 列标题
title: '删除 0 默认 1删除',
// 对应字段
field: 'deletedFlag',
// 宽度
width: 150
},
{
// 列标题
title: '地址',
// 对应字段
field: 'userAddress',
// 宽度
width: 150
},
{
// 列标题
title: '用户ID冗余字段',
// 对应字段
field: 'userId',
// 宽度
width: 150
},
{
// 列标题
title: '系统型号',
// 对应字段
field: 'userSys',
// 宽度
width: 150
},
{
// 列标题
title: '手机型号',
// 对应字段
field: 'userPhoneModel',
// 宽度
width: 150
},
{
// 列标题
title: '用户状态默认启用0,注销1',
// 对应字段
field: 'userStatus',
// 宽度
width: 150
},
{
// 列标题
title: '手机唯一标识',
// 对应字段
field: 'userCid',
// 宽度
width: 150
},
{
// 列标题
title: '手机IP',
// 对应字段
field: 'userIp',
// 宽度
width: 150
},
];

258
vue-vben-admin/apps/web-antd/src/views/user/form.ts

@ -1,258 +0,0 @@
/**
* schema
* component parse_component()
*/
import type {VbenFormSchema} from '#/adapter/form';
export const formSchema: VbenFormSchema[] = [
{
// 字段名
fieldName: 'id',
// label
label: '主键ID',
// 自动组件
component: 'InputNumber'
},
{
// 字段名
fieldName: 'userName',
// label
label: '账号',
// 自动组件
component: 'Input'
},
{
// 字段名
fieldName: 'userPhone',
// label
label: '手机号',
// 自动组件
component: 'Input'
},
{
// 字段名
fieldName: 'userRealName',
// label
label: '姓名',
// 自动组件
component: 'Input'
},
{
// 字段名
fieldName: 'userGender',
// label
label: '性别:0默认保密,1男2女',
// 自动组件
component: 'InputNumber'
},
{
// 字段名
fieldName: 'userPassword',
// label
label: '密码',
// 自动组件
component: 'Input'
},
{
// 字段名
fieldName: 'userBirthday',
// label
label: '生日',
// 自动组件
component: 'DatePicker'
},
{
// 字段名
fieldName: 'userFace',
// label
label: '头像',
// 自动组件
component: 'Input'
},
{
// 字段名
fieldName: 'userEmail',
// label
label: '邮箱',
// 自动组件
component: 'Input'
},
{
// 字段名
fieldName: 'createdAt',
// label
label: '创建时间',
// 自动组件
component: 'DatePicker'
},
{
// 字段名
fieldName: 'updatedAt',
// label
label: '更新时间',
// 自动组件
component: 'DatePicker'
},
{
// 字段名
fieldName: 'createdBy',
// label
label: '创建人',
// 自动组件
component: 'InputNumber'
},
{
// 字段名
fieldName: 'updatedBy',
// label
label: '更新人',
// 自动组件
component: 'InputNumber'
},
{
// 字段名
fieldName: 'deletedFlag',
// label
label: '删除 0 默认 1删除',
// 自动组件
component: 'InputNumber'
},
{
// 字段名
fieldName: 'userAddress',
// label
label: '地址',
// 自动组件
component: 'Input'
},
{
// 字段名
fieldName: 'userId',
// label
label: '用户ID冗余字段',
// 自动组件
component: 'InputNumber'
},
{
// 字段名
fieldName: 'userSys',
// label
label: '系统型号',
// 自动组件
component: 'Input'
},
{
// 字段名
fieldName: 'userPhoneModel',
// label
label: '手机型号',
// 自动组件
component: 'Input'
},
{
// 字段名
fieldName: 'userStatus',
// label
label: '用户状态默认启用0,注销1',
// 自动组件
component: 'InputNumber'
},
{
// 字段名
fieldName: 'userCid',
// label
label: '手机唯一标识',
// 自动组件
component: 'Input'
},
{
// 字段名
fieldName: 'userIp',
// label
label: '手机IP',
// 自动组件
component: 'Input'
},
];

332
vue-vben-admin/apps/web-antd/src/views/user/index.vue

@ -1,332 +0,0 @@
<script setup lang="ts">
/**
* 用户管理页面
*/
import {ref, reactive, onMounted, watch} from 'vue';
import {useVbenVxeGrid} from '#/adapter/vxe-table';
import {useVbenModal} from '@vben/common-ui';
import {useVbenForm} from '#/adapter/form';
import dayjs from 'dayjs';
import {columns} from './data';
import {formSchema} from './form';
import {userApi} from '#/api/user';
// ========== ==========
const currentRow = ref(null);
const isEdit = ref(false);
const modalTitle = ref('新增');
// ========== Schema ==========
const querySchema = ref([]);
// ========== ==========
const enumData = reactive({
loading: true,
list: [], //
});
//todo
const hiddenColumns = ref(['createdAt', 'updatedBy', 'updatedAt', 'userPassword', 'userId', 'userSys', 'deletedFlag', "userFace"])
// ========== ==========
async function initEnumData() {
try {
enumData.loading = true;
//
const res = await userApi.enumList({});
const enums = res.result || res;
//
enumData.list = enums;
// queryFields schema`
querySchema.value = formSchema.filter(formItem => {
// 2.
if (hiddenColumns.value.includes(formItem.fieldName)) {
console.log('跳过隐藏字段:', formItem.fieldName)
return false;
}
return true;
}).map(formSchemaTmp => {
//
const matchedEnums = enums.filter(item => item.fieldName === formSchemaTmp.fieldName);
// fieldName options
const allOptions = matchedEnums.reduce((acc, item) => {
if (item.options && Array.isArray(item.options)) {
return [...acc, ...item.options];
}
return acc;
}, []);
//
if (allOptions.length > 0) {
return {
component: 'Select',
fieldName: formSchemaTmp.fieldName,
label: formSchemaTmp.label,
componentProps: {
placeholder: `请选择`,
allowClear: true,
options: allOptions.map(opt => ({
label: opt.label,
value: String(opt.value), // value
})),
},
};
} else {
// 使 Input
return {
component: 'Input',
fieldName: formSchemaTmp.fieldName,
label: formSchemaTmp.label,
componentProps: {
placeholder: `请输入${formSchemaTmp.label}`,
allowClear: true,
},
};
}
});
} catch (error) {
} finally {
enumData.loading = false;
}
}
//
onMounted(() => {
initEnumData();
});
// ========== ( schema) ==========
const [QueryForm, queryFormApi] = useVbenForm({
schema: [], //
layout: 'inline',
showDefaultActions: false,
wrapperClass: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-5',
})
// ========== querySchema ==========
watch(
querySchema,
(newSchema) => {
if (newSchema && newSchema.length > 0) {
console.log('🔄 更新查询表单 schema:', newSchema);
// 使 setState schema
queryFormApi.setState({
schema: newSchema,
});
}
},
{immediate: false}
);
// ========== ==========
const gridOptions = {
columns: [
...columns,
{
field: 'action',
title: '操作',
width: 120,
fixed: 'right',
slots: {default: 'action'},
},
],
proxyConfig: {
ajax: {
query: async ({page}) => {
try {
//
const queryValues = await queryFormApi.getValues();
console.log('=== 查询参数 ===', {
pageNum: page?.currentPage || 1,
pageSize: page?.pageSize || 10,
...queryValues,
})
const res = await userApi.page({
pageNum: page?.currentPage || 1,
pageSize: page?.pageSize || 10,
...queryValues, //
})
const data = res.error?.result || res.result || res
return {
items: data.records || [],
total: data.total || 0
}
} catch (error) {
console.error('查询用户列表失败:', error)
throw error
}
}
},
response: {
result: 'items',
total: 'total'
}
},
pagerConfig: {
enabled: true,
pageSize: 10,
},
}
const [Grid, gridApi] = useVbenVxeGrid({gridOptions})
// ========== ==========
const [Modal, modalApi] = useVbenModal({
centered: true,
closable: true,
maskClosable: false,
draggable: true,
width: 800,
onCancel() {
modalApi.close();
},
onConfirm: async () => {
try {
const values = await formApi.validateAndSubmitForm();
if (!values) return;
// Day.js
const submitValues = {
...values,
userBirthday: values.userBirthday ? dayjs(values.userBirthday).format('YYYY-MM-DD') : null,
};
if (isEdit.value && currentRow.value?.id) {
await userApi.save({...submitValues, id: currentRow.value.id});
} else {
await userApi.save(submitValues);
}
modalApi.close();
gridApi.reload();
} catch (error) {
console.error('保存失败:', error);
}
},
onOpenChange(isOpen: boolean) {
if (!isOpen && !isEdit.value) {
formApi.resetForm();
}
},
})
// ========== ==========
const [Form, formApi] = useVbenForm({
schema: formSchema,
showDefaultActions: false,
wrapperClass: 'grid-cols-1 md:grid-cols-2',
commonConfig: {
componentProps: {
class: 'w-full',
autocomplete: 'off',
},
},
})
// ========== ==========
function handleAdd() {
isEdit.value = false;
modalTitle.value = '新增用户';
formApi.resetForm();
modalApi.open();
}
// ========== ==========
function handleEdit(row: any) {
isEdit.value = true;
currentRow.value = row;
modalTitle.value = '编辑用户';
//
const formValues = {
id: row.id,
userName: row.userName,
userPhone: row.userPhone,
userRealName: row.userRealName,
userGender: row.userGender,
userPassword: row.userPassword,
userBirthday: row.userBirthday,
userFace: row.userFace,
userEmail: row.userEmail,
userAddress: row.userAddress,
userId: row.userId,
userSys: row.userSys,
userPhoneModel: row.userPhoneModel,
userStatus: row.userStatus,
userCid: row.userCid,
userIp: row.userIp,
};
formApi.setValues(formValues);
modalApi.open();
}
// ========== ==========
function handleDelete(row: any) {
if (!row.id) return;
window.confirm(`确定要删除 "${row.userName}" 吗?`) &&
userApi.remove(row.id).then(() => {
gridApi.reload();
});
}
// ========== ==========
function handleSearch() {
console.log('=== 点击查询按钮 ===')
//
gridApi.query();
}
// ========== ==========
function handleReset() {
queryFormApi.resetForm();
gridApi.reload();
}
</script>
<template>
<div style="height: 100vh; padding: 16px; box-sizing: border-box;">
<!-- 查询表单 -->
<div class="bg-card mb-4 p-4 rounded shadow">
<h3 class="text-lg font-semibold mb-3">查询条件</h3>
<QueryForm/>
<div class="mt-3 flex gap-2">
<button @click="handleSearch"
class="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600">
🔍 查询
</button>
<button @click="handleReset"
class="bg-gray-500 text-white px-4 py-2 rounded hover:bg-gray-600">
🔄 重置
</button>
</div>
</div>
<!-- 数据表格 -->
<Grid>
<template #toolbar-tools>
<button @click="handleAdd" class="mr-2"> 新增</button>
<button @click="() => gridApi.reload()">🔄 刷新</button>
</template>
<template #action="{ row }">
<div class="flex gap-2">
<button @click="() => handleEdit(row)" class="text-blue-500 hover:text-blue-700"> 编辑
</button>
<button @click="() => handleDelete(row)" class="text-red-500 hover:text-red-700">🗑 删除
</button>
</div>
</template>
</Grid>
<Modal :title="modalTitle">
<Form/>
</Modal>
</div>
</template>
Loading…
Cancel
Save