feat: 系统配置通用设置
This commit is contained in:
@@ -10,6 +10,7 @@ export interface BaseEntity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface PaginationParams {
|
export interface PaginationParams {
|
||||||
|
keyword?: string;
|
||||||
role_id?: number | null;
|
role_id?: number | null;
|
||||||
page?: number;
|
page?: number;
|
||||||
page_size?: number;
|
page_size?: number;
|
||||||
@@ -138,7 +139,25 @@ export interface UpdateUserRoleParam {
|
|||||||
role_id: number | null;
|
role_id: number | null;
|
||||||
user_id: number | null;
|
user_id: number | null;
|
||||||
}
|
}
|
||||||
|
// ==================== 系统设置相关类型 ====================
|
||||||
|
export type SafeDefaultPage = 1 | 2 | 3; // 默认登录页:1工作台 2项目管理 3房源剖视
|
||||||
|
export type SafeLoginTimeType = 1 | 2 | 3 | 4; // 登录状态保存时间:1:7天, 2:1天, 3:12小时, 4:1小时
|
||||||
|
export type SafeMoreLogin = 1 | 2; // 多点登录支持:1支持 2不支持
|
||||||
|
|
||||||
|
export interface SafeParams {
|
||||||
|
default_url_typee: SafeDefaultPage;
|
||||||
|
login_time_type: SafeLoginTimeType;
|
||||||
|
is_more_login: SafeMoreLogin;
|
||||||
|
}
|
||||||
|
export interface SafeInfo {
|
||||||
|
id: number;
|
||||||
|
systemTenantId: number | null; // 租户id
|
||||||
|
defaultUrlType: SafeDefaultPage; // 默认登录页:1工作台 2项目管理 3房源剖视
|
||||||
|
loginTimeType: SafeLoginTimeType; // 登录状态保存时间:1:7天, 2:1天, 3:12小时, 4:1小时
|
||||||
|
isMoreLogin: SafeMoreLogin; // 多点登录支持:1支持 2不支持
|
||||||
|
createdAt?: string;
|
||||||
|
updatedAt?: string;
|
||||||
|
}
|
||||||
// ==================== 响应类型别名 ====================
|
// ==================== 响应类型别名 ====================
|
||||||
export type DepartmentFormRes = HttpResponse<DepartmentIdData>;
|
export type DepartmentFormRes = HttpResponse<DepartmentIdData>;
|
||||||
export type DepartmentList = DepartmentItem[];
|
export type DepartmentList = DepartmentItem[];
|
||||||
@@ -153,6 +172,7 @@ export type UserInfoRes = HttpResponse<UserInfo>;
|
|||||||
export type RoleListRes = HttpResponse<RoleList>;
|
export type RoleListRes = HttpResponse<RoleList>;
|
||||||
export type PermissionRes = HttpResponse<UserPermissionItem>;
|
export type PermissionRes = HttpResponse<UserPermissionItem>;
|
||||||
export type RolePermissionRes = HttpResponse<UserPermissionItemList>;
|
export type RolePermissionRes = HttpResponse<UserPermissionItemList>;
|
||||||
|
export type SafeInfoRes = HttpResponse<{ safeSetting: SafeInfo }>;
|
||||||
|
|
||||||
// ==================== 部门相关 API ====================
|
// ==================== 部门相关 API ====================
|
||||||
export function createDepartment(
|
export function createDepartment(
|
||||||
@@ -261,3 +281,13 @@ export function updateUserRole(
|
|||||||
): Promise<HttpResponse> {
|
): Promise<HttpResponse> {
|
||||||
return axios.post('role/updateUserRole', params);
|
return axios.post('role/updateUserRole', params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ==================== 系统设置相关 API ====================
|
||||||
|
// 通用设置-安全设置信息
|
||||||
|
export function getSafeSettingInfo(): Promise<SafeInfoRes> {
|
||||||
|
return axios.get('setting/getSafeSetting');
|
||||||
|
}
|
||||||
|
// 通用设置-安全设置信息保存
|
||||||
|
export function saveSafeSetting(params: SafeParams): Promise<HttpResponse> {
|
||||||
|
return axios.post('setting/saveSafeSetting', params);
|
||||||
|
}
|
||||||
|
|||||||
@@ -117,6 +117,11 @@ export default {
|
|||||||
'all.data.permission': '全部数据权限',
|
'all.data.permission': '全部数据权限',
|
||||||
'customize.data.permission': '自定义数据权限',
|
'customize.data.permission': '自定义数据权限',
|
||||||
'self.data.permission': '仅本人数据',
|
'self.data.permission': '仅本人数据',
|
||||||
|
'setting.general': '通用设置',
|
||||||
|
'setting.process': '流程设置',
|
||||||
|
'setting.project': '项目设置',
|
||||||
|
'setting.contract': '合同设置',
|
||||||
|
'setting.data-dictionary': '数据字典',
|
||||||
|
|
||||||
...localeSettings,
|
...localeSettings,
|
||||||
...localeMessageBox,
|
...localeMessageBox,
|
||||||
|
|||||||
@@ -56,13 +56,89 @@ const SETTING: AppRouteRecordRaw = {
|
|||||||
{
|
{
|
||||||
path: 'system',
|
path: 'system',
|
||||||
name: 'system-setting',
|
name: 'system-setting',
|
||||||
component: () => import('@/views/setting/system/index.vue'),
|
component: PageLayout,
|
||||||
|
redirect: '/setting/system/general',
|
||||||
|
// component: () => import('@/views/setting/system/index.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
locale: 'menu.setting.system',
|
locale: 'menu.setting.system',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
roles: ['admin'],
|
roles: ['admin'],
|
||||||
icon: 'icon-settings',
|
icon: 'icon-settings',
|
||||||
},
|
},
|
||||||
|
children: [
|
||||||
|
// 通用设置
|
||||||
|
{
|
||||||
|
path: 'general',
|
||||||
|
name: 'system-setting-general',
|
||||||
|
component: () =>
|
||||||
|
import('@/views/setting/system/general-settings/index.vue'),
|
||||||
|
meta: {
|
||||||
|
locale: 'setting.general',
|
||||||
|
requiresAuth: true,
|
||||||
|
roles: ['*'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// 组织架构
|
||||||
|
{
|
||||||
|
path: 'organization',
|
||||||
|
name: 'system-setting-organization',
|
||||||
|
component: () =>
|
||||||
|
import('@/views/setting/system/organization/index.vue'),
|
||||||
|
meta: {
|
||||||
|
locale: 'organization',
|
||||||
|
requiresAuth: true,
|
||||||
|
roles: ['*'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// 流程设置
|
||||||
|
{
|
||||||
|
path: 'process',
|
||||||
|
name: 'system-setting-process',
|
||||||
|
component: () =>
|
||||||
|
import('@/views/setting/system/process-settings/index.vue'),
|
||||||
|
meta: {
|
||||||
|
locale: 'setting.process',
|
||||||
|
requiresAuth: true,
|
||||||
|
roles: ['*'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// 项目设置
|
||||||
|
{
|
||||||
|
path: 'project',
|
||||||
|
name: 'system-setting-project',
|
||||||
|
component: () =>
|
||||||
|
import('@/views/setting/system/project-settings/index.vue'),
|
||||||
|
meta: {
|
||||||
|
locale: 'setting.project',
|
||||||
|
requiresAuth: true,
|
||||||
|
roles: ['*'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// 合同设置
|
||||||
|
{
|
||||||
|
path: 'contract',
|
||||||
|
name: 'system-setting-contract',
|
||||||
|
component: () =>
|
||||||
|
import('@/views/setting/system/contract-settings/index.vue'),
|
||||||
|
meta: {
|
||||||
|
locale: 'setting.contract',
|
||||||
|
requiresAuth: true,
|
||||||
|
roles: ['*'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// 数据字典
|
||||||
|
{
|
||||||
|
path: 'data-dictionary',
|
||||||
|
name: 'system-setting-data-dictionary',
|
||||||
|
component: () =>
|
||||||
|
import('@/views/setting/system/data-dictionary/index.vue'),
|
||||||
|
meta: {
|
||||||
|
locale: 'setting.data-dictionary',
|
||||||
|
requiresAuth: true,
|
||||||
|
roles: ['*'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
<template>
|
||||||
|
<div> Data Dictionary </div>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
<template>
|
||||||
|
<div> Data Dictionary </div>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
const generalList = [{ id: 1, text: '安全相关' }];
|
||||||
|
const safeSettingList = [
|
||||||
|
{
|
||||||
|
title: '默认登陆页',
|
||||||
|
options: [
|
||||||
|
{ type: 1, label: '工作台' },
|
||||||
|
{ type: 2, label: '项目管理' },
|
||||||
|
{ type: 3, label: '房源剖视' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '登陆状态保存',
|
||||||
|
options: [
|
||||||
|
{ type: 1, label: '7天' },
|
||||||
|
{ type: 2, label: '1天' },
|
||||||
|
{ type: 3, label: '12小时' },
|
||||||
|
{ type: 4, label: '1小时' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '多点登陆支持',
|
||||||
|
options: [
|
||||||
|
{ type: 1, label: '支持' },
|
||||||
|
{ type: 2, label: '不支持' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
export { generalList, safeSettingList };
|
||||||
@@ -0,0 +1,166 @@
|
|||||||
|
<template>
|
||||||
|
<div class="system-setting-general">
|
||||||
|
<Breadcrumb
|
||||||
|
:items="['menu.setting', 'menu.setting.system', 'setting.general']"
|
||||||
|
/>
|
||||||
|
<a-card class="full_height" :title="t('setting.general')">
|
||||||
|
<a-row :gutter="12">
|
||||||
|
<a-col :span="6">
|
||||||
|
<ul class="general_setting_list">
|
||||||
|
<li
|
||||||
|
v-for="item in generalList"
|
||||||
|
:key="item.id"
|
||||||
|
:class="[
|
||||||
|
'general_setting_item',
|
||||||
|
{ isChoose: generalId === item.id },
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
{{ item.text }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="18">
|
||||||
|
<a-card title="安全相关">
|
||||||
|
<template #extra>
|
||||||
|
<a-button type="primary" @click="handleSaveSafe">保存</a-button>
|
||||||
|
</template>
|
||||||
|
<ul class="safe_setting_list">
|
||||||
|
<li
|
||||||
|
v-for="(item, index) in safeSettingList"
|
||||||
|
:key="index"
|
||||||
|
class="safe_setting_item"
|
||||||
|
>
|
||||||
|
<h4 class="safe_setting_item_title">{{ item.title }}</h4>
|
||||||
|
<ul class="options">
|
||||||
|
<li
|
||||||
|
v-for="(subItem, subIndex) in item.options"
|
||||||
|
:key="subIndex"
|
||||||
|
:class="[
|
||||||
|
'subItem',
|
||||||
|
{ isActive: isActiveOption(index, subItem.type) },
|
||||||
|
]"
|
||||||
|
@click="onOptionClick(index, subItem.type)"
|
||||||
|
>
|
||||||
|
{{ subItem.label }}</li
|
||||||
|
>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</a-card>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</a-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, onMounted } from 'vue';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { getSafeSettingInfo, SafeInfo, saveSafeSetting } from '@/api/setting';
|
||||||
|
import { Message } from '@arco-design/web-vue';
|
||||||
|
import { generalList, safeSettingList } from './contrant';
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
const generalId = ref<number>(1);
|
||||||
|
const safeSettingInfo = ref<SafeInfo | null>(null);
|
||||||
|
|
||||||
|
const getSafeSettingInfoData = async () => {
|
||||||
|
try {
|
||||||
|
const { code, data } = await getSafeSettingInfo();
|
||||||
|
if (code === 200 && data) {
|
||||||
|
safeSettingInfo.value = data?.safeSetting;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const isActiveOption = (itemIndex: number, type: number) => {
|
||||||
|
if (!safeSettingInfo.value) return false;
|
||||||
|
if (itemIndex === 0) return safeSettingInfo.value.defaultUrlType === type;
|
||||||
|
if (itemIndex === 1) return safeSettingInfo.value.loginTimeType === type;
|
||||||
|
if (itemIndex === 2) return safeSettingInfo.value.isMoreLogin === type;
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
const onOptionClick = (itemIndex: number, type: any) => {
|
||||||
|
if (!safeSettingInfo.value) return;
|
||||||
|
if (itemIndex === 0) safeSettingInfo.value.defaultUrlType = type;
|
||||||
|
if (itemIndex === 1) safeSettingInfo.value.loginTimeType = type;
|
||||||
|
if (itemIndex === 2) safeSettingInfo.value.isMoreLogin = type;
|
||||||
|
};
|
||||||
|
const handleSaveSafe = async () => {
|
||||||
|
try {
|
||||||
|
if (safeSettingInfo.value) {
|
||||||
|
const params = {
|
||||||
|
default_url_typee: safeSettingInfo.value.defaultUrlType,
|
||||||
|
login_time_type: safeSettingInfo.value.loginTimeType,
|
||||||
|
is_more_login: safeSettingInfo.value.isMoreLogin,
|
||||||
|
};
|
||||||
|
const { code, data, message } = await saveSafeSetting(params);
|
||||||
|
if (code === 200 && data) {
|
||||||
|
Message.success(message);
|
||||||
|
getSafeSettingInfoData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
onMounted(() => {
|
||||||
|
getSafeSettingInfoData();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.system-setting-general {
|
||||||
|
.general_setting_list {
|
||||||
|
border-radius: 6px;
|
||||||
|
border: 1px solid rgba(239, 239, 239, 1);
|
||||||
|
padding: 14px 0;
|
||||||
|
padding-bottom: 200px;
|
||||||
|
|
||||||
|
.general_setting_item {
|
||||||
|
padding: 0 20px;
|
||||||
|
height: 42px;
|
||||||
|
line-height: 42px;
|
||||||
|
color: #000;
|
||||||
|
background-color: #fff;
|
||||||
|
|
||||||
|
&.isChoose {
|
||||||
|
background-color: #efefef;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.safe_setting_list {
|
||||||
|
.safe_setting_item {
|
||||||
|
margin-top: 20px;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// .safe_setting_item_title {}
|
||||||
|
.options {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
background-color: #f2f3f5;
|
||||||
|
width: 430px;
|
||||||
|
height: 36px;
|
||||||
|
margin-top: 10px;
|
||||||
|
padding: 0 3px;
|
||||||
|
|
||||||
|
.subItem {
|
||||||
|
flex: 1;
|
||||||
|
text-align: center;
|
||||||
|
padding: 4px 0;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&.isActive {
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
<template>
|
|
||||||
<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>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { ref, watch } from 'vue';
|
|
||||||
import { useI18n } from 'vue-i18n';
|
|
||||||
import { useRoute } from 'vue-router';
|
|
||||||
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 route = useRoute();
|
|
||||||
const currentActive = ref(1);
|
|
||||||
|
|
||||||
// 监听路由query参数中的active参数
|
|
||||||
watch(
|
|
||||||
() => route.query.active,
|
|
||||||
(newActive) => {
|
|
||||||
if (newActive) {
|
|
||||||
const activeValue = parseInt(newActive as string, 10);
|
|
||||||
if (!Number.isNaN(activeValue)) {
|
|
||||||
currentActive.value = activeValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ immediate: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
// watch()
|
|
||||||
</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>
|
|
||||||
+10
-5
@@ -1,12 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
|
<div class="system-setting-organization">
|
||||||
|
<Breadcrumb
|
||||||
|
:items="['menu.setting', 'menu.setting.system', 'organization']"
|
||||||
|
/>
|
||||||
<a-card class="full_height" :bordered="false">
|
<a-card class="full_height" :bordered="false">
|
||||||
<template #title>
|
<template #title>
|
||||||
<div class="card-title_between">
|
<div class="card-title_between">
|
||||||
<p>
|
<p>
|
||||||
<icon-drag-arrow />
|
<!-- <icon-drag-arrow /> -->
|
||||||
<span class="title" style="margin-left: 15px">{{
|
<span class="title" style="margin-left: 15px">
|
||||||
$t('organization')
|
{{ $t('organization') }}</span
|
||||||
}}</span>
|
>
|
||||||
</p>
|
</p>
|
||||||
<a-button type="primary" @click="handleAdd">
|
<a-button type="primary" @click="handleAdd">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
@@ -90,6 +94,7 @@
|
|||||||
@submitted="getDepartmentListData"
|
@submitted="getDepartmentListData"
|
||||||
/>
|
/>
|
||||||
</a-card>
|
</a-card>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
@@ -106,7 +111,7 @@
|
|||||||
} from '@/api/setting';
|
} from '@/api/setting';
|
||||||
import { debounce } from '@/utils';
|
import { debounce } from '@/utils';
|
||||||
import { Message } from '@arco-design/web-vue';
|
import { Message } from '@arco-design/web-vue';
|
||||||
import departmentFormModal from './components/department-form-modal.vue';
|
import departmentFormModal from '../components/department-form-modal.vue';
|
||||||
|
|
||||||
const {
|
const {
|
||||||
departmentListData,
|
departmentListData,
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
<template>
|
||||||
|
<div> Data Dictionary </div>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
<template>
|
||||||
|
<div> Data Dictionary </div>
|
||||||
|
</template>
|
||||||
Reference in New Issue
Block a user