mirror of
https://github.com/vbenjs/gf-vben-admin.git
synced 2025-01-23 11:50:20 +08:00
合并
This commit is contained in:
parent
44cda700e9
commit
5f62d64757
@ -1,5 +1,5 @@
|
|||||||
# Whether to open mock
|
# Whether to open mock
|
||||||
VITE_USE_MOCK = true
|
VITE_USE_MOCK = false
|
||||||
|
|
||||||
# public path
|
# public path
|
||||||
VITE_PUBLIC_PATH = /
|
VITE_PUBLIC_PATH = /
|
||||||
@ -13,7 +13,7 @@ VITE_PROXY = [["/basic-api","http://localhost:3000"],["/upload","http://localhos
|
|||||||
VITE_DROP_CONSOLE = false
|
VITE_DROP_CONSOLE = false
|
||||||
|
|
||||||
# Basic interface address SPA
|
# Basic interface address SPA
|
||||||
VITE_GLOB_API_URL=/basic-api
|
VITE_GLOB_API_URL=http://localhost:10088/api
|
||||||
|
|
||||||
# File upload address, optional
|
# File upload address, optional
|
||||||
VITE_GLOB_UPLOAD_URL=/upload
|
VITE_GLOB_UPLOAD_URL=/upload
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# shellcheck source=./_/husky.sh
|
|
||||||
. "$(dirname "$0")/_/husky.sh"
|
|
||||||
|
|
||||||
npx --no-install commitlint --edit "$1"
|
|
@ -1,9 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
command_exists () {
|
|
||||||
command -v "$1" >/dev/null 2>&1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Workaround for Windows 10, Git Bash and Yarn
|
|
||||||
if command_exists winpty && test -t 1; then
|
|
||||||
exec < /dev/tty
|
|
||||||
fi
|
|
@ -1,8 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
'*.{js,jsx,ts,tsx}': ['eslint --fix', 'prettier --write'],
|
|
||||||
'{!(package)*.json,*.code-snippets,.!(browserslist)*rc}': ['prettier --write--parser json'],
|
|
||||||
'package.json': ['prettier --write'],
|
|
||||||
'*.vue': ['eslint --fix', 'prettier --write', 'stylelint --fix'],
|
|
||||||
'*.{scss,less,styl,html}': ['stylelint --fix', 'prettier --write'],
|
|
||||||
'*.md': ['prettier --write'],
|
|
||||||
};
|
|
@ -1,10 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
. "$(dirname "$0")/_/husky.sh"
|
|
||||||
. "$(dirname "$0")/common.sh"
|
|
||||||
|
|
||||||
[ -n "$CI" ] && exit 0
|
|
||||||
|
|
||||||
# Format and submit code according to lintstagedrc.js configuration
|
|
||||||
npm run lint:lint-staged
|
|
||||||
|
|
||||||
npm run lint:pretty
|
|
@ -30,7 +30,6 @@
|
|||||||
"test:gzip": "http-server dist --cors --gzip -c-1",
|
"test:gzip": "http-server dist --cors --gzip -c-1",
|
||||||
"test:br": "http-server dist --cors --brotli -c-1",
|
"test:br": "http-server dist --cors --brotli -c-1",
|
||||||
"reinstall": "rimraf yarn.lock && rimraf package.lock.json && rimraf node_modules && npm run bootstrap",
|
"reinstall": "rimraf yarn.lock && rimraf package.lock.json && rimraf node_modules && npm run bootstrap",
|
||||||
"prepare": "husky install",
|
|
||||||
"gen:icon": "esno ./build/generate/icon/index.ts"
|
"gen:icon": "esno ./build/generate/icon/index.ts"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
3
src/api/Curd.ts
Normal file
3
src/api/Curd.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import { defHttp } from '/@/utils/http/axios';
|
||||||
|
|
||||||
|
export const Curd = (params) => defHttp.post({ url: '/curd', params });
|
@ -15,7 +15,7 @@ import { defHttp } from '/@/utils/http/axios';
|
|||||||
enum Api {
|
enum Api {
|
||||||
AccountList = '/system/getAccountList',
|
AccountList = '/system/getAccountList',
|
||||||
IsAccountExist = '/system/accountExist',
|
IsAccountExist = '/system/accountExist',
|
||||||
DeptList = '/system/getDeptList',
|
DeptList = 'https://open.ys7.com/api/lapp/device/list',
|
||||||
setRoleStatus = '/system/setRoleStatus',
|
setRoleStatus = '/system/setRoleStatus',
|
||||||
MenuList = '/system/getMenuList',
|
MenuList = '/system/getMenuList',
|
||||||
RolePageList = '/system/getRoleListByPage',
|
RolePageList = '/system/getRoleListByPage',
|
||||||
@ -26,7 +26,7 @@ export const getAccountList = (params: AccountParams) =>
|
|||||||
defHttp.get<AccountListGetResultModel>({ url: Api.AccountList, params });
|
defHttp.get<AccountListGetResultModel>({ url: Api.AccountList, params });
|
||||||
|
|
||||||
export const getDeptList = (params?: DeptListItem) =>
|
export const getDeptList = (params?: DeptListItem) =>
|
||||||
defHttp.get<DeptListGetResultModel>({ url: Api.DeptList, params });
|
defHttp.post<DeptListGetResultModel>({ url: Api.DeptList, params });
|
||||||
|
|
||||||
export const getMenuList = (params?: MenuParams) =>
|
export const getMenuList = (params?: MenuParams) =>
|
||||||
defHttp.get<MenuListGetResultModel>({ url: Api.MenuList, params });
|
defHttp.get<MenuListGetResultModel>({ url: Api.MenuList, params });
|
||||||
|
@ -2,7 +2,7 @@ import { defHttp } from '/@/utils/http/axios';
|
|||||||
import { getMenuListResultModel } from './model/menuModel';
|
import { getMenuListResultModel } from './model/menuModel';
|
||||||
|
|
||||||
enum Api {
|
enum Api {
|
||||||
GetMenuList = '/getMenuList',
|
GetMenuList = '/router/list',
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
import { defHttp } from '/@/utils/http/axios';
|
import { defHttp } from '/@/utils/http/axios';
|
||||||
import {
|
import { LoginParams, GetUserInfoModel } from './model/userModel';
|
||||||
LoginParams,
|
|
||||||
GetUserInfoByUserIdParams,
|
|
||||||
GetUserInfoByUserIdModel,
|
|
||||||
} from './model/userModel';
|
|
||||||
|
|
||||||
import { ErrorMessageMode } from '/#/axios';
|
import { ErrorMessageMode } from '/#/axios';
|
||||||
|
|
||||||
@ -25,6 +21,7 @@ export function loginApi(params: LoginParams, mode: ErrorMessageMode = 'modal')
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
errorMessageMode: mode,
|
errorMessageMode: mode,
|
||||||
|
apiUrl: 'http://localhost:10088',
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -66,6 +66,7 @@ export function transformRouteToMenu(routeModList: AppRouteModule[], routerMappi
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
joinParentPath(list);
|
joinParentPath(list);
|
||||||
return cloneDeep(list);
|
return cloneDeep(list);
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ const setting: ProjectConfig = {
|
|||||||
settingButtonPosition: SettingButtonPositionEnum.AUTO,
|
settingButtonPosition: SettingButtonPositionEnum.AUTO,
|
||||||
|
|
||||||
// Permission mode
|
// Permission mode
|
||||||
permissionMode: PermissionModeEnum.ROUTE_MAPPING,
|
permissionMode: PermissionModeEnum.BACK,
|
||||||
|
|
||||||
// Permission-related cache is stored in sessionStorage or localStorage
|
// Permission-related cache is stored in sessionStorage or localStorage
|
||||||
permissionCacheType: CacheTypeEnum.LOCAL,
|
permissionCacheType: CacheTypeEnum.LOCAL,
|
||||||
|
@ -184,7 +184,7 @@ export const usePermissionStore = defineStore({
|
|||||||
// this function may only need to be executed once, and the actual project can be put at the right time by itself
|
// this function may only need to be executed once, and the actual project can be put at the right time by itself
|
||||||
let routeList: AppRouteRecordRaw[] = [];
|
let routeList: AppRouteRecordRaw[] = [];
|
||||||
try {
|
try {
|
||||||
this.changePermissionCode();
|
// this.changePermissionCode();
|
||||||
routeList = (await getMenuList()) as AppRouteRecordRaw[];
|
routeList = (await getMenuList()) as AppRouteRecordRaw[];
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
|
@ -83,13 +83,13 @@ export class VAxios {
|
|||||||
const {
|
const {
|
||||||
headers: { ignoreCancelToken },
|
headers: { ignoreCancelToken },
|
||||||
} = config;
|
} = config;
|
||||||
|
|
||||||
const ignoreCancel =
|
const ignoreCancel =
|
||||||
ignoreCancelToken !== undefined
|
ignoreCancelToken !== undefined
|
||||||
? ignoreCancelToken
|
? ignoreCancelToken
|
||||||
: this.options.requestOptions?.ignoreCancelToken;
|
: this.options.requestOptions?.ignoreCancelToken;
|
||||||
|
|
||||||
!ignoreCancel && axiosCanceler.addPending(config);
|
!ignoreCancel && axiosCanceler.addPending(config);
|
||||||
|
|
||||||
if (requestInterceptors && isFunction(requestInterceptors)) {
|
if (requestInterceptors && isFunction(requestInterceptors)) {
|
||||||
config = requestInterceptors(config, this.options);
|
config = requestInterceptors(config, this.options);
|
||||||
}
|
}
|
||||||
|
@ -52,8 +52,18 @@ const transform: AxiosTransform = {
|
|||||||
|
|
||||||
// 这里逻辑可以根据项目进行修改
|
// 这里逻辑可以根据项目进行修改
|
||||||
const hasSuccess = data && Reflect.has(data, 'code') && code === ResultEnum.SUCCESS;
|
const hasSuccess = data && Reflect.has(data, 'code') && code === ResultEnum.SUCCESS;
|
||||||
if (!hasSuccess) {
|
if (hasSuccess) {
|
||||||
if (message) {
|
if (message) {
|
||||||
|
notification.success({ message });
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
checkStatus(code, message, options.errorMessageMode);
|
||||||
|
// if (options.errorMessageMode === 'modal') {
|
||||||
|
// createErrorModal({ title: t('sys.api.errorTip'), content: message });
|
||||||
|
// } else if (options.errorMessageMode === 'message') {
|
||||||
|
// createMessage.error(message);
|
||||||
|
// }
|
||||||
// errorMessageMode=‘modal’的时候会显示modal错误弹窗,而不是消息提示,用于一些比较重要的错误
|
// errorMessageMode=‘modal’的时候会显示modal错误弹窗,而不是消息提示,用于一些比较重要的错误
|
||||||
if (options.errorMessageMode === 'modal') {
|
if (options.errorMessageMode === 'modal') {
|
||||||
createErrorModal({ title: t('sys.api.errorTip'), content: message });
|
createErrorModal({ title: t('sys.api.errorTip'), content: message });
|
||||||
@ -63,38 +73,8 @@ const transform: AxiosTransform = {
|
|||||||
}
|
}
|
||||||
Promise.reject(new Error(message));
|
Promise.reject(new Error(message));
|
||||||
return message;
|
return message;
|
||||||
}
|
|
||||||
|
|
||||||
// 接口请求成功,直接返回结果
|
|
||||||
if (code === ResultEnum.SUCCESS) {
|
|
||||||
if (message) {
|
|
||||||
notification.success({ message });
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
// 接口请求错误,统一提示错误信息
|
|
||||||
if (code === ResultEnum.ERROR) {
|
|
||||||
if (message) {
|
|
||||||
createMessage.error(data.message);
|
|
||||||
Promise.reject(new Error(message));
|
|
||||||
} else {
|
|
||||||
const msg = t('sys.api.errorMessage');
|
|
||||||
createMessage.error(msg);
|
|
||||||
Promise.reject(new Error(msg));
|
|
||||||
}
|
|
||||||
throw new Error( t('sys.api.apiRequestFailed'));
|
|
||||||
}
|
|
||||||
// 登录超时
|
|
||||||
if (code === ResultEnum.TIMEOUT) {
|
|
||||||
const timeoutMsg = t('sys.api.timeoutMessage');
|
|
||||||
createErrorModal({
|
|
||||||
title: t('sys.api.operationFailed'),
|
|
||||||
content: timeoutMsg,
|
|
||||||
});
|
|
||||||
Promise.reject(new Error(timeoutMsg));
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
return message;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// 请求之前处理config
|
// 请求之前处理config
|
||||||
@ -174,6 +154,7 @@ const transform: AxiosTransform = {
|
|||||||
responseInterceptorsCatch: (error: any) => {
|
responseInterceptorsCatch: (error: any) => {
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const errorLogStore = useErrorLogStoreWithOut();
|
const errorLogStore = useErrorLogStoreWithOut();
|
||||||
|
|
||||||
errorLogStore.addAjaxErrorInfo(error);
|
errorLogStore.addAjaxErrorInfo(error);
|
||||||
const { response, code, message, config } = error || {};
|
const { response, code, message, config } = error || {};
|
||||||
const errorMessageMode = config?.requestOptions?.errorMessageMode || 'none';
|
const errorMessageMode = config?.requestOptions?.errorMessageMode || 'none';
|
||||||
@ -212,8 +193,8 @@ function createAxios(opt?: Partial<CreateAxiosOptions>) {
|
|||||||
{
|
{
|
||||||
// See https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#authentication_schemes
|
// See https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#authentication_schemes
|
||||||
// authentication schemes,e.g: Bearer
|
// authentication schemes,e.g: Bearer
|
||||||
// authenticationScheme: 'Bearer',
|
|
||||||
authenticationScheme: 'Bearer',
|
authenticationScheme: 'Bearer',
|
||||||
|
// authenticationScheme: '',
|
||||||
timeout: 10 * 1000,
|
timeout: 10 * 1000,
|
||||||
// 基础接口地址
|
// 基础接口地址
|
||||||
// baseURL: globSetting.apiUrl,
|
// baseURL: globSetting.apiUrl,
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<BasicModal v-bind="$attrs" @register="registerModal" :title="getTitle" @ok="handleSubmit">
|
<BasicModal v-bind="$attrs" @register="registerModal" :title="getTitle" @ok="handleSubmit">
|
||||||
|
{{ formRef }}
|
||||||
<BasicForm @register="registerForm" />
|
<BasicForm @register="registerForm" />
|
||||||
</BasicModal>
|
</BasicModal>
|
||||||
</template>
|
</template>
|
||||||
@ -16,10 +17,11 @@
|
|||||||
emits: ['success', 'register'],
|
emits: ['success', 'register'],
|
||||||
setup(_, { emit }) {
|
setup(_, { emit }) {
|
||||||
const isUpdate = ref(true);
|
const isUpdate = ref(true);
|
||||||
|
const formRef = ref();
|
||||||
const [registerForm, { resetFields, setFieldsValue, updateSchema, validate }] = useForm({
|
const [registerForm, { resetFields, setFieldsValue, updateSchema, validate }] = useForm({
|
||||||
labelWidth: 100,
|
labelWidth: 100,
|
||||||
schemas: formSchema,
|
schemas: formSchema,
|
||||||
|
model: formRef,
|
||||||
showActionButtonGroup: false,
|
showActionButtonGroup: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -55,7 +57,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return { registerModal, registerForm, getTitle, handleSubmit };
|
return { registerModal, registerForm, getTitle, handleSubmit, formRef };
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
60
src/views/dept/DeptModal.vue
Normal file
60
src/views/dept/DeptModal.vue
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
<template>
|
||||||
|
<BasicModal v-bind="$attrs" @register="registerModal" :title="getTitle" @ok="handleSubmit">
|
||||||
|
<BasicForm @register="registerForm" />
|
||||||
|
</BasicModal>
|
||||||
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent, ref, computed, unref } from 'vue';
|
||||||
|
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||||
|
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||||
|
import { formSchema } from './dept.data';
|
||||||
|
|
||||||
|
import { getDeptList } from '/@/api/demo/system';
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'DeptModal',
|
||||||
|
components: { BasicModal, BasicForm },
|
||||||
|
emits: ['success', 'register'],
|
||||||
|
setup(_, { emit }) {
|
||||||
|
const isUpdate = ref(true);
|
||||||
|
const [registerForm, { resetFields, setFieldsValue, updateSchema, validate }] = useForm({
|
||||||
|
labelWidth: 100,
|
||||||
|
schemas: formSchema,
|
||||||
|
showActionButtonGroup: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||||||
|
resetFields();
|
||||||
|
setModalProps({ confirmLoading: false });
|
||||||
|
isUpdate.value = !!data?.isUpdate;
|
||||||
|
|
||||||
|
if (unref(isUpdate)) {
|
||||||
|
setFieldsValue({
|
||||||
|
...data.record,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// const treeData = await getDeptList();
|
||||||
|
// updateSchema({
|
||||||
|
// field: 'parentDept',
|
||||||
|
// componentProps: { treeData },
|
||||||
|
// });
|
||||||
|
});
|
||||||
|
|
||||||
|
const getTitle = computed(() => (!unref(isUpdate) ? '新增部门' : '编辑部门'));
|
||||||
|
|
||||||
|
async function handleSubmit() {
|
||||||
|
// try {
|
||||||
|
// const values = await validate();
|
||||||
|
// setModalProps({ confirmLoading: true });
|
||||||
|
// // TODO custom api
|
||||||
|
// console.log(values);
|
||||||
|
// closeModal();
|
||||||
|
// emit('success');
|
||||||
|
// } finally {
|
||||||
|
// setModalProps({ confirmLoading: false });
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
return { registerModal, registerForm, getTitle, handleSubmit };
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
108
src/views/dept/dept.data.ts
Normal file
108
src/views/dept/dept.data.ts
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
import { BasicColumn } from '/@/components/Table';
|
||||||
|
import { FormSchema } from '/@/components/Table';
|
||||||
|
import { h } from 'vue';
|
||||||
|
import { Tag } from 'ant-design-vue';
|
||||||
|
|
||||||
|
export const columns: BasicColumn[] = [
|
||||||
|
{
|
||||||
|
title: '部门名称',
|
||||||
|
dataIndex: 'deptName',
|
||||||
|
width: 160,
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '排序',
|
||||||
|
dataIndex: 'orderNo',
|
||||||
|
width: 50,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '状态',
|
||||||
|
dataIndex: 'status',
|
||||||
|
width: 80,
|
||||||
|
customRender: ({ record }) => {
|
||||||
|
const status = record.status;
|
||||||
|
const enable = ~~status === 0;
|
||||||
|
const color = enable ? 'green' : 'red';
|
||||||
|
const text = enable ? '启用' : '停用';
|
||||||
|
return h(Tag, { color: color }, () => text);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '创建时间',
|
||||||
|
dataIndex: 'createTime',
|
||||||
|
width: 180,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '备注',
|
||||||
|
dataIndex: 'remark',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const searchFormSchema: FormSchema[] = [
|
||||||
|
{
|
||||||
|
field: 'deptName',
|
||||||
|
label: '部门名称',
|
||||||
|
component: 'Input',
|
||||||
|
colProps: { span: 8 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'status',
|
||||||
|
label: '状态',
|
||||||
|
component: 'Select',
|
||||||
|
componentProps: {
|
||||||
|
options: [
|
||||||
|
{ label: '启用', value: '0' },
|
||||||
|
{ label: '停用', value: '1' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
colProps: { span: 8 },
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const formSchema: FormSchema[] = [
|
||||||
|
{
|
||||||
|
field: 'deptName',
|
||||||
|
label: '部门名称',
|
||||||
|
component: 'Input',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'parentDept',
|
||||||
|
label: '上级部门',
|
||||||
|
component: 'TreeSelect',
|
||||||
|
|
||||||
|
componentProps: {
|
||||||
|
replaceFields: {
|
||||||
|
title: 'deptName',
|
||||||
|
key: 'id',
|
||||||
|
value: 'id',
|
||||||
|
},
|
||||||
|
getPopupContainer: () => document.body,
|
||||||
|
},
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'orderNo',
|
||||||
|
label: '排序',
|
||||||
|
component: 'InputNumber',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'status',
|
||||||
|
label: '状态',
|
||||||
|
component: 'RadioButtonGroup',
|
||||||
|
defaultValue: '0',
|
||||||
|
componentProps: {
|
||||||
|
options: [
|
||||||
|
{ label: '启用', value: '0' },
|
||||||
|
{ label: '停用', value: '1' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '备注',
|
||||||
|
field: 'remark',
|
||||||
|
component: 'InputTextArea',
|
||||||
|
},
|
||||||
|
];
|
100
src/views/dept/index.vue
Normal file
100
src/views/dept/index.vue
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<BasicTable @register="registerTable">
|
||||||
|
<template #toolbar>
|
||||||
|
<a-button type="primary" @click="handleCreate"> 新增部门 </a-button>
|
||||||
|
</template>
|
||||||
|
<template #action="{ record }">
|
||||||
|
<TableAction
|
||||||
|
:actions="[
|
||||||
|
{
|
||||||
|
icon: 'clarity:note-edit-line',
|
||||||
|
onClick: handleEdit.bind(null, record),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'ant-design:delete-outlined',
|
||||||
|
color: 'error',
|
||||||
|
popConfirm: {
|
||||||
|
title: '是否确认删除',
|
||||||
|
confirm: handleDelete.bind(null, record),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</BasicTable>
|
||||||
|
<DeptModal @register="registerModal" @success="handleSuccess" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
|
import { BasicTable, useTable, TableAction } from '/@/components/Table';
|
||||||
|
import { getDeptList } from '/@/api/demo/system';
|
||||||
|
|
||||||
|
import { useModal } from '/@/components/Modal';
|
||||||
|
import DeptModal from './DeptModal.vue';
|
||||||
|
|
||||||
|
import { columns, searchFormSchema } from './dept.data';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'DeptManagement',
|
||||||
|
components: { BasicTable, DeptModal, TableAction },
|
||||||
|
setup() {
|
||||||
|
const [registerModal, { openModal }] = useModal();
|
||||||
|
const [registerTable, { reload }] = useTable({
|
||||||
|
title: '部门列表',
|
||||||
|
api: getDeptList,
|
||||||
|
columns,
|
||||||
|
formConfig: {
|
||||||
|
labelWidth: 120,
|
||||||
|
schemas: searchFormSchema,
|
||||||
|
},
|
||||||
|
pagination: false,
|
||||||
|
striped: false,
|
||||||
|
useSearchForm: true,
|
||||||
|
showTableSetting: true,
|
||||||
|
bordered: true,
|
||||||
|
showIndexColumn: false,
|
||||||
|
canResize: false,
|
||||||
|
actionColumn: {
|
||||||
|
width: 80,
|
||||||
|
title: '操作',
|
||||||
|
dataIndex: 'action',
|
||||||
|
slots: { customRender: 'action' },
|
||||||
|
fixed: undefined,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
function handleCreate() {
|
||||||
|
openModal(true, {
|
||||||
|
isUpdate: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleEdit(record: Recordable) {
|
||||||
|
openModal(true, {
|
||||||
|
record,
|
||||||
|
isUpdate: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleDelete(record: Recordable) {
|
||||||
|
console.log(record);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleSuccess() {
|
||||||
|
reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
registerTable,
|
||||||
|
registerModal,
|
||||||
|
handleCreate,
|
||||||
|
handleEdit,
|
||||||
|
handleDelete,
|
||||||
|
handleSuccess,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
70
src/views/menu/MenuDrawer.vue
Normal file
70
src/views/menu/MenuDrawer.vue
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
<template>
|
||||||
|
<BasicDrawer
|
||||||
|
v-bind="$attrs"
|
||||||
|
@register="registerDrawer"
|
||||||
|
showFooter
|
||||||
|
:title="getTitle"
|
||||||
|
width="50%"
|
||||||
|
@ok="handleSubmit"
|
||||||
|
>
|
||||||
|
<BasicForm @register="registerForm" />
|
||||||
|
</BasicDrawer>
|
||||||
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent, ref, computed, unref } from 'vue';
|
||||||
|
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||||
|
import { formSchema } from './menu.data';
|
||||||
|
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
|
||||||
|
|
||||||
|
import { getMenuList } from '/@/api/demo/system';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'MenuDrawer',
|
||||||
|
components: { BasicDrawer, BasicForm },
|
||||||
|
emits: ['success', 'register'],
|
||||||
|
setup(_, { emit }) {
|
||||||
|
const isUpdate = ref(true);
|
||||||
|
|
||||||
|
const [registerForm, { resetFields, setFieldsValue, updateSchema, validate }] = useForm({
|
||||||
|
labelWidth: 100,
|
||||||
|
schemas: formSchema,
|
||||||
|
showActionButtonGroup: false,
|
||||||
|
baseColProps: { lg: 12, md: 24 },
|
||||||
|
});
|
||||||
|
|
||||||
|
const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
|
||||||
|
resetFields();
|
||||||
|
setDrawerProps({ confirmLoading: false });
|
||||||
|
isUpdate.value = !!data?.isUpdate;
|
||||||
|
|
||||||
|
if (unref(isUpdate)) {
|
||||||
|
setFieldsValue({
|
||||||
|
...data.record,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const treeData = await getMenuList();
|
||||||
|
updateSchema({
|
||||||
|
field: 'parentMenu',
|
||||||
|
componentProps: { treeData },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const getTitle = computed(() => (!unref(isUpdate) ? '新增菜单' : '编辑菜单'));
|
||||||
|
|
||||||
|
async function handleSubmit() {
|
||||||
|
try {
|
||||||
|
const values = await validate();
|
||||||
|
setDrawerProps({ confirmLoading: true });
|
||||||
|
// TODO custom api
|
||||||
|
console.log(values);
|
||||||
|
closeDrawer();
|
||||||
|
emit('success');
|
||||||
|
} finally {
|
||||||
|
setDrawerProps({ confirmLoading: false });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { registerDrawer, registerForm, getTitle, handleSubmit };
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
104
src/views/menu/index.vue
Normal file
104
src/views/menu/index.vue
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<BasicTable @register="registerTable">
|
||||||
|
<template #toolbar>
|
||||||
|
<a-button type="primary" @click="handleCreate"> 新增菜单 </a-button>
|
||||||
|
</template>
|
||||||
|
<template #action="{ record }">
|
||||||
|
<TableAction
|
||||||
|
:actions="[
|
||||||
|
{
|
||||||
|
icon: 'clarity:note-edit-line',
|
||||||
|
onClick: handleEdit.bind(null, record),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'ant-design:delete-outlined',
|
||||||
|
color: 'error',
|
||||||
|
popConfirm: {
|
||||||
|
title: '是否确认删除',
|
||||||
|
confirm: handleDelete.bind(null, record),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</BasicTable>
|
||||||
|
<MenuDrawer @register="registerDrawer" @success="handleSuccess" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
|
import { BasicTable, useTable, TableAction } from '/@/components/Table';
|
||||||
|
|
||||||
|
import { useDrawer } from '/@/components/Drawer';
|
||||||
|
import MenuDrawer from './MenuDrawer.vue';
|
||||||
|
import { columns, searchFormSchema } from './menu.data';
|
||||||
|
import { Curd } from '/@/api/Curd';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'MenuManagement',
|
||||||
|
components: { BasicTable, MenuDrawer, TableAction },
|
||||||
|
setup() {
|
||||||
|
const [registerDrawer, { openDrawer }] = useDrawer();
|
||||||
|
const [registerTable, { reload }] = useTable({
|
||||||
|
title: '菜单列表',
|
||||||
|
api: Curd,
|
||||||
|
beforeFetch: (v) => {
|
||||||
|
v.i = 'router';
|
||||||
|
v.a = 'list';
|
||||||
|
return v;
|
||||||
|
},
|
||||||
|
columns,
|
||||||
|
formConfig: {
|
||||||
|
labelWidth: 120,
|
||||||
|
schemas: searchFormSchema,
|
||||||
|
},
|
||||||
|
pagination: false,
|
||||||
|
striped: false,
|
||||||
|
useSearchForm: true,
|
||||||
|
showTableSetting: true,
|
||||||
|
bordered: true,
|
||||||
|
showIndexColumn: false,
|
||||||
|
canResize: false,
|
||||||
|
actionColumn: {
|
||||||
|
width: 80,
|
||||||
|
title: '操作',
|
||||||
|
dataIndex: 'action',
|
||||||
|
slots: { customRender: 'action' },
|
||||||
|
fixed: undefined,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
function handleCreate() {
|
||||||
|
openDrawer(true, {
|
||||||
|
isUpdate: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleEdit(record: Recordable) {
|
||||||
|
openDrawer(true, {
|
||||||
|
record,
|
||||||
|
isUpdate: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleDelete(record: Recordable) {
|
||||||
|
console.log(record);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleSuccess() {
|
||||||
|
reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
registerTable,
|
||||||
|
registerDrawer,
|
||||||
|
handleCreate,
|
||||||
|
handleEdit,
|
||||||
|
handleDelete,
|
||||||
|
handleSuccess,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
202
src/views/menu/menu.data.ts
Normal file
202
src/views/menu/menu.data.ts
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
import { BasicColumn } from '/@/components/Table';
|
||||||
|
import { FormSchema } from '/@/components/Table';
|
||||||
|
import { h } from 'vue';
|
||||||
|
import { Tag } from 'ant-design-vue';
|
||||||
|
import { Icon } from '/@/components/Icon';
|
||||||
|
|
||||||
|
export const columns: BasicColumn[] = [
|
||||||
|
{
|
||||||
|
title: '菜单名称',
|
||||||
|
dataIndex: 'name',
|
||||||
|
width: 200,
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '图标',
|
||||||
|
dataIndex: 'icon',
|
||||||
|
width: 50,
|
||||||
|
customRender: ({ record }) => {
|
||||||
|
return h(Icon, { icon: record.meta.icon });
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '权限标识',
|
||||||
|
dataIndex: 'permission',
|
||||||
|
width: 180,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '组件',
|
||||||
|
dataIndex: 'component',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '排序',
|
||||||
|
dataIndex: 'orderNo',
|
||||||
|
width: 50,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '状态',
|
||||||
|
dataIndex: 'status',
|
||||||
|
width: 80,
|
||||||
|
customRender: ({ record }) => {
|
||||||
|
const status = record.status;
|
||||||
|
const enable = ~~status === 1;
|
||||||
|
const color = enable ? 'green' : 'red';
|
||||||
|
const text = enable ? '启用' : '停用';
|
||||||
|
return h(Tag, { color: color }, () => text);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '创建时间',
|
||||||
|
dataIndex: 'create_at',
|
||||||
|
width: 180,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const isDir = (type: string) => type === '0';
|
||||||
|
const isMenu = (type: string) => type === '1';
|
||||||
|
const isButton = (type: string) => type === '2';
|
||||||
|
|
||||||
|
export const searchFormSchema: FormSchema[] = [
|
||||||
|
{
|
||||||
|
field: 'menuName',
|
||||||
|
label: '菜单名称',
|
||||||
|
component: 'Input',
|
||||||
|
colProps: { span: 8 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'status',
|
||||||
|
label: '状态',
|
||||||
|
component: 'Select',
|
||||||
|
componentProps: {
|
||||||
|
options: [
|
||||||
|
{ label: '启用', value: '0' },
|
||||||
|
{ label: '停用', value: '1' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
colProps: { span: 8 },
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const formSchema: FormSchema[] = [
|
||||||
|
{
|
||||||
|
field: 'type',
|
||||||
|
label: '菜单类型',
|
||||||
|
component: 'RadioButtonGroup',
|
||||||
|
defaultValue: '0',
|
||||||
|
componentProps: {
|
||||||
|
options: [
|
||||||
|
{ label: '目录', value: '0' },
|
||||||
|
{ label: '菜单', value: '1' },
|
||||||
|
{ label: '按钮', value: '2' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
colProps: { lg: 24, md: 24 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'menuName',
|
||||||
|
label: '菜单名称',
|
||||||
|
component: 'Input',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
field: 'parentMenu',
|
||||||
|
label: '上级菜单',
|
||||||
|
component: 'TreeSelect',
|
||||||
|
componentProps: {
|
||||||
|
replaceFields: {
|
||||||
|
title: 'menuName',
|
||||||
|
key: 'id',
|
||||||
|
value: 'id',
|
||||||
|
},
|
||||||
|
getPopupContainer: () => document.body,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
field: 'orderNo',
|
||||||
|
label: '排序',
|
||||||
|
component: 'InputNumber',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'icon',
|
||||||
|
label: '图标',
|
||||||
|
component: 'IconPicker',
|
||||||
|
required: true,
|
||||||
|
show: ({ values }) => !isButton(values.type),
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
field: 'routePath',
|
||||||
|
label: '路由地址',
|
||||||
|
component: 'Input',
|
||||||
|
required: true,
|
||||||
|
show: ({ values }) => !isButton(values.type),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'component',
|
||||||
|
label: '组件路径',
|
||||||
|
component: 'Input',
|
||||||
|
show: ({ values }) => isMenu(values.type),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'permission',
|
||||||
|
label: '权限标识',
|
||||||
|
component: 'Input',
|
||||||
|
show: ({ values }) => !isDir(values.type),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'status',
|
||||||
|
label: '状态',
|
||||||
|
component: 'RadioButtonGroup',
|
||||||
|
defaultValue: '0',
|
||||||
|
componentProps: {
|
||||||
|
options: [
|
||||||
|
{ label: '启用', value: '0' },
|
||||||
|
{ label: '禁用', value: '1' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'isExt',
|
||||||
|
label: '是否外链',
|
||||||
|
component: 'RadioButtonGroup',
|
||||||
|
defaultValue: '0',
|
||||||
|
componentProps: {
|
||||||
|
options: [
|
||||||
|
{ label: '否', value: '0' },
|
||||||
|
{ label: '是', value: '1' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
show: ({ values }) => !isButton(values.type),
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
field: 'keepalive',
|
||||||
|
label: '是否缓存',
|
||||||
|
component: 'RadioButtonGroup',
|
||||||
|
defaultValue: '0',
|
||||||
|
componentProps: {
|
||||||
|
options: [
|
||||||
|
{ label: '否', value: '0' },
|
||||||
|
{ label: '是', value: '1' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
show: ({ values }) => isMenu(values.type),
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
field: 'show',
|
||||||
|
label: '是否显示',
|
||||||
|
component: 'RadioButtonGroup',
|
||||||
|
defaultValue: '0',
|
||||||
|
componentProps: {
|
||||||
|
options: [
|
||||||
|
{ label: '是', value: '0' },
|
||||||
|
{ label: '否', value: '1' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
show: ({ values }) => !isButton(values.type),
|
||||||
|
},
|
||||||
|
];
|
84
src/views/role/RoleDrawer.vue
Normal file
84
src/views/role/RoleDrawer.vue
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
<template>
|
||||||
|
<BasicDrawer
|
||||||
|
v-bind="$attrs"
|
||||||
|
@register="registerDrawer"
|
||||||
|
showFooter
|
||||||
|
:title="getTitle"
|
||||||
|
width="500px"
|
||||||
|
@ok="handleSubmit"
|
||||||
|
>
|
||||||
|
<BasicForm @register="registerForm">
|
||||||
|
<template #menu="{ model, field }">
|
||||||
|
<BasicTree
|
||||||
|
v-model:value="model[field]"
|
||||||
|
:treeData="treeData"
|
||||||
|
:replaceFields="{ title: 'menuName', key: 'id' }"
|
||||||
|
checkable
|
||||||
|
toolbar
|
||||||
|
title="菜单分配"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</BasicForm>
|
||||||
|
</BasicDrawer>
|
||||||
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent, ref, computed, unref } from 'vue';
|
||||||
|
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||||
|
import { formSchema } from './role.data';
|
||||||
|
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
|
||||||
|
import { BasicTree, TreeItem } from '/@/components/Tree';
|
||||||
|
|
||||||
|
import { getMenuList } from '/@/api/demo/system';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'RoleDrawer',
|
||||||
|
components: { BasicDrawer, BasicForm, BasicTree },
|
||||||
|
emits: ['success', 'register'],
|
||||||
|
setup(_, { emit }) {
|
||||||
|
const isUpdate = ref(true);
|
||||||
|
const treeData = ref<TreeItem[]>([]);
|
||||||
|
|
||||||
|
const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
|
||||||
|
labelWidth: 90,
|
||||||
|
schemas: formSchema,
|
||||||
|
showActionButtonGroup: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
|
||||||
|
resetFields();
|
||||||
|
setDrawerProps({ confirmLoading: false });
|
||||||
|
isUpdate.value = !!data?.isUpdate;
|
||||||
|
|
||||||
|
if (unref(isUpdate)) {
|
||||||
|
setFieldsValue({
|
||||||
|
...data.record,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
treeData.value = (await getMenuList()) as any as TreeItem[];
|
||||||
|
});
|
||||||
|
|
||||||
|
const getTitle = computed(() => (!unref(isUpdate) ? '新增角色' : '编辑角色'));
|
||||||
|
|
||||||
|
async function handleSubmit() {
|
||||||
|
try {
|
||||||
|
const values = await validate();
|
||||||
|
setDrawerProps({ confirmLoading: true });
|
||||||
|
// TODO custom api
|
||||||
|
console.log(values);
|
||||||
|
closeDrawer();
|
||||||
|
emit('success');
|
||||||
|
} finally {
|
||||||
|
setDrawerProps({ confirmLoading: false });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
registerDrawer,
|
||||||
|
registerForm,
|
||||||
|
getTitle,
|
||||||
|
handleSubmit,
|
||||||
|
treeData,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
101
src/views/role/index.vue
Normal file
101
src/views/role/index.vue
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<BasicTable @register="registerTable">
|
||||||
|
<template #toolbar>
|
||||||
|
<a-button type="primary" @click="handleCreate"> 新增角色 </a-button>
|
||||||
|
</template>
|
||||||
|
<template #action="{ record }">
|
||||||
|
<TableAction
|
||||||
|
:actions="[
|
||||||
|
{
|
||||||
|
icon: 'clarity:note-edit-line',
|
||||||
|
onClick: handleEdit.bind(null, record),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'ant-design:delete-outlined',
|
||||||
|
color: 'error',
|
||||||
|
popConfirm: {
|
||||||
|
title: '是否确认删除',
|
||||||
|
confirm: handleDelete.bind(null, record),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</BasicTable>
|
||||||
|
<RoleDrawer @register="registerDrawer" @success="handleSuccess" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
|
import { BasicTable, useTable, TableAction } from '/@/components/Table';
|
||||||
|
|
||||||
|
import { useDrawer } from '/@/components/Drawer';
|
||||||
|
import RoleDrawer from './RoleDrawer.vue';
|
||||||
|
|
||||||
|
import { columns, searchFormSchema } from './role.data';
|
||||||
|
import { Curd } from '/@/api/Curd';
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'RoleManagement',
|
||||||
|
components: { BasicTable, RoleDrawer, TableAction },
|
||||||
|
setup() {
|
||||||
|
const [registerDrawer, { openDrawer }] = useDrawer();
|
||||||
|
const [registerTable, { reload }] = useTable({
|
||||||
|
title: '角色列表',
|
||||||
|
api: Curd,
|
||||||
|
beforeFetch: (v) => {
|
||||||
|
v.i = 'role';
|
||||||
|
v.a = 'list';
|
||||||
|
return v;
|
||||||
|
},
|
||||||
|
columns,
|
||||||
|
formConfig: {
|
||||||
|
labelWidth: 120,
|
||||||
|
schemas: searchFormSchema,
|
||||||
|
},
|
||||||
|
useSearchForm: true,
|
||||||
|
showTableSetting: true,
|
||||||
|
bordered: true,
|
||||||
|
showIndexColumn: false,
|
||||||
|
actionColumn: {
|
||||||
|
width: 80,
|
||||||
|
title: '操作',
|
||||||
|
dataIndex: 'action',
|
||||||
|
slots: { customRender: 'action' },
|
||||||
|
fixed: undefined,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
function handleCreate() {
|
||||||
|
openDrawer(true, {
|
||||||
|
isUpdate: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleEdit(record: Recordable) {
|
||||||
|
openDrawer(true, {
|
||||||
|
record,
|
||||||
|
isUpdate: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleDelete(record: Recordable) {
|
||||||
|
console.log(record);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleSuccess() {
|
||||||
|
reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
registerTable,
|
||||||
|
registerDrawer,
|
||||||
|
handleCreate,
|
||||||
|
handleEdit,
|
||||||
|
handleDelete,
|
||||||
|
handleSuccess,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
69
src/views/role/role.data.ts
Normal file
69
src/views/role/role.data.ts
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
import { BasicColumn } from '/@/components/Table';
|
||||||
|
import { FormSchema } from '/@/components/Table';
|
||||||
|
|
||||||
|
export const columns: BasicColumn[] = [
|
||||||
|
{
|
||||||
|
title: '角色名称',
|
||||||
|
dataIndex: 'name',
|
||||||
|
width: 200,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const searchFormSchema: FormSchema[] = [
|
||||||
|
{
|
||||||
|
field: 'roleNme',
|
||||||
|
label: '角色名称',
|
||||||
|
component: 'Input',
|
||||||
|
colProps: { span: 8 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'status',
|
||||||
|
label: '状态',
|
||||||
|
component: 'Select',
|
||||||
|
componentProps: {
|
||||||
|
options: [
|
||||||
|
{ label: '启用', value: '0' },
|
||||||
|
{ label: '停用', value: '1' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
colProps: { span: 8 },
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const formSchema: FormSchema[] = [
|
||||||
|
{
|
||||||
|
field: 'roleName',
|
||||||
|
label: '角色名称',
|
||||||
|
required: true,
|
||||||
|
component: 'Input',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'roleValue',
|
||||||
|
label: '角色值',
|
||||||
|
required: true,
|
||||||
|
component: 'Input',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'status',
|
||||||
|
label: '状态',
|
||||||
|
component: 'RadioButtonGroup',
|
||||||
|
defaultValue: '0',
|
||||||
|
componentProps: {
|
||||||
|
options: [
|
||||||
|
{ label: '启用', value: '0' },
|
||||||
|
{ label: '停用', value: '1' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '备注',
|
||||||
|
field: 'remark',
|
||||||
|
component: 'InputTextArea',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: ' ',
|
||||||
|
field: 'menu',
|
||||||
|
slot: 'menu',
|
||||||
|
component: 'Input',
|
||||||
|
},
|
||||||
|
];
|
@ -1,8 +1,20 @@
|
|||||||
<template>
|
<template>
|
||||||
<LoginFormTitle v-show="getShow" class="enter-x" />
|
<LoginFormTitle v-show="getShow" class="enter-x" />
|
||||||
<Form class="p-4 enter-x" :model="formData" :rules="getFormRules" ref="formRef" v-show="getShow">
|
<Form
|
||||||
|
class="p-4 enter-x"
|
||||||
|
:model="formData"
|
||||||
|
:rules="getFormRules"
|
||||||
|
ref="formRef"
|
||||||
|
v-show="getShow"
|
||||||
|
@keypress.enter="handleLogin"
|
||||||
|
>
|
||||||
<FormItem name="account" class="enter-x">
|
<FormItem name="account" class="enter-x">
|
||||||
<Input size="large" v-model:value="formData.account" :placeholder="t('sys.login.userName')" />
|
<Input
|
||||||
|
size="large"
|
||||||
|
v-model:value="formData.account"
|
||||||
|
:placeholder="t('sys.login.userName')"
|
||||||
|
class="fix-auto-fill"
|
||||||
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
<FormItem name="password" class="enter-x">
|
<FormItem name="password" class="enter-x">
|
||||||
<InputPassword
|
<InputPassword
|
||||||
@ -107,7 +119,7 @@
|
|||||||
const rememberMe = ref(false);
|
const rememberMe = ref(false);
|
||||||
|
|
||||||
const formData = reactive({
|
const formData = reactive({
|
||||||
account: 'vben',
|
account: 'admin',
|
||||||
password: '123456',
|
password: '123456',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user