refactor: ♻️ 用户管理重构

This commit is contained in:
H0nGzA1
2023-03-24 18:45:58 +08:00
parent b6b3b4a39a
commit df74c792f6
2 changed files with 377 additions and 292 deletions

View File

@@ -1,297 +1,305 @@
import * as api from "./api"; import * as api from './api';
import { dict, PageQuery, AddReq, DelReq, EditReq, CrudExpose, CrudOptions, } from "@fast-crud/fast-crud"; import { dict, PageQuery, AddReq, DelReq, EditReq, CrudExpose, CrudOptions } from '@fast-crud/fast-crud';
import { request } from "/@/utils/service"; import { request } from '/@/utils/service';
import { dictionary } from "/@/utils/dictionary"; import { dictionary } from '/@/utils/dictionary';
interface CreateCrudOptionsTypes { interface CreateCrudOptionsTypes {
crudOptions: CrudOptions; crudOptions: CrudOptions;
} }
export const createCrudOptions = function ({ crudExpose }: { crudExpose: CrudExpose }): CreateCrudOptionsTypes { export const createCrudOptions = function ({ crudExpose }: { crudExpose: CrudExpose }): CreateCrudOptionsTypes {
const pageRequest = async (query: PageQuery) => { const pageRequest = async (query: PageQuery) => {
return await api.GetList(query); return await api.GetList(query);
}; };
const editRequest = async ({ form, row }: EditReq) => { const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id; form.id = row.id;
return await api.UpdateObj(form); return await api.UpdateObj(form);
}; };
const delRequest = async ({ row }: DelReq) => { const delRequest = async ({ row }: DelReq) => {
return await api.DelObj(row.id); return await api.DelObj(row.id);
}; };
const addRequest = async ({ form }: AddReq) => { const addRequest = async ({ form }: AddReq) => {
return await api.AddObj(form); return await api.AddObj(form);
}; };
return { return {
crudOptions: { crudOptions: {
request: { request: {
pageRequest, pageRequest,
addRequest, addRequest,
editRequest, editRequest,
delRequest delRequest,
}, },
rowHandle: { rowHandle: {
//固定右侧 //固定右侧
fixed: "right", fixed: 'right',
width: 310, width: 300,
buttons: { buttons: {
orderExample: { view: {
show:false, show: false,
text: "重置密码", },
click: () => { edit: {
//console.log("reset password") iconRight: 'Edit',
} type: 'text',
} },
}, remove: {
iconRight: 'Delete',
}, type: 'text',
columns: { },
_index: { },
title: '序号', },
form: { show: false }, columns: {
column: { _index: {
type: 'index', title: '序号',
align: 'center', form: { show: false },
width: '70px', column: {
columnSetDisabled: true, //禁止在列设置中选择 type: 'index',
}, align: 'center',
}, width: '70px',
username: { columnSetDisabled: true, //禁止在列设置中选择
title: '账号', },
search: { },
show: true, username: {
}, title: '账号',
minWidth: 100, search: {
type: 'input', show: true,
form: { },
rules: [ // 表单校验规则 minWidth: 100,
{ type: 'input',
required: true, form: {
message: '账号必填项' rules: [
} // 表单校验规则
], {
component: { required: true,
placeholder: '请输入账号' message: '账号必填项',
}, },
} ],
}, component: {
password: { placeholder: '请输入账号',
title: '密码', },
type: 'input', },
column: { },
show: false password: {
}, title: '密码',
editForm: { type: 'input',
show: false column: {
}, show: false,
form: { },
rules: [ // 表单校验规则 editForm: {
{ show: false,
required: true, },
message: '密码必填项' form: {
} rules: [
], // 表单校验规则
component: { {
span: 12, required: true,
showPassword: true, message: '密码必填项',
placeholder: '请输入密码' },
}, ],
// value: vm.systemConfig('base.default_password'), component: {
}, span: 12,
/* valueResolve(row, key) { showPassword: true,
placeholder: '请输入密码',
},
// value: vm.systemConfig('base.default_password'),
},
/* valueResolve(row, key) {
if (row.password) { if (row.password) {
row.password = vm.$md5(row.password) row.password = vm.$md5(row.password)
} }
} */ } */
}, },
name: { name: {
title: '姓名', title: '姓名',
search: { search: {
show: true, show: true,
}, },
type: 'input', type: 'input',
form: { form: {
rules: [ // 表单校验规则 rules: [
{ // 表单校验规则
required: true, {
message: '姓名必填项' required: true,
} message: '姓名必填项',
], },
component: { ],
span: 12, component: {
placeholder: '请输入姓名' span: 12,
}, placeholder: '请输入姓名',
} },
}, },
dept: { },
title: '部门', dept: {
search: { title: '部门',
disabled: true search: {
}, disabled: true,
type: 'dict-tree', },
dict: dict({ type: 'dict-tree',
isTree: true, dict: dict({
url: '/api/system/dept/all_dept/', isTree: true,
value: 'id', url: '/api/system/dept/all_dept/',
label: 'name', value: 'id',
getData: async ({ url }: { url: string }) => { label: 'name',
return request({ getData: async ({ url }: { url: string }) => {
url: url, return request({
}).then((ret: any) => { url: url,
return ret.data }).then((ret: any) => {
}) return ret.data;
} });
}), },
form: { }),
rules: [ // 表单校验规则 form: {
{ rules: [
required: true, // 表单校验规则
message: '必填项' {
} required: true,
], message: '必填项',
component: { },
filterable: true, ],
placeholder: '请选择', component: {
props: { filterable: true,
props: { placeholder: '请选择',
value: "id", props: {
label: "name", props: {
} value: 'id',
} label: 'name',
}, },
}, },
}, },
role: { },
title: '角色', },
search: { role: {
disabled: true title: '角色',
}, search: {
type: 'dict-select', disabled: true,
dict: dict({ },
url: '/api/system/role/', type: 'dict-select',
value: 'id', dict: dict({
label: 'name', url: '/api/system/role/',
isTree: true, value: 'id',
getData: async ({ url }: { url: string }) => { label: 'name',
return request({ isTree: true,
url: url, getData: async ({ url }: { url: string }) => {
params: { return request({
page: 1, url: url,
limit: 10 params: {
} page: 1,
}).then((ret: any) => { limit: 10,
return ret.data },
}) }).then((ret: any) => {
} return ret.data;
}), });
form: { },
rules: [ // 表单校验规则 }),
{ form: {
required: true, rules: [
message: '必填项' // 表单校验规则
} {
], required: true,
component: { message: '必填项',
multiple: true, },
filterable: true, ],
placeholder: '请选择角色' component: {
}, multiple: true,
} filterable: true,
}, placeholder: '请选择角色',
mobile: { },
title: '手机号码', },
search: { },
show: true, mobile: {
}, title: '手机号码',
type: 'input', search: {
form: { show: true,
rules: [ },
{ type: 'input',
max: 20, form: {
message: '请输入正确的手机号码', rules: [
trigger: 'blur' {
}, max: 20,
{ message: '请输入正确的手机号码',
pattern: /^1[3-9]\d{9}$/, trigger: 'blur',
message: '请输入正确的手机号码' },
} {
], pattern: /^1[3-9]\d{9}$/,
component: { message: '请输入正确的手机号码',
placeholder: '请输入手机号码' },
} ],
} component: {
}, placeholder: '请输入手机号码',
email: { },
title: '邮箱', },
column:{ },
width:260 email: {
}, title: '邮箱',
form: { column: {
rules: [ width: 260,
{ },
type: 'email', form: {
message: '请输入正确的邮箱地址', rules: [
trigger: ['blur', 'change'] {
} type: 'email',
], message: '请输入正确的邮箱地址',
component: { trigger: ['blur', 'change'],
placeholder: '请输入邮箱' },
} ],
} component: {
}, placeholder: '请输入邮箱',
gender: { },
title: '性别', },
type: 'dict-radio', },
dict: dict({ gender: {
data: dictionary('gender') title: '性别',
}), type: 'dict-radio',
form: { dict: dict({
value: 1, data: dictionary('gender'),
component: { }),
span: 12 form: {
} value: 1,
}, component: {
component: { props: { color: 'auto' } } // 自动染色 span: 12,
}, },
user_type: { },
title: '用户类型', component: { props: { color: 'auto' } }, // 自动染色
search: { },
show: true, user_type: {
}, title: '用户类型',
type: 'dict-select', search: {
dict: dict({ show: true,
data: dictionary('user_type') },
}), type: 'dict-select',
form: { dict: dict({
show: false, data: dictionary('user_type'),
value: 0, }),
component: { form: {
span: 12 show: false,
} value: 0,
} component: {
}, span: 12,
is_active: { },
title: '状态', },
search: { },
show: true, is_active: {
}, title: '状态',
type: 'dict-radio', search: {
dict: dict({ show: true,
data: dictionary('button_status_bool') },
}), type: 'dict-radio',
form: { dict: dict({
value: true, data: dictionary('button_status_bool'),
component: { }),
span: 12 form: {
} value: true,
} component: {
}, span: 12,
avatar: { },
title: '头像', },
type: 'avatar-cropper', },
form:{ avatar: {
show:false title: '头像',
} type: 'avatar-cropper',
} form: {
} show: false,
} },
}; },
} },
},
};
};

View File

@@ -1,13 +1,32 @@
<template> <template>
<fs-page> <fs-page>
<fs-crud ref="crudRef" v-bind="crudBinding"> </fs-crud> <el-row>
<el-col :span="4">
<el-card :body-style="{ height: '100%' }">
<el-input v-model="filterText" :placeholder="placeholder" />
<el-tree ref="treeRef" class="filter-tree" :data="data" :props="defaultProps" default-expand-all :filter-node-method="filterNode" />
</el-card>
</el-col>
<el-col :span="20" :offset="0">
<el-card :body-style="{ height: '100%' }">
<fs-crud class="h-full w-full" ref="crudRef" v-bind="crudBinding"> </fs-crud>
</el-card>
</el-col>
</el-row>
</fs-page> </fs-page>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref, onMounted } from 'vue'; import * as api from './api';
import { ElTree } from 'element-plus';
import { ref, onMounted, computed, watch } from 'vue';
import { useExpose, useCrud } from '@fast-crud/fast-crud'; import { useExpose, useCrud } from '@fast-crud/fast-crud';
import { createCrudOptions } from './crud'; import { createCrudOptions } from './crud';
import MenuButton from './components/menuButton/index.vue';
import XEUtils from 'xe-utils';
const menuButtonRef = ref();
defineExpose(menuButtonRef);
// crud组件的ref // crud组件的ref
const crudRef = ref(); const crudRef = ref();
// crud 配置的ref // crud 配置的ref
@@ -15,12 +34,70 @@ const crudBinding = ref();
// 暴露的方法 // 暴露的方法
const { crudExpose } = useExpose({ crudRef, crudBinding }); const { crudExpose } = useExpose({ crudRef, crudBinding });
// 你的crud配置 // 你的crud配置
const { crudOptions } = createCrudOptions({ crudExpose }); const { crudOptions } = createCrudOptions({ crudExpose, menuButtonRef });
// 初始化crud配置 // 初始化crud配置
const { resetCrudOptions } = useCrud({ crudExpose, crudOptions }); const { resetCrudOptions } = useCrud({ crudExpose, crudOptions });
interface Tree {
id: number;
label: string;
children?: Tree[];
}
const placeholder = ref('请输入用户');
const filterText = ref('');
const treeRef = ref<InstanceType<typeof ElTree>>();
const defaultProps = {
children: 'children',
label: 'name',
};
watch(filterText, (val) => {
treeRef.value!.filter(val);
});
const filterNode = (value: string, data: Tree) => {
if (!value) return true;
return data.label.includes(value);
};
let data = ref([]);
interface APIResponseData {
code?: number;
data: [];
msg?: string;
}
const getData = () => {
api.GetList({}).then((ret: APIResponseData) => {
const responseData = ret.data;
const result = XEUtils.toArrayTree(responseData, {
parentKey: 'parent_id',
children: 'children',
strict: true,
});
data.value = result;
});
};
// 页面打开后获取列表数据 // 页面打开后获取列表数据
onMounted(() => { onMounted(() => {
crudExpose.doRefresh(); crudExpose.doRefresh();
getData();
}); });
</script> </script>
<style lang="scss" scoped>
.el-row {
height: 100%;
.el-col {
height: 100%;
}
}
.el-card {
height: 100%;
}
</style>