feat: 对接系统配置中的组织架构90%
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
# 开发环境配置
|
# 开发环境配置
|
||||||
VITE_APP_TITLE=租赁管理系统
|
VITE_APP_TITLE=租赁管理系统
|
||||||
VITE_API_BASE_URL=http://localhost:9500/api/
|
VITE_API_BASE_URL=https://go.kola.work/api
|
||||||
VITE_APP_MODE=development
|
VITE_APP_MODE=development
|
||||||
|
|
||||||
# 调试相关
|
# 调试相关
|
||||||
|
|||||||
+17
-3
@@ -1,6 +1,6 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import type { RouteRecordNormalized } from 'vue-router';
|
// import type { RouteRecordNormalized } from 'vue-router';
|
||||||
import { UserState } from '@/store/modules/user/types';
|
// import { UserState } from '@/store/modules/user/types';
|
||||||
|
|
||||||
export interface ProjectRecord {
|
export interface ProjectRecord {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -11,4 +11,18 @@ export interface ProjectRecord {
|
|||||||
export interface ProjectParams extends Partial<ProjectRecord> {
|
export interface ProjectParams extends Partial<ProjectRecord> {
|
||||||
current: number;
|
current: number;
|
||||||
pageSize: number;
|
pageSize: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 全部项目列表
|
||||||
|
export function getAllProjectList() {
|
||||||
|
return axios.get<any>('/project/getAllProjectList');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 项目信息
|
||||||
|
export function getProjectDetail(id: string) {
|
||||||
|
return axios.get<any>(`/project/getProject?id=${id}`);
|
||||||
|
}
|
||||||
|
// 项目列表(分页)
|
||||||
|
export function queryPolicyList(params: ProjectParams) {
|
||||||
|
return axios.post<any>('/project/getProjectList', { params });
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,103 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import { HttpResponse } from './interceptor';
|
||||||
|
|
||||||
|
export interface DepartmentFormParams {
|
||||||
|
parent_id: number | null;
|
||||||
|
name: string;
|
||||||
|
leaderId?: number;
|
||||||
|
remark?: string;
|
||||||
|
id?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DepartmentIdData {
|
||||||
|
departmentId: number | string;
|
||||||
|
}
|
||||||
|
type DepartmentFormRes = HttpResponse<DepartmentIdData>;
|
||||||
|
|
||||||
|
export interface DepartmentItem {
|
||||||
|
id: number;
|
||||||
|
systemTenantId: number;
|
||||||
|
name: string;
|
||||||
|
parentId: number;
|
||||||
|
UserId: number;
|
||||||
|
level: number;
|
||||||
|
path: string;
|
||||||
|
remark: string;
|
||||||
|
isDelete: number;
|
||||||
|
createdAt: string;
|
||||||
|
updatedAt: string;
|
||||||
|
sort: number;
|
||||||
|
children?: DepartmentItem[]; // 递归结构
|
||||||
|
isShowEditIcon?: boolean; // 是否展示编辑icon
|
||||||
|
username?: string;
|
||||||
|
parentName?: string;
|
||||||
|
}
|
||||||
|
export type DepartmentList = DepartmentItem[];
|
||||||
|
export type DepartmentListRes = HttpResponse<{
|
||||||
|
departmentList: DepartmentItem[];
|
||||||
|
}>;
|
||||||
|
export interface DepartmentDetailData {
|
||||||
|
department: DepartmentItem;
|
||||||
|
}
|
||||||
|
export type DepartmentDetailRes = HttpResponse<DepartmentDetailData>;
|
||||||
|
|
||||||
|
// 创建部门
|
||||||
|
export function createDepartment(
|
||||||
|
params: DepartmentFormParams
|
||||||
|
): Promise<DepartmentFormRes> {
|
||||||
|
return axios.post('/department/createDepartment', params);
|
||||||
|
}
|
||||||
|
// 获取部门列表
|
||||||
|
export function getDepartmentList(): Promise<DepartmentListRes> {
|
||||||
|
return axios.get('/department/getDepartmentList');
|
||||||
|
}
|
||||||
|
// 更新(编辑)部门
|
||||||
|
export function updateDepartment(
|
||||||
|
params: DepartmentFormParams
|
||||||
|
): Promise<DepartmentFormRes> {
|
||||||
|
return axios.post('/department/updateDepartment', params);
|
||||||
|
}
|
||||||
|
export function getDepartmentDetail(id: number): Promise<DepartmentDetailRes> {
|
||||||
|
return axios.get(`/department/getDepartment?id=${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UserItem {
|
||||||
|
id: number; // 用户id
|
||||||
|
username: string; // 用户名称
|
||||||
|
realname: string; // 姓名
|
||||||
|
email: string; // 邮箱
|
||||||
|
tel: string; // 手机号
|
||||||
|
status: 1 | 2; // 状态:1 启用,2 禁用
|
||||||
|
role_id: number; // 角色id
|
||||||
|
department_id: number; // 部门id
|
||||||
|
role_name: string; // 角色名称
|
||||||
|
dept_name: string; // 部门名称
|
||||||
|
lastLoginTime: string; // 最后登录时间
|
||||||
|
}
|
||||||
|
export type UserList = UserItem[];
|
||||||
|
export type UserListRes = HttpResponse<UserList>;
|
||||||
|
|
||||||
|
// 后台-用户列表(除主管外所有用户)
|
||||||
|
export function getAllUserList(params): Promise<UserListRes> {
|
||||||
|
return axios.post('/user/getAllUserList', params);
|
||||||
|
}
|
||||||
|
// 部门-向上移动
|
||||||
|
export function departmentSetUp(id: number): Promise<HttpResponse> {
|
||||||
|
return axios.get(`/department/setUp?id=${id}`);
|
||||||
|
}
|
||||||
|
// 部门-向下移动
|
||||||
|
export function departmentSetDown(id: number): Promise<HttpResponse> {
|
||||||
|
return axios.get(`/department/setDown?id=${id}`);
|
||||||
|
}
|
||||||
|
// 删除部门
|
||||||
|
export function delDepartment(id: number): Promise<HttpResponse> {
|
||||||
|
return axios.get(`/department/delDepartment?id=${id}`);
|
||||||
|
}
|
||||||
|
// // 项目信息
|
||||||
|
// export function getProjectDetail(id: string) {
|
||||||
|
// return axios.get<any>(`/project/getProject?id=${id}`);
|
||||||
|
// }
|
||||||
|
// // 项目列表(分页)
|
||||||
|
// export function queryPolicyList(params: ProjectParams) {
|
||||||
|
// return axios.post<any>('/project/getProjectList', { params });
|
||||||
|
// }
|
||||||
@@ -13,36 +13,131 @@ body {
|
|||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
}
|
}
|
||||||
|
// reset.less - 通用 CSS Reset 初始化样式
|
||||||
|
*,
|
||||||
|
*::before,
|
||||||
|
*::after {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
article,
|
||||||
|
aside,
|
||||||
|
details,
|
||||||
|
figcaption,
|
||||||
|
figure,
|
||||||
|
footer,
|
||||||
|
header,
|
||||||
|
main,
|
||||||
|
menu,
|
||||||
|
nav,
|
||||||
|
section,
|
||||||
|
summary {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.5;
|
||||||
|
text-size-adjust: 100%;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul,
|
||||||
|
ol {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
background-color: transparent;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
img,
|
||||||
|
video {
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
vertical-align: middle;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
button,
|
||||||
|
input,
|
||||||
|
select,
|
||||||
|
textarea {
|
||||||
|
font: inherit;
|
||||||
|
color: inherit;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
appearance: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
cursor: pointer;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
border-spacing: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type='search'] {
|
||||||
|
appearance: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 常用隐藏类
|
||||||
|
.hide {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 通用字体加粗
|
||||||
|
.bold {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
.echarts-tooltip-diy {
|
.echarts-tooltip-diy {
|
||||||
background: linear-gradient(
|
background: linear-gradient(
|
||||||
304.17deg,
|
304.17deg,
|
||||||
rgba(253, 254, 255, 0.6) -6.04%,
|
rgb(253 254 255 / 60%) -6.04%,
|
||||||
rgba(244, 247, 252, 0.6) 85.2%
|
rgb(244 247 252 / 60%) 85.2%
|
||||||
) !important;
|
) !important;
|
||||||
border: none !important;
|
border: none !important;
|
||||||
backdrop-filter: blur(10px) !important;
|
backdrop-filter: blur(10px) !important;
|
||||||
|
|
||||||
/* Note: backdrop-filter has minimal browser support */
|
/* Note: backdrop-filter has minimal browser support */
|
||||||
|
|
||||||
border-radius: 6px !important;
|
border-radius: 6px !important;
|
||||||
|
|
||||||
.content-panel {
|
.content-panel {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding: 0 9px;
|
padding: 0 9px;
|
||||||
background: rgba(255, 255, 255, 0.8);
|
background: rgb(255 255 255 / 80%);
|
||||||
width: 164px;
|
width: 164px;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
line-height: 32px;
|
line-height: 32px;
|
||||||
box-shadow: 6px 0px 20px rgba(34, 87, 188, 0.1);
|
box-shadow: 6px 0 20px rgb(34 87 188 / 10%);
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
margin-bottom: 4px;
|
margin-bottom: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tooltip-title {
|
.tooltip-title {
|
||||||
margin: 0 0 10px 0;
|
margin: 0 0 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tooltip-title,
|
.tooltip-title,
|
||||||
.tooltip-value {
|
.tooltip-value {
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
@@ -53,6 +148,7 @@ body {
|
|||||||
color: #1d2129;
|
color: #1d2129;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tooltip-item-icon {
|
.tooltip-item-icon {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-right: 8px;
|
margin-right: 8px;
|
||||||
@@ -65,13 +161,15 @@ body {
|
|||||||
.general-card {
|
.general-card {
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
border: none;
|
border: none;
|
||||||
|
|
||||||
& > .arco-card-header {
|
& > .arco-card-header {
|
||||||
height: auto;
|
height: auto;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
& > .arco-card-body {
|
& > .arco-card-body {
|
||||||
padding: 0 20px 20px 20px;
|
padding: 0 20px 20px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,18 +185,26 @@ body {
|
|||||||
height: 6px;
|
height: 6px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background-color: rgb(var(--blue-6));
|
background-color: rgb(var(--blue-6));
|
||||||
|
|
||||||
&.pass {
|
&.pass {
|
||||||
background-color: rgb(var(--green-6));
|
background-color: rgb(var(--green-6));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.flex_center_between{
|
|
||||||
|
.flex_center_between {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
.card-title_between{
|
|
||||||
|
.card-title_between {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.full_height {
|
||||||
|
/* 56为面包屑高度 58为头部layout高度 20为内容padding */
|
||||||
|
min-height: calc(100vh - 56px - 58px - 20px);
|
||||||
|
}
|
||||||
|
|||||||
@@ -116,7 +116,7 @@
|
|||||||
const paddingStyle = computed(() => {
|
const paddingStyle = computed(() => {
|
||||||
const paddingLeft =
|
const paddingLeft =
|
||||||
renderMenu.value && !hideMenu.value
|
renderMenu.value && !hideMenu.value
|
||||||
? { paddingLeft: `${menuWidth.value + 10}px` }
|
? { paddingLeft: `${menuWidth.value + 18}px` }
|
||||||
: {};
|
: {};
|
||||||
const paddingTop = navbar.value ? { paddingTop: navbarHeight } : {};
|
const paddingTop = navbar.value ? { paddingTop: navbarHeight } : {};
|
||||||
return { ...paddingLeft, ...paddingTop };
|
return { ...paddingLeft, ...paddingTop };
|
||||||
|
|||||||
+40
-12
@@ -5,18 +5,13 @@ import localeWorkplace from '@/views/dashboard/workplace/locale/zh-CN';
|
|||||||
|
|
||||||
import localeMonitor from '@/views/dashboard/monitor/locale/zh-CN';
|
import localeMonitor from '@/views/dashboard/monitor/locale/zh-CN';
|
||||||
|
|
||||||
|
|
||||||
import locale403 from '@/views/exception/403/locale/zh-CN';
|
import locale403 from '@/views/exception/403/locale/zh-CN';
|
||||||
import locale404 from '@/views/exception/404/locale/zh-CN';
|
import locale404 from '@/views/exception/404/locale/zh-CN';
|
||||||
import locale500 from '@/views/exception/500/locale/zh-CN';
|
import locale500 from '@/views/exception/500/locale/zh-CN';
|
||||||
|
|
||||||
|
|
||||||
import localeSettings from './zh-CN/settings';
|
|
||||||
|
|
||||||
import localeBusiness from '@/views/business/locale/zh-CN';
|
|
||||||
import localeFinance from '@/views/finance/locale/zh-CN';
|
import localeFinance from '@/views/finance/locale/zh-CN';
|
||||||
import localeProperty from '@/views/property/locale/zh-CN';
|
import localeProperty from '@/views/property/locale/zh-CN';
|
||||||
import localeSetting from '@/views/setting/locale/zh-CN';
|
import localeSettings from './zh-CN/settings';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
'menu.dashboard': '仪表盘',
|
'menu.dashboard': '仪表盘',
|
||||||
@@ -35,14 +30,49 @@ export default {
|
|||||||
'navbar.docs': '文档中心',
|
'navbar.docs': '文档中心',
|
||||||
'navbar.action.locale': '切换为中文',
|
'navbar.action.locale': '切换为中文',
|
||||||
|
|
||||||
|
// 翻译
|
||||||
'menu.business': '业务',
|
'menu.business': '业务',
|
||||||
'menu.finance': '财务',
|
'menu.finance': '财务',
|
||||||
'menu.property': '物业',
|
'menu.property': '物业',
|
||||||
'menu.setting': '设置',
|
'menu.setting': '设置',
|
||||||
|
'search.placeholder': '请输入内容',
|
||||||
'search.placeholder':'请输入内容',
|
'table.filter': '筛选',
|
||||||
'table.filter':'筛选',
|
'table.export': '导出',
|
||||||
'table.export':'导出',
|
'watch-detail': '查看详情',
|
||||||
|
'menu.business.project': '项目管理',
|
||||||
|
'menu.business.space': '空间管理',
|
||||||
|
'menu.business.house-view': '房源剖视',
|
||||||
|
'menu.business.house-list': '房源列表',
|
||||||
|
'menu.business.contract': '合同管理',
|
||||||
|
'menu.business.contract-list': '合同列表',
|
||||||
|
'menu.business.contract-file': '合同归档',
|
||||||
|
'menu.business.contract-template': '合同模板',
|
||||||
|
'menu.business.tenant': '租客管理',
|
||||||
|
'menu.business.tenant-list': '租客列表',
|
||||||
|
'menu.business.tenant.contacts': '租客联系人',
|
||||||
|
'add-project': '新建项目',
|
||||||
|
'menu.setting.user': '用户设置',
|
||||||
|
'menu.setting.user-list': '用户列表',
|
||||||
|
'menu.setting.role': '角色权限',
|
||||||
|
'menu.setting.system': '系统配置',
|
||||||
|
'organization': '组织架构',
|
||||||
|
'general-setting': '通用设置',
|
||||||
|
'security-setting': '安全设置',
|
||||||
|
'company-info': '公司信息',
|
||||||
|
'appearance-setting': '外观设置',
|
||||||
|
'add-department': '新建部门',
|
||||||
|
'department-name': '部门名称',
|
||||||
|
'belongto-department': '所属部门',
|
||||||
|
'department-head': '部门主管',
|
||||||
|
'department-desc': '部门描述',
|
||||||
|
'remark': '备注',
|
||||||
|
'confirm.delete': '确认删除',
|
||||||
|
'delete.some': '删除{name}',
|
||||||
|
'please.confirm.delete.some': '请确认是否要删除此{name}?',
|
||||||
|
'department': '部门',
|
||||||
|
'delete': '删除',
|
||||||
|
'confirm': '确定',
|
||||||
|
'cancel': '取消',
|
||||||
|
|
||||||
...localeSettings,
|
...localeSettings,
|
||||||
...localeMessageBox,
|
...localeMessageBox,
|
||||||
@@ -54,8 +84,6 @@ export default {
|
|||||||
...locale404,
|
...locale404,
|
||||||
...locale500,
|
...locale500,
|
||||||
|
|
||||||
...localeBusiness,
|
|
||||||
...localeFinance,
|
...localeFinance,
|
||||||
...localeProperty,
|
...localeProperty,
|
||||||
...localeSetting,
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
|
import PageLayout from '@/layout/page-layout.vue';
|
||||||
import { DEFAULT_LAYOUT } from '../base';
|
import { DEFAULT_LAYOUT } from '../base';
|
||||||
import { AppRouteRecordRaw } from '../types';
|
import { AppRouteRecordRaw } from '../types';
|
||||||
import PageLayout from '@/layout/page-layout.vue';
|
|
||||||
// 设置
|
// 设置
|
||||||
const SETTING: AppRouteRecordRaw = {
|
const SETTING: AppRouteRecordRaw = {
|
||||||
path: '/setting',
|
path: '/setting',
|
||||||
name: 'setting',
|
name: 'setting',
|
||||||
component: DEFAULT_LAYOUT,
|
component: DEFAULT_LAYOUT,
|
||||||
redirect: '/setting/basic',
|
redirect: '/setting/user',
|
||||||
meta: {
|
meta: {
|
||||||
locale: 'menu.setting',
|
locale: 'menu.setting',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
@@ -20,6 +20,7 @@ const SETTING: AppRouteRecordRaw = {
|
|||||||
path: 'user',
|
path: 'user',
|
||||||
name: 'user-setting',
|
name: 'user-setting',
|
||||||
component: PageLayout,
|
component: PageLayout,
|
||||||
|
redirect: '/setting/user/list',
|
||||||
meta: {
|
meta: {
|
||||||
locale: 'menu.setting.user',
|
locale: 'menu.setting.user',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
|
|||||||
@@ -22,4 +22,17 @@ export const regexUrl = new RegExp(
|
|||||||
'i'
|
'i'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export function debounce<T extends (...args: any[]) => any>(
|
||||||
|
fn: T,
|
||||||
|
delay = 300
|
||||||
|
) {
|
||||||
|
let timer: ReturnType<typeof setTimeout> | null = null;
|
||||||
|
return function (this: any, ...args: Parameters<T>) {
|
||||||
|
if (timer) clearTimeout(timer);
|
||||||
|
timer = setTimeout(() => {
|
||||||
|
fn.apply(this, args);
|
||||||
|
}, delay);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export default null;
|
export default null;
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
export default {
|
|
||||||
'menu.business.project': '项目管理',
|
|
||||||
'menu.business.space': '空间管理',
|
|
||||||
'menu.business.house-view': '房源剖视',
|
|
||||||
'menu.business.house-list': '房源列表',
|
|
||||||
'menu.business.contract': '合同管理',
|
|
||||||
'menu.business.contract-list': '合同列表',
|
|
||||||
'menu.business.contract-file': '合同归档',
|
|
||||||
'menu.business.contract-template': '合同模板',
|
|
||||||
'menu.business.tenant': '租客管理',
|
|
||||||
'menu.business.tenant-list': '租客列表',
|
|
||||||
'menu.business.tenant.contacts': '租客联系人',
|
|
||||||
'add-project': '新建项目',
|
|
||||||
};
|
|
||||||
@@ -77,6 +77,7 @@
|
|||||||
PROJECT_TYPE_COLORS,
|
PROJECT_TYPE_COLORS,
|
||||||
PROJECT_TYPE_LABELS,
|
PROJECT_TYPE_LABELS,
|
||||||
} from '@/types/business';
|
} from '@/types/business';
|
||||||
|
import { ProjectParams, getAllProjectList } from '@/api/business';
|
||||||
|
|
||||||
const { loading, setLoading } = useLoading(false);
|
const { loading, setLoading } = useLoading(false);
|
||||||
const renderData = ref<ProjectRecord[]>([
|
const renderData = ref<ProjectRecord[]>([
|
||||||
@@ -138,4 +139,17 @@
|
|||||||
pagination.current = current;
|
pagination.current = current;
|
||||||
// TODO: 这里应该调用API获取对应页码的数据
|
// TODO: 这里应该调用API获取对应页码的数据
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getAllProjectListData = async () => {
|
||||||
|
setLoading(true);
|
||||||
|
try {
|
||||||
|
const { data } = await getAllProjectList();
|
||||||
|
console.log(data, 'getAllProjectList');
|
||||||
|
} catch (err) {
|
||||||
|
// you can report use errorHandler or other
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// getAllProjectListData()
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
import { ref, onMounted } from 'vue';
|
||||||
|
import {
|
||||||
|
getDepartmentList,
|
||||||
|
DepartmentItem,
|
||||||
|
getDepartmentDetail,
|
||||||
|
} from '@/api/setting';
|
||||||
|
|
||||||
|
export default function useDepartmentList(autoFetch = true) {
|
||||||
|
const departmentListData = ref<DepartmentItem[]>([]);
|
||||||
|
const allDepartmentKeys = ref<number[]>([]);
|
||||||
|
function markNonLevel1Departments(list: DepartmentItem[]): DepartmentItem[] {
|
||||||
|
const traverse = (items: DepartmentItem[]) => {
|
||||||
|
return items.map((item) => {
|
||||||
|
const newItem: DepartmentItem = {
|
||||||
|
...item,
|
||||||
|
isShowEditIcon: false,
|
||||||
|
children: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
// 收集 ID
|
||||||
|
allDepartmentKeys.value.push(item.id);
|
||||||
|
|
||||||
|
if (item.children && item.children.length > 0) {
|
||||||
|
newItem.children = traverse(item.children);
|
||||||
|
}
|
||||||
|
|
||||||
|
return newItem;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return traverse(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
const getDepartmentListData = async () => {
|
||||||
|
try {
|
||||||
|
const { code, data } = await getDepartmentList();
|
||||||
|
if (code === 200) {
|
||||||
|
if (data?.departmentList?.length === 0) return;
|
||||||
|
allDepartmentKeys.value = []; // 清空再收集
|
||||||
|
|
||||||
|
const fetchDepartmentList = markNonLevel1Departments(
|
||||||
|
data?.departmentList
|
||||||
|
);
|
||||||
|
departmentListData.value = fetchDepartmentList;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取部门列表失败:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getDepartmentDetailData = async (
|
||||||
|
id: number
|
||||||
|
): Promise<DepartmentItem | null> => {
|
||||||
|
try {
|
||||||
|
const { code, data } = await getDepartmentDetail(id);
|
||||||
|
if (code === 200 && data?.department) {
|
||||||
|
return data.department;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取部门详情失败:', error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (autoFetch) {
|
||||||
|
onMounted(() => {
|
||||||
|
getDepartmentListData();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
departmentListData,
|
||||||
|
allDepartmentKeys,
|
||||||
|
getDepartmentListData,
|
||||||
|
getDepartmentDetailData,
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
export default {
|
|
||||||
'menu.setting.user': '用户设置',
|
|
||||||
'menu.setting.user-list': '用户列表',
|
|
||||||
'menu.setting.role': '角色权限',
|
|
||||||
'menu.setting.system': '系统配置',
|
|
||||||
};
|
|
||||||
@@ -0,0 +1,148 @@
|
|||||||
|
<template>
|
||||||
|
<a-modal
|
||||||
|
:visible="visible"
|
||||||
|
:title="isEdit ? '编辑部门' : '新增部门'"
|
||||||
|
unmount-on-close
|
||||||
|
@ok="handleSubmit"
|
||||||
|
@cancel="handleCancel"
|
||||||
|
>
|
||||||
|
<a-form
|
||||||
|
ref="formRef"
|
||||||
|
:model="form"
|
||||||
|
:rules="rules"
|
||||||
|
auto-label-width
|
||||||
|
layout="vertical"
|
||||||
|
>
|
||||||
|
<!-- 部门名称 -->
|
||||||
|
<a-form-item :label="t('department-name')" field="name" required>
|
||||||
|
<a-input v-model="form.name" placeholder="请输入部门名称" />
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<!-- 所属部门 -->
|
||||||
|
<a-form-item :label="t('belongto-department')" field="parent_id" required>
|
||||||
|
<a-tree-select
|
||||||
|
v-model="form.parent_id"
|
||||||
|
:data="departmentListData"
|
||||||
|
:field-names="{ key: 'id', title: 'name', children: 'children' }"
|
||||||
|
placeholder="请选择所属部门"
|
||||||
|
allow-clear
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<!-- 部门主管 -->
|
||||||
|
<a-form-item :label="t('department-head')" field="user_id">
|
||||||
|
<a-select
|
||||||
|
v-model="form.user_id"
|
||||||
|
:options="props.userListData"
|
||||||
|
placeholder="请选择部门主管"
|
||||||
|
allow-clear
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<!-- 备注 -->
|
||||||
|
<a-form-item :label="t('remark')" field="remark">
|
||||||
|
<a-textarea
|
||||||
|
v-model="form.remark"
|
||||||
|
placeholder="请输入备注"
|
||||||
|
allow-clear
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, reactive, watch } from 'vue';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import type { FormInstance } from '@arco-design/web-vue';
|
||||||
|
import {
|
||||||
|
createDepartment,
|
||||||
|
updateDepartment,
|
||||||
|
DepartmentItem,
|
||||||
|
UserList,
|
||||||
|
} from '@/api/setting';
|
||||||
|
import { Message } from '@arco-design/web-vue';
|
||||||
|
// Props & Emits
|
||||||
|
// interface LeaderOption {
|
||||||
|
// name: string;
|
||||||
|
// id: number;
|
||||||
|
// }
|
||||||
|
|
||||||
|
interface DepartmentForm {
|
||||||
|
id?: number;
|
||||||
|
name: string;
|
||||||
|
parent_id: number | null;
|
||||||
|
user_id?: number;
|
||||||
|
remark?: string;
|
||||||
|
}
|
||||||
|
const props = defineProps<{
|
||||||
|
visible: boolean;
|
||||||
|
isEdit: boolean;
|
||||||
|
record?: DepartmentItem | null;
|
||||||
|
departmentListData: any[]; // 新增
|
||||||
|
userListData: UserList;
|
||||||
|
}>();
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'update:visible', val: boolean): void;
|
||||||
|
(e: 'submitted'): void;
|
||||||
|
}>();
|
||||||
|
// 表单数据
|
||||||
|
const formRef = ref<FormInstance>();
|
||||||
|
const form = reactive<DepartmentForm>({
|
||||||
|
name: '',
|
||||||
|
parent_id: null,
|
||||||
|
user_id: undefined,
|
||||||
|
remark: '',
|
||||||
|
id: undefined,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
// 校验规则
|
||||||
|
const rules = {
|
||||||
|
name: [{ required: true, message: '请输入部门名称' }],
|
||||||
|
parent_id: [{ required: true, message: '请选择所属部门' }],
|
||||||
|
};
|
||||||
|
|
||||||
|
// Watch 弹窗控制 & 初始化
|
||||||
|
watch(
|
||||||
|
() => props.visible,
|
||||||
|
(val) => {
|
||||||
|
if (val) {
|
||||||
|
if (props.record) {
|
||||||
|
form.id = props.record?.id;
|
||||||
|
form.name = props.record?.name;
|
||||||
|
form.parent_id = props.record?.parentId ?? '';
|
||||||
|
form.user_id = props.record?.UserId ?? '';
|
||||||
|
form.remark = props.record?.remark ?? '';
|
||||||
|
// Object.assign(form, props.record);
|
||||||
|
} else {
|
||||||
|
Object.assign(form, {
|
||||||
|
id: undefined,
|
||||||
|
name: '',
|
||||||
|
parent_id: null,
|
||||||
|
user_id: undefined,
|
||||||
|
remark: '',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
// 表单事件
|
||||||
|
const handleCancel = () => {
|
||||||
|
emit('update:visible', false);
|
||||||
|
};
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
await formRef.value?.validate();
|
||||||
|
const { code, message } = props.isEdit
|
||||||
|
? await updateDepartment(form)
|
||||||
|
: await createDepartment(form);
|
||||||
|
if (code === 200) {
|
||||||
|
Message.success(message);
|
||||||
|
handleCancel();
|
||||||
|
// 通知父组件更新部门列表数据
|
||||||
|
emit('submitted');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -1,3 +1,82 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>帅哥kilo</div>
|
<div class="setting_user_list">
|
||||||
|
<Breadcrumb :items="['menu.setting', 'menu.setting.system']" />
|
||||||
|
<a-row :gutter="12">
|
||||||
|
<a-col flex="310px">
|
||||||
|
<a-card
|
||||||
|
class="full_height"
|
||||||
|
:bordered="false"
|
||||||
|
:title="$t('menu.setting.system')"
|
||||||
|
>
|
||||||
|
<ul class="system_setting_list">
|
||||||
|
<li
|
||||||
|
v-for="item in systemSettingList"
|
||||||
|
:key="item.id"
|
||||||
|
:class="[
|
||||||
|
'system_setting_item',
|
||||||
|
{ active: currentActive === item.id },
|
||||||
|
]"
|
||||||
|
@click="handleChooseSystemItem(item.id)"
|
||||||
|
>
|
||||||
|
<component :is="item.icon" class="mr-2" />
|
||||||
|
<p class="name">{{ item.name }}</p>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</a-card>
|
||||||
|
</a-col>
|
||||||
|
<a-col flex="auto">
|
||||||
|
<organization v-if="currentActive === 4" />
|
||||||
|
<div v-else>开发中{{ currentActive }}</div>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import {
|
||||||
|
IconSettings,
|
||||||
|
IconSafe,
|
||||||
|
IconPaste,
|
||||||
|
IconFullscreen,
|
||||||
|
IconTiktokColor,
|
||||||
|
} from '@arco-design/web-vue/es/icon';
|
||||||
|
import organization from './organization.vue';
|
||||||
|
// import { CreateDepartmentParams, createDepartment, getDepartmentList, DepartmentItem } from '@/api/setting'
|
||||||
|
const { t } = useI18n();
|
||||||
|
const currentActive = ref(4);
|
||||||
|
const systemSettingList = [
|
||||||
|
{ id: 1, name: t('general-setting'), icon: IconSettings },
|
||||||
|
{ id: 2, name: t('security-setting'), icon: IconSafe },
|
||||||
|
{ id: 3, name: t('company-info'), icon: IconPaste },
|
||||||
|
{ id: 4, name: t('organization'), icon: IconFullscreen },
|
||||||
|
{ id: 5, name: t('appearance-setting'), icon: IconTiktokColor },
|
||||||
|
];
|
||||||
|
const handleChooseSystemItem = (id: number) => {
|
||||||
|
currentActive.value = id;
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.setting_user_list {
|
||||||
|
.system_setting_list {
|
||||||
|
.system_setting_item {
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 8px;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background-color: #efefef;
|
||||||
|
}
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.name {
|
||||||
|
margin-left: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -0,0 +1,234 @@
|
|||||||
|
<template>
|
||||||
|
<a-card class="full_height" :bordered="false">
|
||||||
|
<template #title>
|
||||||
|
<div class="card-title_between">
|
||||||
|
<p>
|
||||||
|
<icon-drag-arrow />
|
||||||
|
<span class="title" style="margin-left: 15px">{{
|
||||||
|
$t('organization')
|
||||||
|
}}</span>
|
||||||
|
</p>
|
||||||
|
<a-button type="primary" @click="handleAdd">
|
||||||
|
<template #icon>
|
||||||
|
<icon-plus />
|
||||||
|
</template>
|
||||||
|
{{ $t('add-department') }}
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<a-row :gutter="12">
|
||||||
|
<a-col class="border" :span="12">
|
||||||
|
<a-tree
|
||||||
|
v-model:expanded-keys="expandedKeys"
|
||||||
|
:field-names="{ key: 'id', title: 'name' }"
|
||||||
|
:data="departmentListData"
|
||||||
|
@select="onSelect"
|
||||||
|
>
|
||||||
|
<template #icon>
|
||||||
|
<IconStar />
|
||||||
|
</template>
|
||||||
|
<template #extra="nodeData">
|
||||||
|
<a-row
|
||||||
|
v-if="nodeData.isShowEditIcon"
|
||||||
|
style="position: absolute; right: 0"
|
||||||
|
:gutter="24"
|
||||||
|
>
|
||||||
|
<a-col :span="4" @click="handleEdit"><icon-edit /></a-col>
|
||||||
|
<a-col :span="4">
|
||||||
|
<a-popconfirm
|
||||||
|
:ok-text="t('cancel')"
|
||||||
|
:cancel-text="t('delete')"
|
||||||
|
:ok-button-props="{ type: 'outline' }"
|
||||||
|
:cancel-button-props="{ type: 'primary', status: 'danger' }"
|
||||||
|
:content="
|
||||||
|
t('please.confirm.delete.some', { name: t('department') })
|
||||||
|
"
|
||||||
|
type="error"
|
||||||
|
@cancel="handleDelete(nodeData)"
|
||||||
|
>
|
||||||
|
<icon-delete />
|
||||||
|
</a-popconfirm>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="4" @click="handleMoveUp(nodeData)"
|
||||||
|
><icon-up
|
||||||
|
/></a-col>
|
||||||
|
<a-col :span="4" @click="handleMoveDown(nodeData)"
|
||||||
|
><icon-down
|
||||||
|
/></a-col>
|
||||||
|
</a-row>
|
||||||
|
</template>
|
||||||
|
</a-tree>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-descriptions
|
||||||
|
v-if="departmentDetailInfo"
|
||||||
|
:column="1"
|
||||||
|
layout="horizontal"
|
||||||
|
bordered
|
||||||
|
>
|
||||||
|
<a-descriptions-item :label="t('department-name')">
|
||||||
|
{{ departmentDetailInfo.name }}</a-descriptions-item
|
||||||
|
>
|
||||||
|
<a-descriptions-item :label="t('belongto-department')">
|
||||||
|
{{ departmentDetailInfo.parentName || '-' }}</a-descriptions-item
|
||||||
|
>
|
||||||
|
<a-descriptions-item :label="t('department-head')">
|
||||||
|
{{ departmentDetailInfo.username || '-' }}</a-descriptions-item
|
||||||
|
>
|
||||||
|
<a-descriptions-item :label="t('department-desc')">
|
||||||
|
{{ departmentDetailInfo.remark }}</a-descriptions-item
|
||||||
|
>
|
||||||
|
</a-descriptions>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
<departmentFormModal
|
||||||
|
v-model:visible="showModal"
|
||||||
|
:department-list-data="departmentListData"
|
||||||
|
:record="departmentDetailInfo"
|
||||||
|
:user-list-data="allUserList"
|
||||||
|
:is-edit="isEdit"
|
||||||
|
@submitted="getDepartmentListData"
|
||||||
|
/>
|
||||||
|
</a-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { reactive, ref, watch, onMounted } from 'vue';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import useDepartmentList from '@/views/setting/composables/useDepartmentList';
|
||||||
|
import {
|
||||||
|
DepartmentItem,
|
||||||
|
getAllUserList,
|
||||||
|
UserList,
|
||||||
|
departmentSetUp,
|
||||||
|
departmentSetDown,
|
||||||
|
delDepartment,
|
||||||
|
} from '@/api/setting';
|
||||||
|
import { debounce } from '@/utils';
|
||||||
|
import { Message } from '@arco-design/web-vue';
|
||||||
|
import departmentFormModal from './components/department-form-modal.vue';
|
||||||
|
|
||||||
|
const {
|
||||||
|
departmentListData,
|
||||||
|
allDepartmentKeys,
|
||||||
|
getDepartmentListData,
|
||||||
|
getDepartmentDetailData,
|
||||||
|
} = useDepartmentList();
|
||||||
|
const emit = defineEmits(['onSelectTree']);
|
||||||
|
const expandedKeys = ref<(string | number)[]>([]);
|
||||||
|
const { t } = useI18n();
|
||||||
|
watch(
|
||||||
|
allDepartmentKeys,
|
||||||
|
(val) => {
|
||||||
|
expandedKeys.value = val;
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
const showModal = ref<boolean>(false);
|
||||||
|
const isEdit = ref<boolean>(false);
|
||||||
|
const departmentDetailInfo = ref<DepartmentItem | null>(null);
|
||||||
|
|
||||||
|
const resetEditIcon = (nodes: any[]) => {
|
||||||
|
nodes.forEach((node) => {
|
||||||
|
node.isShowEditIcon = false;
|
||||||
|
if (node.children && node.children.length > 0) {
|
||||||
|
resetEditIcon(node.children);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const currentNode = ref<any>(null);
|
||||||
|
const onSelect = debounce(async (_: (string | number)[], event: any) => {
|
||||||
|
const { node } = event;
|
||||||
|
if (node.id === currentNode.value?.id) return;
|
||||||
|
currentNode.value = node;
|
||||||
|
// 递归重置所有节点的 isShowEditIcon
|
||||||
|
resetEditIcon(departmentListData.value);
|
||||||
|
// 只设置当前节点
|
||||||
|
if (currentNode.value.level !== 1) {
|
||||||
|
node.isShowEditIcon = true;
|
||||||
|
}
|
||||||
|
departmentDetailInfo.value = await getDepartmentDetailData(
|
||||||
|
currentNode.value.id
|
||||||
|
);
|
||||||
|
}, 300);
|
||||||
|
|
||||||
|
// 所有用户数据
|
||||||
|
const allUserList = ref<UserList>([]);
|
||||||
|
const userKeyword = ref<string>('');
|
||||||
|
|
||||||
|
const getAllUserListData = async () => {
|
||||||
|
try {
|
||||||
|
const { code, data } = await getAllUserList({
|
||||||
|
keyword: userKeyword.value,
|
||||||
|
});
|
||||||
|
if (code === 200 && data?.length) {
|
||||||
|
allUserList.value = data;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取所以用户数据失败:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleAdd = () => {
|
||||||
|
showModal.value = true;
|
||||||
|
isEdit.value = false;
|
||||||
|
};
|
||||||
|
const handleEdit = () => {
|
||||||
|
showModal.value = true;
|
||||||
|
isEdit.value = true;
|
||||||
|
};
|
||||||
|
const handleDelete = async (item) => {
|
||||||
|
const { id } = item;
|
||||||
|
try {
|
||||||
|
const { code, message } = await delDepartment(id);
|
||||||
|
if (code === 200) {
|
||||||
|
Message.success(message);
|
||||||
|
getDepartmentListData();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log('删除失败:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleMoveUp = async (item) => {
|
||||||
|
const { id } = item;
|
||||||
|
try {
|
||||||
|
const { code, message } = await departmentSetUp(id);
|
||||||
|
if (code === 200) {
|
||||||
|
Message.success(message);
|
||||||
|
getDepartmentListData();
|
||||||
|
} else {
|
||||||
|
Message.info(message);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log('向上移动失败:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleMoveDown = async (item) => {
|
||||||
|
const { id } = item;
|
||||||
|
try {
|
||||||
|
const { code, message } = await departmentSetDown(id);
|
||||||
|
if (code === 200) {
|
||||||
|
Message.success(message);
|
||||||
|
getDepartmentListData();
|
||||||
|
} else {
|
||||||
|
Message.info(message);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log('向下移动失败:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getAllUserListData();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.border {
|
||||||
|
border: 1px solid #f4f4f4;
|
||||||
|
height: 100%;
|
||||||
|
padding: 15px 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,3 +1,57 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>帅哥kilo</div>
|
<div class="setting_user_list">
|
||||||
|
<Breadcrumb
|
||||||
|
:items="['menu.setting', 'menu.setting.user', 'menu.setting.user-list']"
|
||||||
|
/>
|
||||||
|
<a-row class="" :gutter="12">
|
||||||
|
<a-col flex="310px">
|
||||||
|
<a-card :bordered="false">
|
||||||
|
<template #title>
|
||||||
|
<div class="card-title_between">
|
||||||
|
<p class="title">{{ $t('organization') }}</p>
|
||||||
|
<a-button @click="onClick"> {{ $t('watch-detail') }} </a-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<a-tree
|
||||||
|
:field-names="{ key: 'ID', title: 'Name' }"
|
||||||
|
:data="departmentListData"
|
||||||
|
>
|
||||||
|
<template #icon>
|
||||||
|
<IconStar />
|
||||||
|
</template>
|
||||||
|
</a-tree>
|
||||||
|
</a-card>
|
||||||
|
</a-col>
|
||||||
|
<a-col flex="auto">
|
||||||
|
<a-card title="Arco Card" :bordered="false">
|
||||||
|
<template #extra>
|
||||||
|
<a-link>More</a-link>
|
||||||
|
</template>
|
||||||
|
Card content
|
||||||
|
<br />
|
||||||
|
Card content
|
||||||
|
</a-card>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { DepartmentFormParams, createDepartment } from '@/api/setting';
|
||||||
|
import useDepartmentList from '@/views/setting/composables/useDepartmentList';
|
||||||
|
// import { ref } from 'vue'
|
||||||
|
const onClick = async () => {
|
||||||
|
const params: DepartmentFormParams = {
|
||||||
|
name: '冰一下很开心', // 部门名称
|
||||||
|
parent_id: 34, // 上一级id
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
const res = await createDepartment(params);
|
||||||
|
console.log(res, 'res');
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error, 'res');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const { departmentListData, getDepartmentListData } = useDepartmentList();
|
||||||
|
getDepartmentListData();
|
||||||
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user