Merge pull request #519 from chat2db/team

Team
This commit is contained in:
贺喜
2023-09-05 17:05:45 +08:00
committed by GitHub
70 changed files with 2259 additions and 187 deletions

View File

@@ -53,7 +53,7 @@ export default forwardRef(function CreateConnection(props: IProps, ref: Forwarde
backfillDataLoading: false,
sshTestLoading: false
});
const [envList, setEnvList] = useState<{value:string,label:string}[]>([]);
const [envList, setEnvList] = useState<{ value: string, label: string }[]>([]);
useEffect(() => {
@@ -200,7 +200,7 @@ export default forwardRef(function CreateConnection(props: IProps, ref: Forwarde
p.id = backfillData.id;
}
if (type === submitType.SAVE || type === submitType.UPDATE) {
if ((type === submitType.SAVE || type === submitType.UPDATE) && submit) {
submit?.(p);
return
}

View File

@@ -1,7 +1,9 @@
@font-face {
font-family: 'iconfont'; /* Project id 3633546 */
src: url('../../assets/font/iconfont.woff2') format('woff2'), url('../../assets/font/iconfont.woff') format('woff'),
url('../../assets/font/iconfont.ttf') format('truetype');
font-family: 'iconfont';
/* Project id 3633546 */
src: url('//at.alicdn.com/t/c/font_3633546_73vqnzklicw.woff2?t=1693730048111') format('woff2'),
url('//at.alicdn.com/t/c/font_3633546_73vqnzklicw.woff?t=1693730048111') format('woff'),
url('//at.alicdn.com/t/c/font_3633546_73vqnzklicw.ttf?t=1693730048111') format('truetype');
}
.iconfont {
@@ -12,4 +14,4 @@
-webkit-font-smoothing: antialiased;
-webkit-text-stroke-width: 0.2px;
-moz-osx-font-smoothing: grayscale;
}
}

View File

@@ -8,10 +8,11 @@ if (__ENV__ === 'local') {
let container = `
/* 在线链接服务仅供平台体验和调试使用,平台不承诺服务的稳定性,企业客户需下载字体包自行发布使用并做好备份。 */
@font-face {
font-family: 'iconfont'; /* Project id 3633546 */
src: url('//at.alicdn.com/t/c/font_3633546_3p2ezsbklq9.woff2?t=1692415581018') format('woff2'),
url('//at.alicdn.com/t/c/font_3633546_3p2ezsbklq9.woff?t=1692415581018') format('woff'),
url('//at.alicdn.com/t/c/font_3633546_3p2ezsbklq9.ttf?t=1692415581018') format('truetype');
font-family: 'iconfont';
/* Project id 3633546 */
src: url('//at.alicdn.com/t/c/font_3633546_73vqnzklicw.woff2?t=1693730048111') format('woff2'),
url('//at.alicdn.com/t/c/font_3633546_73vqnzklicw.woff?t=1693730048111') format('woff'),
url('//at.alicdn.com/t/c/font_3633546_73vqnzklicw.ttf?t=1693730048111') format('truetype');
}
`;
let style = document.createElement('style');

View File

@@ -79,5 +79,7 @@ export default {
'common.tips.delete.confirm': 'Are you sure to delete it?',
'common.tips.updateSuccess': 'Update Successfully',
'common.tips.createSuccess': 'Create Successfully',
'common.text.action': 'Action'
'common.text.action': 'Action',
'common.button.add': 'Add',
};

View File

@@ -6,6 +6,7 @@ import workspace from './workspace';
import dashboard from './dashboard';
import chat from './chat';
import team from './team'
import login from './login';
export default {
lang: 'en',
@@ -16,5 +17,6 @@ export default {
...menu,
...dashboard,
...chat,
...team
...team,
...login
};

View File

@@ -0,0 +1,12 @@
export default {
'login.text.logout': 'Logout',
'login.text.welcome': 'Welcome to Chat2DB',
'login.text.tips': 'The Chat2DB account is only for team collaboration management.',
'login.text.tips.title': 'Why need login?',
'login.text.setting': 'Setting',
'login.form.user': 'UserName',
'login.form.user.placeholder': 'Please enter your username',
'login.form.password': 'Password',
'login.form.password.placeholder': 'Please enter your password',
'login.button.login': 'Login',
};

View File

@@ -2,22 +2,35 @@ export default {
'team.tab.datasource': 'DataSource Management',
'team.tab.user': 'User Management',
'team.tab.team': 'Team Management',
'team.datasource.alias': 'DataSource Name',
'team.datasource.url': 'DataSource URL',
'team.user.userName': 'UserName',
'team.user.nickName': 'NickName',
'team.user.status': 'Status',
'team.action.rightManagement': 'Right Management',
'team.action.editDatasource': 'Edit DataSource',
'team.action.addDatasource': 'Add DataSource',
'team.action.addDatasource.placeholder': 'Search DataSource',
'team.action.addUser': 'Add User',
'team.action.addUser.placeholder': 'Search User',
'team.action.editTeam': 'Edit Team',
'team.action.addTeam': 'Add Team',
'team.action.addTeam.placeholder': 'Search Team',
'team.action.affiliation.user': 'Affiliation User',
'team.action.affiliation.team': 'Affiliation Team',
'team.action.affiliation.datasource': 'Affiliation DataSource',
'team.action.addUserAndTeam': 'Add User/Team',
'team.action.addUserAndTeam.placeholder': 'Search User/Team',
'team.input.search.placeholder': 'Please enter keywords to search',
'team.datasource.rightManagement': 'Right Management',
'team.datasource.alias': 'DataSource Name',
'team.datasource.url': 'DataSource URL',
'team.datasource.code': 'Code',
'team.datasource.name': 'Name',
'team.datasource.status': 'Status',
'team.user.name': 'User',
'team.user.userName': 'UserName',
'team.user.nickName': 'NickName',
'team.user.status': 'Status',
'team.user.addForm.userName': 'UserName',
'team.user.addForm.nickName': 'NickName',
'team.user.addForm.email': 'Email',
@@ -30,10 +43,13 @@ export default {
'team.user.addForm.status.invalid': 'Invalid',
'team.team.name': 'Team',
'team.team.addForm.code': 'Team Code',
'team.team.addForm.name': 'Team Name',
'team.team.addForm.status': 'Status',
'team.team.addForm.status.valid': 'Valid',
'team.team.addForm.status.invalid': 'Invalid',
'team.team.addForm.description': 'Description',
}

View File

@@ -77,5 +77,7 @@ export default {
'common.tips.delete.confirm': '确认要删除吗?',
'common.tips.updateSuccess': '更新成功',
'common.tips.createSuccess': '创建成功',
'common.text.action': '操作'
'common.text.action': '操作',
'common.button.add': '添加',
};

View File

@@ -7,6 +7,7 @@ import workspace from './workspace';
import dashboard from './dashboard';
import chat from './chat';
import team from './team'
import login from './login';
export default {
lang: LangType.ZH_CN,
@@ -18,5 +19,6 @@ export default {
...connection,
...dashboard,
...chat,
...team
...team,
...login
};

View File

@@ -0,0 +1,12 @@
export default {
'login.text.logout': '退出登录',
'login.text.welcome': '欢迎使用 Chat2DB',
'login.text.tips': 'Chat2DB 账号仅用于团队协作管理',
'login.text.tips.title': '为什么需要登录?',
'login.text.setting': '设 置',
'login.form.user': '用户名',
'login.form.user.placeholder': '请输入用户名',
'login.form.password': '密码',
'login.form.password.placeholder': '请输入密码',
'login.button.login': '登 录',
};

View File

@@ -1,39 +1,52 @@
export default {
'team.tab.datasource': '链接管理',
'team.tab.user': '用户管理',
'team.tab.team': '团队管理',
'team.datasource.alias': '链接名称',
'team.datasource.url': '链接地址',
'team.user.userName': '用户名',
'team.user.nickName': '昵称',
'team.user.status': '状态',
'team.action.rightManagement': '权限管理',
'team.action.editDatasource': '编辑链接',
'team.action.addDatasource': '添加链接',
'team.action.editUser': '编辑用户',
'team.action.addUser': '添加用户',
'team.action.editTeam': '编辑团队',
'team.action.addTeam': '添加团队',
'team.action.affiliation.user': '包含用户',
'team.action.affiliation.team': '所属团队',
'team.action.affiliation.datasource': '归属链接',
'team.input.search.placeholder': '输入关键字进行搜索',
'team.tab.datasource': '链接管理',
'team.tab.user': '用户管理',
'team.tab.team': '团队管理',
'team.user.addForm.userName': '用户名',
'team.user.addForm.nickName': '昵称',
'team.user.addForm.email': '邮箱',
'team.user.addForm.password': '密码',
'team.user.addForm.roleCode': '角色',
'team.user.addForm.roleCode.admin': '管理员',
'team.user.addForm.roleCode.user': '用户',
'team.user.addForm.status': '状态',
'team.user.addForm.status.valid': '有效',
'team.user.addForm.status.invalid': '无效',
'team.action.rightManagement': '权限管理',
'team.action.editDatasource': '编辑链接',
'team.action.addDatasource': '添加链接',
'team.action.addDatasource.placeholder': '搜索链接',
'team.action.editUser': '编辑用户',
'team.action.addUser': '添加用户',
'team.action.addUser.placeholder': '搜索用户',
'team.action.editTeam': '编辑团队',
'team.action.addTeam': '添加团队',
'team.action.addTeam.placeholder': '搜索团队',
'team.action.affiliation.user': '包含用户',
'team.action.affiliation.team': '所属团队',
'team.action.affiliation.datasource': '归属链接',
'team.action.addUserAndTeam': '添加用户/团队',
'team.action.addUserAndTeam.placeholder': '搜索人员/团队',
'team.input.search.placeholder': '输入关键字进行搜索',
'team.team.addForm.code': '团队编码',
'team.team.addForm.name': '团队名',
'team.team.addForm.status': '状态',
'team.team.addForm.status.valid': '有效',
'team.team.addForm.status.invalid': '无效',
'team.team.addForm.description': '描述',
}
'team.datasource.rightManagement': '权限管理',
'team.datasource.alias': '链接名称',
'team.datasource.url': '链接地址',
'team.datasource.code': '编码',
'team.datasource.name': '名称',
'team.datasource.status': '状态',
'team.user.name': '用户',
'team.user.userName': '用户名',
'team.user.nickName': '昵称',
'team.user.status': '状态',
'team.user.addForm.userName': '用户名',
'team.user.addForm.nickName': '昵称',
'team.user.addForm.email': '邮箱',
'team.user.addForm.password': '密码',
'team.user.addForm.roleCode': '角色',
'team.user.addForm.roleCode.admin': '管理员',
'team.user.addForm.roleCode.user': '用户',
'team.user.addForm.status': '状态',
'team.user.addForm.status.valid': '有效',
'team.user.addForm.status.invalid': '无效',
'team.team.name': '团队',
'team.team.addForm.code': '团队编码',
'team.team.addForm.name': '团队名',
'team.team.addForm.status': '状态',
'team.team.addForm.status.valid': '有效',
'team.team.addForm.status.invalid': '无效',
'team.team.addForm.description': '描述',
};

View File

@@ -6,6 +6,7 @@ import LogoImg from '@/assets/logo/logo.png';
import styles from './index.less';
import Setting from '@/blocks/Setting';
import Iconfont from '@/components/Iconfont';
import i18n from '@/i18n';
interface IFormData {
userName: string;
@@ -27,32 +28,32 @@ const App: React.FC = () => {
<div className={styles.logoText}>Chat2DB</div>
</div>
<div className={styles.loginPlane}>
<div className={styles.loginWelcome}>欢迎使用 Chat2DB</div>
<div className={styles.loginWelcome}>{i18n('login.text.welcome')}</div>
<Tooltip
placement="right"
color={window._AppThemePack.colorBgBase}
title={
<div style={{ color: window._AppThemePack.colorText, opacity: 0.8, padding: '8px 4px' }}>
Chat2DB 账号仅用于团队协作管理
{i18n('login.text.tips')}
</div>
}
>
<div className={styles.whyLogin}>为什么需要登录?</div>
<div className={styles.whyLogin}>{i18n('login.text.tips.title')}</div>
</Tooltip>
<Form className={styles.loginForm} size="large" onFinish={handleLogin}>
<Form.Item
className={styles.loginFormItem}
name="userName"
rules={[{ required: true, message: '请输入用户名' }]}
rules={[{ required: true, message: i18n('login.form.user.placeholder') }]}
>
<Input autoComplete="off" placeholder="用户名" />
<Input autoComplete="off" placeholder={i18n('login.form.user')} />
</Form.Item>
<Form.Item name="password" rules={[{ required: true, message: '请输入密码' }]}>
<Input.Password placeholder="密码" />
<Form.Item name="password" rules={[{ required: true, message: i18n('login.form.password.placeholder') }]}>
<Input.Password placeholder={i18n('login.form.password')} />
</Form.Item>
<Button type="primary" htmlType="submit" className={styles.loginFormSubmit}>
登 录
{i18n('login.button.login')}
</Button>
</Form>
</div>
@@ -65,7 +66,7 @@ const App: React.FC = () => {
icon={<Iconfont style={{ fontSize: '14px' }} code="&#xe630;" />}
className={styles.settingBtn}
>
设 置
{i18n('login.text.setting')}
</Button>
}
/>

View File

@@ -5,7 +5,7 @@ import ConnectionEdit from '@/components/ConnectionEdit';
import Iconfont from '@/components/Iconfont';
import connectionService from '@/service/connection';
import { DatabaseTypeCode, databaseMap, databaseTypeList } from '@/constants';
import { IDatabase, IConnectionDetails } from '@/typings';
import { IDatabase, IConnectionDetails, IEnvironmentVO } from '@/typings';
import { Button, Dropdown, Modal } from 'antd';
import { MoreOutlined } from '@ant-design/icons';
import styles from './index.less';
@@ -13,6 +13,7 @@ import { connect, history, Dispatch } from 'umi';
import { IConnectionModelType } from '@/models/connection';
import { IWorkspaceModelType } from '@/models/workspace';
interface IMenu {
key: number;
label: string;
@@ -20,16 +21,19 @@ interface IMenu {
meta: IConnectionDetails;
}
// interface IConnectionList {
// environment: 'dev' | 'test' | 'prod';
// connectionList: IMenu[];
// }
interface IProps {
connectionModel: IConnectionModelType['state'];
workspaceModel: IWorkspaceModelType['state'];
dispatch: any;
}
function Connections(props: IProps) {
const { connectionModel, workspaceModel, dispatch } = props;
const { connectionModel, dispatch } = props;
const { connectionList } = connectionModel;
const { curWorkspaceParams } = workspaceModel;
const volatileRef = useRef<any>();
const [curConnection, setCurConnection] = useState<Partial<IConnectionDetails>>({});

View File

@@ -18,6 +18,7 @@ import { getUser, userLogout } from '@/service/user';
import { ILoginUser } from '@/typings/user';
import { Dropdown } from 'antd';
import Team from './team';
import i18n from '@/i18n';
let navConfig: INavItem[] = [
{
@@ -75,8 +76,8 @@ function MainPage(props: IProps) {
if (res.admin) {
navConfig.splice(3, 0, {
key: 'team',
icon: '\ue66d',
iconFontSize: 20,
icon: '\ue64b',
iconFontSize: 24,
isLoad: false,
component: <Team />,
});
@@ -139,14 +140,14 @@ function MainPage(props: IProps) {
items: [
{
key: '1',
label: <div onClick={handleLogout}>退出登录</div>,
label: <div onClick={handleLogout}>{i18n('login.text.logout')}</div>,
},
],
}}
placement="bottomRight"
arrow={{ pointAtCenter: true }}
>
<Iconfont code="&#xe666;" className={styles.questionIcon} />
<Iconfont code="&#xe64c;" className={styles.questionIcon} />
</Dropdown>
);
};

View File

@@ -159,7 +159,7 @@ function DataSourceManagement() {
enterButton={<SearchOutlined />}
/>
<Button type="primary" icon={<PlusOutlined />} onClick={handleAddDataSource}>
{i18n('team.action.editDatasource')}
{i18n('team.action.addDatasource')}
</Button>
</div>
<Table

View File

@@ -165,7 +165,7 @@ function TeamManagement() {
enterButton={<SearchOutlined />}
/>
<Button type="primary" icon={<PlusOutlined />} onClick={() => setIsModalVisible(true)}>
{i18n('team.action.addUser')}
{i18n('team.action.addTeam')}
</Button>
</div>
<Table

View File

@@ -1,9 +1,15 @@
import { getCommonDataSourceList, getCommonTeamList, getCommonUserAndTeamList, getCommonUserList } from '@/service/team';
import {
getCommonDataSourceList,
getCommonTeamList,
getCommonUserAndTeamList,
getCommonUserList,
} from '@/service/team';
import { IDataSourceVO, ITeamAndUserVO, ITeamVO, IUserVO, ManagementType, SearchType } from '@/typings/team';
import { Modal, Select, Spin } from 'antd';
import debounce from 'lodash/debounce';
import React, { useMemo, useState } from 'react';
import styles from './index.less';
import i18n from '@/i18n';
interface IProps {
open: boolean;
@@ -21,51 +27,51 @@ interface ValueType {
const addAuthMap = {
[SearchType['USER/TEAM']]: {
title: '添加人员/团队',
title: i18n('team.action.addUserAndTeam'),
loadRequest: getCommonUserAndTeamList,
searchLabel: (data: ITeamAndUserVO) => data.name,
searchValue: (data: ITeamAndUserVO) => JSON.stringify({ id: data.id, type: data.type }),
searchListKey: 'accessObjectList',
placeholder: '搜索人员/团队',
placeholder: i18n('team.action.addUserAndTeam.placeholder'),
},
[SearchType.TEAM]: {
title: '添加团队',
title: i18n('team.action.addTeam'),
loadRequest: getCommonTeamList,
searchLabel: (data: ITeamVO) => data.name,
searchValue: (data: ITeamVO) => data.id,
searchListKey: 'teamIdList',
placeholder: '搜索团队',
placeholder: i18n('team.action.addTeam.placeholder'),
},
[SearchType.USER]: {
title: '添加人员',
title: i18n('team.action.addUser'),
loadRequest: getCommonUserList,
searchLabel: (data: IUserVO) => data.userName,
searchValue: (data: IUserVO) => data.id,
searchListKey: 'userIdList',
placeholder: '搜索人员',
placeholder: i18n('team.action.addUser.placeholder'),
},
[SearchType.DATASOURCE]: {
title: '添加链接',
title: i18n('team.action.addDatasource'),
loadRequest: getCommonDataSourceList,
searchLabel: (data: IDataSourceVO) => data.alias,
searchValue: (data: IDataSourceVO) => data.id,
searchListKey: 'dataSourceIdList',
placeholder: '搜索链接',
placeholder: i18n('team.action.addDatasource.placeholder'),
},
}
};
function UniversalAddModal(props: IProps) {
const { open, type } = props;
const [fetching, setFetching] = useState(false);
const [options, setOptions] = useState<ValueType[]>([]);
const [selectedValues, setSelectedValues] = useState([])
const [selectedValues, setSelectedValues] = useState([]);
const authData = useMemo(() => {
if (type) {
return addAuthMap[type]
return addAuthMap[type];
}
}, [type])
}, [type]);
const loadOptions = (value: string) => {
setOptions([]);
@@ -91,14 +97,15 @@ function UniversalAddModal(props: IProps) {
}
const realValue = {
[authData.searchListKey]: type !== SearchType['USER/TEAM'] ? selectedValues : selectedValues.map(i => JSON.parse(i))
}
[authData.searchListKey]:
type !== SearchType['USER/TEAM'] ? selectedValues : selectedValues.map((i) => JSON.parse(i)),
};
props.onConfirm(realValue)
props.onConfirm(realValue);
props.onClose && props.onClose();
setSelectedValues([]);
setOptions([]);
}
};
return (
<Modal
@@ -120,7 +127,7 @@ function UniversalAddModal(props: IProps) {
options={options}
value={selectedValues}
onChange={(values) => {
setSelectedValues(values)
setSelectedValues(values);
}}
/>
</Modal>

View File

@@ -1,8 +1,36 @@
import { Button, Drawer, Input, message, Popconfirm, Table, Tag } from 'antd';
import React, { useEffect, useMemo, useState } from 'react';
import { SearchOutlined, PlusOutlined } from '@ant-design/icons';
import { AffiliationType, IDataSourceAccessVO, IDataSourceVO, ITeamVO, ITeamWithDataSourceVO, ITeamWithUserVO, IUserVO, IUserWithDataSourceVO, IUserWithTeamVO, ManagementType, SearchType, } from '@/typings/team';
import { deleteDataSourceFromTeam, deleteDataSourceFromUser, deleteTeamListFromUser, deleteUserFromTeam, deleteUserOrTeamFromDataSource, getDataSourceListFromTeam, getDataSourceListFromUser, getTeamListFromUser, getUserAndTeamListFromDataSource, getUserListFromTeam, updateDataSourceListFromTeam, updateDataSourceListFromUser, updateTeamListFromUser, updateUserAndTeamListFromDataSource, updateUserListFromTeam } from '@/service/team';
import {
AffiliationType,
IDataSourceAccessVO,
IDataSourceVO,
ITeamVO,
ITeamWithDataSourceVO,
ITeamWithUserVO,
IUserVO,
IUserWithDataSourceVO,
IUserWithTeamVO,
ManagementType,
SearchType,
} from '@/typings/team';
import {
deleteDataSourceFromTeam,
deleteDataSourceFromUser,
deleteTeamListFromUser,
deleteUserFromTeam,
deleteUserOrTeamFromDataSource,
getDataSourceListFromTeam,
getDataSourceListFromUser,
getTeamListFromUser,
getUserAndTeamListFromDataSource,
getUserListFromTeam,
updateDataSourceListFromTeam,
updateDataSourceListFromUser,
updateTeamListFromUser,
updateUserAndTeamListFromDataSource,
updateUserListFromTeam,
} from '@/service/team';
import UniversalAddModal from '../universal-add-modal';
import styles from './index.less';
@@ -31,11 +59,10 @@ interface IAffiliationDetail {
function UniversalDrawer(props: IProps) {
const { type, open } = props;
const [dataSource, setDataSource] = useState<Array<IUserVO | ITeamVO | IDataSourceVO>>([]);
const [isModalVisible, setIsModalVisible] = useState(false);
const [modalInfo, setModalInfo] = useState<{ open: boolean; type?: SearchType }>({
open: false,
});
const [searchInput, setSearchInput] = useState('')
const [searchInput, setSearchInput] = useState('');
const [pagination, setPagination] = useState({
searchKey: '',
@@ -51,24 +78,24 @@ function UniversalDrawer(props: IProps) {
[AffiliationType.USER_TEAM]: {
type: AffiliationType.USER_TEAM,
searchType: SearchType.TEAM,
title: '团队',
title: i18n('team.team.name'),
byIdKey: 'userId',
queryListApi: getTeamListFromUser,
updateListApi: updateTeamListFromUser,
deleteApi: deleteTeamListFromUser,
columns: [
{
title: '团队编码',
title: i18n('team.team.addForm.code'),
dataIndex: ['team', 'code'],
key: 'team.code'
key: 'team.code',
},
{
title: '团队名称',
title: i18n('team.team.addForm.name'),
dataIndex: ['team', 'name'],
key: 'team.name'
key: 'team.name',
},
{
title: '操作',
title: i18n('common.text.action'),
key: 'action',
width: 100,
render: (_: any, record: IUserWithTeamVO) => (
@@ -79,39 +106,40 @@ function UniversalDrawer(props: IProps) {
onConfirm={async () => {
if (record.id !== undefined) {
await deleteTeamListFromUser({ id: record.id });
message.success(i18n('common.text.successfullyDelete'))
message.success(i18n('common.text.successfullyDelete'));
queryTableList();
}
}}>
<a href='#' onClick={(e) => e.preventDefault()}>
}}
>
<a href="#" onClick={(e) => e.preventDefault()}>
{i18n('common.button.delete')}
</a>
</Popconfirm>
)
}
]
),
},
],
},
[AffiliationType.USER_DATASOURCE]: {
type: AffiliationType.USER_DATASOURCE,
searchType: SearchType.DATASOURCE,
title: '归属链接',
title: i18n('team.datasource.rightManagement'),
byIdKey: 'userId',
queryListApi: getDataSourceListFromUser,
updateListApi: updateDataSourceListFromUser,
deleteApi: deleteDataSourceFromUser,
columns: [
{
title: '链接名称',
title: i18n('team.datasource.alias'),
dataIndex: ['dataSource', 'alias'],
key: 'dataSource.alias'
key: 'dataSource.alias',
},
{
title: '链接地址',
title: i18n('team.datasource.url'),
dataIndex: ['dataSource', 'url'],
key: 'dataSource.url'
key: 'dataSource.url',
},
{
title: '操作',
title: i18n('common.text.action'),
key: 'action',
width: 100,
render: (_: any, record: IUserWithDataSourceVO) => (
@@ -122,39 +150,40 @@ function UniversalDrawer(props: IProps) {
onConfirm={async () => {
if (record.id !== undefined) {
await deleteDataSourceFromUser({ id: record.id });
message.success(i18n('common.text.successfullyDelete'))
message.success(i18n('common.text.successfullyDelete'));
queryTableList();
}
}}>
<a href='#' onClick={(e) => e.preventDefault()}>
}}
>
<a href="#" onClick={(e) => e.preventDefault()}>
{i18n('common.button.delete')}
</a>
</Popconfirm>
)
}
]
),
},
],
},
[AffiliationType.TEAM_USER]: {
type: AffiliationType.TEAM_USER,
searchType: SearchType.USER,
title: '用户',
title: i18n('team.user.name'),
byIdKey: 'teamId',
queryListApi: getUserListFromTeam,
updateListApi: updateUserListFromTeam,
deleteApi: deleteUserFromTeam,
columns: [
{
title: '用户名',
title: i18n('team.user.addForm.userName'),
dataIndex: ['user', 'userName'],
key: 'user.userName'
key: 'user.userName',
},
{
title: '昵称',
title: i18n('team.user.addForm.nickName'),
dataIndex: ['user', 'nickName'],
key: 'user.nickName'
key: 'user.nickName',
},
{
title: '操作',
title: i18n('common.text.action'),
key: 'action',
width: 100,
render: (_: any, record: ITeamWithUserVO) => (
@@ -165,39 +194,40 @@ function UniversalDrawer(props: IProps) {
onConfirm={async () => {
if (record.id !== undefined) {
await deleteUserFromTeam({ id: record.id });
message.success(i18n('common.text.successfullyDelete'))
message.success(i18n('common.text.successfullyDelete'));
queryTableList();
}
}}>
<a href='#' onClick={(e) => e.preventDefault()}>
}}
>
<a href="#" onClick={(e) => e.preventDefault()}>
{i18n('common.button.delete')}
</a>
</Popconfirm>
)
}
]
),
},
],
},
[AffiliationType.TEAM_DATASOURCE]: {
type: AffiliationType.TEAM_DATASOURCE,
searchType: SearchType.DATASOURCE,
title: '归属链接',
title: i18n('team.action.affiliation.datasource'),
byIdKey: 'teamId',
queryListApi: getDataSourceListFromTeam,
updateListApi: updateDataSourceListFromTeam,
deleteApi: deleteDataSourceFromTeam,
columns: [
{
title: '链接名称',
title: i18n('team.datasource.alias'),
dataIndex: ['dataSource', 'alias'],
key: 'dataSource.alias'
key: 'dataSource.alias',
},
{
title: '链接地址',
title: i18n('team.datasource.url'),
dataIndex: ['dataSource', 'url'],
key: 'dataSource.url'
key: 'dataSource.url',
},
{
title: '操作',
title: i18n('common.text.action'),
key: 'action',
width: 100,
render: (_: any, record: ITeamWithDataSourceVO) => (
@@ -208,45 +238,48 @@ function UniversalDrawer(props: IProps) {
onConfirm={async () => {
if (record.id !== undefined) {
await deleteDataSourceFromUser({ id: record.id });
message.success(i18n('common.text.successfullyDelete'))
message.success(i18n('common.text.successfullyDelete'));
queryTableList();
}
}}>
<a href='#' onClick={(e) => e.preventDefault()}>
}}
>
<a href="#" onClick={(e) => e.preventDefault()}>
{i18n('common.button.delete')}
</a>
</Popconfirm>
)
}
]
),
},
],
},
[AffiliationType['DATASOURCE_USER/TEAM']]: {
type: AffiliationType['DATASOURCE_USER/TEAM'],
searchType: SearchType['USER/TEAM'],
title: '链接权限管理',
title: i18n('team.datasource.rightManagement'),
byIdKey: 'dataSourceId',
queryListApi: getUserAndTeamListFromDataSource,
updateListApi: updateUserAndTeamListFromDataSource,
deleteApi: deleteUserOrTeamFromDataSource,
columns: [
{
title: '编码',
title: i18n('team.datasource.code'),
dataIndex: ['accessObject', 'code'],
key: 'accessObject.code'
key: 'accessObject.code',
},
{
title: '名称',
title: i18n('team.datasource.name'),
dataIndex: ['accessObject', 'name'],
key: 'accessObject.name'
key: 'accessObject.name',
},
{
title: '类型',
title: i18n('team.datasource.status'),
dataIndex: ['accessObject', 'type'],
key: 'accessObject.type',
render: (status: ManagementType) => <Tag color={status === ManagementType.TEAM ? 'blue' : 'lime'}>{status}</Tag>
render: (status: ManagementType) => (
<Tag color={status === ManagementType.TEAM ? 'blue' : 'lime'}>{status}</Tag>
),
},
{
title: '操作',
title: i18n('common.text.action'),
key: 'action',
width: 100,
render: (_: any, record: IDataSourceAccessVO) => (
@@ -257,25 +290,29 @@ function UniversalDrawer(props: IProps) {
onConfirm={async () => {
if (record.id !== undefined) {
await deleteUserOrTeamFromDataSource({ id: record.id });
message.success(i18n('common.text.successfullyDelete'))
message.success(i18n('common.text.successfullyDelete'));
queryTableList();
}
}}>
<a href='#' onClick={(e) => e.preventDefault()}>
}}
>
<a href="#" onClick={(e) => e.preventDefault()}>
{i18n('common.button.delete')}
</a>
</Popconfirm>
)
}
]
}
),
},
],
},
}),
[props.byId, type],
);
const managementDataByType = type ? managementMap[type] : null
const managementDataByType = type ? managementMap[type] : null;
useEffect(() => {
if (!open) {
return;
}
setSearchInput('');
setPagination({
searchKey: '',
@@ -289,19 +326,24 @@ function UniversalDrawer(props: IProps) {
open: false,
type: managementDataByType?.searchType,
});
}, [props.byId]);
}, [props.byId, type, open]);
useEffect(() => {
queryTableList();
}, [pagination.current, pagination.pageSize, pagination.searchKey, props.byId, type]);
}, [pagination]);
const queryTableList = async () => {
const { searchKey, current: pageNo, pageSize } = pagination;
const queryTableList = async (searchKey?: string) => {
const { current: pageNo, pageSize } = pagination;
const requestApi = managementDataByType?.queryListApi;
if (!requestApi || !isNumber(props.byId)) {
return;
}
let res = await requestApi({ searchKey, pageNo, pageSize, [managementDataByType?.byIdKey]: props.byId });
let res = await requestApi({
searchKey: searchKey || pagination.searchKey,
pageNo,
pageSize,
[managementDataByType?.byIdKey]: props.byId,
});
if (res) {
setDataSource(res?.data ?? []);
}
@@ -310,8 +352,8 @@ function UniversalDrawer(props: IProps) {
const handleSearch = (searchKey: string) => {
setPagination({
...pagination,
searchKey
})
searchKey,
});
};
if (!managementDataByType) {
@@ -323,7 +365,7 @@ function UniversalDrawer(props: IProps) {
<div className={styles.tableTop}>
<Input.Search
style={{ width: '200px' }}
placeholder="输入关键字进行搜索"
placeholder={i18n('team.input.search.placeholder')}
value={searchInput}
onChange={(v) => setSearchInput(v.target.value)}
onSearch={handleSearch}
@@ -336,11 +378,11 @@ function UniversalDrawer(props: IProps) {
setModalInfo({
...modalInfo,
open: true,
type: managementDataByType.searchType
type: managementDataByType.searchType,
});
}}
>
添加
{i18n('common.button.add')}
</Button>
</div>
<Table rowKey={'id'} columns={managementDataByType?.columns} dataSource={dataSource} />
@@ -348,10 +390,10 @@ function UniversalDrawer(props: IProps) {
<UniversalAddModal
{...modalInfo}
onConfirm={(values) => {
managementDataByType.updateListApi({ [managementDataByType.byIdKey]: props.byId, ...values }).then(res => {
message.success('更新成功')
queryTableList()
})
managementDataByType.updateListApi({ [managementDataByType.byIdKey]: props.byId, ...values }).then((res) => {
message.success(i18n('common.tips.updateSuccess'));
queryTableList();
});
}}
onClose={() => {
setModalInfo({

View File

@@ -5,4 +5,5 @@ export * from './database';
export * from './main';
export * from './theme';
export * from './tree';
export * from './setting'
export * from './setting'
export * from './team'

View File

@@ -7,6 +7,7 @@ import ai.chat2db.spi.model.KeyValue;
import ai.chat2db.spi.model.SSHInfo;
import ai.chat2db.spi.model.SSLInfo;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
@@ -101,4 +102,10 @@ public class DataSourceCreateParam {
* @see ai.chat2db.server.domain.api.enums.DataSourceKindEnum
*/
private String kind;
/**
* 环境id
*/
@NotNull
private Long environmentId;
}

View File

@@ -64,7 +64,7 @@ public interface DataSourceService {
* @return
* @throws ai.chat2db.server.tools.common.exception.DataNotFoundException
*/
DataResult<DataSource> queryExistent(@NotNull Long id);
DataResult<DataSource> queryExistent(@NotNull Long id, DataSourceSelector selector);
/**
* 克隆连接

View File

@@ -26,6 +26,7 @@ import ai.chat2db.server.tools.base.wrapper.result.DataResult;
import ai.chat2db.server.tools.base.wrapper.result.ListResult;
import ai.chat2db.server.tools.common.exception.DataNotFoundException;
import ai.chat2db.server.tools.common.model.EasyLambdaQueryWrapper;
import ai.chat2db.server.tools.common.util.ContextUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -59,6 +60,7 @@ public class ChartServiceImpl implements ChartService {
param.setGmtCreate(LocalDateTime.now());
param.setGmtModified(LocalDateTime.now());
param.setDeleted(YesOrNoEnum.NO.getLetter());
param.setUserId(ContextUtils.getUserId());
ChartDO chartDO = chartConverter.param2do(param);
chartMapper.insert(chartDO);
return DataResult.of(chartDO.getId());

View File

@@ -45,6 +45,7 @@ import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
@@ -117,7 +118,7 @@ public class DataSourceServiceImpl implements DataSourceService {
@Override
public DataResult<Long> updateWithPermission(DataSourceUpdateParam param) {
DataSource dataSource = queryExistent(param.getId()).getData();
DataSource dataSource = queryExistent(param.getId(), null).getData();
PermissionUtils.checkOperationPermission(dataSource.getUserId());
DataSourceDO dataSourceDO = dataSourceConverter.param2do(param);
@@ -129,7 +130,7 @@ public class DataSourceServiceImpl implements DataSourceService {
@Override
public ActionResult deleteWithPermission(Long id) {
DataSource dataSource = queryExistent(id).getData();
DataSource dataSource = queryExistent(id, null).getData();
PermissionUtils.checkOperationPermission(dataSource.getUserId());
dataSourceMapper.deleteById(id);
@@ -143,17 +144,20 @@ public class DataSourceServiceImpl implements DataSourceService {
}
@Override
public DataResult<DataSource> queryExistent(Long id) {
public DataResult<DataSource> queryExistent(Long id, DataSourceSelector selector) {
DataResult<DataSource> dataResult = queryById(id);
if (dataResult.getData() == null) {
throw new DataNotFoundException();
}
fillData(Lists.newArrayList(dataResult.getData()), selector);
return dataResult;
}
@Override
public DataResult<Long> copyByIdWithPermission(Long id) {
DataSource dataSource = queryExistent(id).getData();
DataSource dataSource = queryExistent(id, null).getData();
PermissionUtils.checkOperationPermission(dataSource.getUserId());
DataSourceDO dataSourceDO = dataSourceMapper.selectById(id);
@@ -191,7 +195,7 @@ public class DataSourceServiceImpl implements DataSourceService {
IPage<DataSourceDO> iPage = dataSourceCustomMapper.selectPageWithPermission(
new Page<>(param.getPageNo(), param.getPageSize()),
BooleanUtils.isTrue(loginUser.getAdmin()), loginUser.getId(), param.getSearchKey(),param.getKind(),
BooleanUtils.isTrue(loginUser.getAdmin()), loginUser.getId(), param.getSearchKey(), param.getKind(),
EasySqlUtils.orderBy(param.getOrderByList()));
List<DataSource> dataSources = dataSourceConverter.do2dto(iPage.getRecords());

View File

@@ -0,0 +1,22 @@
package ai.chat2db.server.start.test.dto;
import java.io.Serial;
import java.io.Serializable;
import ai.chat2db.server.tools.base.constant.EasyToolsConstant;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class TestDTO implements Serializable {
@Serial
private static final long serialVersionUID = EasyToolsConstant.SERIAL_VERSION_UID;
private String name;
}

View File

@@ -0,0 +1,27 @@
package ai.chat2db.server.admin.api.controller.common.request;
import ai.chat2db.server.domain.api.enums.AccessObjectTypeEnum;
import ai.chat2db.server.tools.base.wrapper.request.PageQueryRequest;
import lombok.Data;
/**
* Common pagination query
*
* @author Jiaju Zhuang
*/
@Data
public class TeamUserPageQueryRequest extends PageQueryRequest {
/**
* 授权类型
*
* @see AccessObjectTypeEnum
*/
private String type;
/**
* searchKey
*/
private String searchKey;
}

View File

@@ -0,0 +1,50 @@
package ai.chat2db.server.admin.api.controller.common.vo;
import java.io.Serial;
import java.io.Serializable;
import ai.chat2db.server.domain.api.enums.AccessObjectTypeEnum;
import ai.chat2db.server.tools.base.constant.EasyToolsConstant;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
* DataSource Access Object
* It could be a user or a team
*
* @author Jiaju Zhuang
*/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class TeamUserListVO implements Serializable {
@Serial
private static final long serialVersionUID = EasyToolsConstant.SERIAL_VERSION_UID;
/**
* 授权id,根据类型区分是用户还是团队
*/
private Long id;
/**
* 授权类型
*
* @see AccessObjectTypeEnum
*/
private String type;
/**
* The name of the code that belongs to the authorization type, such as user account, team code
*/
private String code;
/**
* Code that belongs to the authorization type, such as user name, team name
*/
private String name;
}

View File

@@ -0,0 +1,50 @@
package ai.chat2db.server.admin.api.controller.datasource.converter;
import ai.chat2db.server.admin.api.controller.datasource.request.DataSourceAccessBatchCreateRequest;
import ai.chat2db.server.admin.api.controller.datasource.request.DataSourceAccessPageQueryRequest;
import ai.chat2db.server.admin.api.controller.datasource.vo.DataSourceAccessPageQueryVO;
import ai.chat2db.server.domain.api.enums.DataSourceKindEnum;
import ai.chat2db.server.domain.api.model.DataSourceAccess;
import ai.chat2db.server.domain.api.param.datasource.access.DataSourceAccessBatchCreatParam;
import ai.chat2db.server.domain.api.param.datasource.access.DataSourceAccessComprehensivePageQueryParam;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
/**
* converter
*
* @author Jiaju Zhuang
*/
@Mapper(componentModel = "spring", imports = {DataSourceKindEnum.class})
public abstract class DataSourceAccessAdminConverter {
/**
* convert
*
* @param request
* @return
*/
@Mappings({
@Mapping(source = "searchKey", target = "userOrTeamSearchKey"),
@Mapping(target = "enableReturnCount", expression = "java(true)"),
})
public abstract DataSourceAccessComprehensivePageQueryParam request2param(DataSourceAccessPageQueryRequest request);
/**
* convert
*
* @param request
* @return
*/
public abstract DataSourceAccessBatchCreatParam request2param(DataSourceAccessBatchCreateRequest request);
/**
* conversion
*
* @param dto
* @return
*/
public abstract DataSourceAccessPageQueryVO dto2vo(DataSourceAccess dto);
}

View File

@@ -0,0 +1,76 @@
package ai.chat2db.server.admin.api.controller.datasource.converter;
import ai.chat2db.server.admin.api.controller.datasource.request.DataSourceCreateRequest;
import ai.chat2db.server.admin.api.controller.datasource.request.DataSourceUpdateRequest;
import ai.chat2db.server.admin.api.controller.datasource.vo.DataSourcePageQueryVO;
import ai.chat2db.server.common.api.controller.request.CommonPageQueryRequest;
import ai.chat2db.server.domain.api.enums.DataSourceKindEnum;
import ai.chat2db.server.domain.api.model.DataSource;
import ai.chat2db.server.domain.api.param.datasource.DataSourceCreateParam;
import ai.chat2db.server.domain.api.param.datasource.DataSourcePageQueryParam;
import ai.chat2db.server.domain.api.param.datasource.DataSourceUpdateParam;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
/**
* converter
*
* @author Jiaju Zhuang
*/
@Mapper(componentModel = "spring",imports = {DataSourceKindEnum.class})
public abstract class DataSourceAdminConverter {
/**
* conversion
*
* @param request
* @return
*/
@Mappings({
@Mapping(target = "enableReturnCount", expression = "java(true)"),
})
public abstract DataSourcePageQueryParam request2param(CommonPageQueryRequest request);
/**
* conversion
*
* @param request
* @return
*/
@Mappings({
@Mapping(target = "enableReturnCount", expression = "java(true)"),
})
public abstract DataSourcePageQueryParam request2paramAccess(CommonPageQueryRequest request);
/**
* conversion
*
* @param dto
* @return
*/
public abstract DataSourcePageQueryVO dto2vo(DataSource dto);
/**
* 参数转换
*
* @param request
* @return
*/
@Mappings({
@Mapping(source = "user", target = "userName"),
@Mapping(target = "kind", expression = "java(DataSourceKindEnum.SHARED.getCode())"),
})
public abstract DataSourceCreateParam createReq2param(DataSourceCreateRequest request);
/**
* 参数转换
*
* @param request
* @return
*/
@Mappings({
@Mapping(source = "user", target = "userName")
})
public abstract DataSourceUpdateParam updateReq2param(DataSourceUpdateRequest request);
}

View File

@@ -0,0 +1,33 @@
package ai.chat2db.server.admin.api.controller.datasource.request;
import java.util.List;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
* create
*
* @author Jiaju Zhuang
*/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class DataSourceAccessBatchCreateRequest {
/**
* 数据源id
*/
@NotNull
private Long dataSourceId;
/**
* DataSource Access Object
*/
@NotNull
private List<DataSourceAccessObjectRequest> accessObjectList;
}

View File

@@ -0,0 +1,41 @@
package ai.chat2db.server.admin.api.controller.datasource.request;
import java.io.Serial;
import java.io.Serializable;
import ai.chat2db.server.domain.api.enums.AccessObjectTypeEnum;
import ai.chat2db.server.tools.base.constant.EasyToolsConstant;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
* DataSource Access Object
* It could be a user or a team
*
* @author Jiaju Zhuang
*/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class DataSourceAccessObjectRequest implements Serializable {
@Serial
private static final long serialVersionUID = EasyToolsConstant.SERIAL_VERSION_UID;
/**
* 授权id,根据类型区分是用户还是团队
*/
private Long id;
/**
* 授权类型
*
* @see AccessObjectTypeEnum
*/
private String type;
}

View File

@@ -0,0 +1,26 @@
package ai.chat2db.server.admin.api.controller.datasource.request;
import ai.chat2db.server.tools.base.wrapper.request.PageQueryRequest;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
* Common pagination query
*
* @author Jiaju Zhuang
*/
@Data
public class DataSourceAccessPageQueryRequest extends PageQueryRequest {
/**
* 数据源id
*/
@NotNull
private Long dataSourceId;
/**
* searchKey
*/
private String searchKey;
}

View File

@@ -0,0 +1,19 @@
package ai.chat2db.server.admin.api.controller.datasource.request;
import lombok.Data;
/**
* @author moji
* @version ConnectionCloneRequest.java, v 0.1 2022年09月16日 14:23 moji Exp $
* @date 2022/09/16
*/
@Data
public class DataSourceCloneRequest {
/**
* 主键id
*/
private Long id;
}

View File

@@ -0,0 +1,106 @@
package ai.chat2db.server.admin.api.controller.datasource.request;
import java.util.List;
import ai.chat2db.spi.config.DriverConfig;
import ai.chat2db.spi.model.KeyValue;
import ai.chat2db.spi.model.SSHInfo;
import ai.chat2db.spi.model.SSLInfo;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
* @author moji
* @version ConnectionCreateRequest.java, v 0.1 2022年09月16日 14:23 moji Exp $
* @date 2022/09/16
*/
@Data
public class DataSourceCreateRequest {
/**
* 连接别名
*/
private String alias;
/**
* 连接地址
*/
@NotNull
private String url;
/**
* 连接用户名
*/
private String user;
/**
* 密码
*/
@NotNull
private String password;
/**
* 认证类型
*/
private String authenticationType;
/**
* 连接类型
*/
@NotNull
private String type;
/**
* host
*/
private String host;
/**
* port
*/
private String port;
/**
* ssh
*/
private SSHInfo ssh;
/**
* ssh
*/
private SSLInfo ssl;
/**
* sid
*/
private String sid;
/**
* driver
*/
private String driver;
/**
* jdbc版本
*/
private String jdbc;
/**
* 扩展信息
*/
private List<KeyValue> extendInfo;
/**
* 驱动配置
*/
private DriverConfig driverConfig;
/**
* 环境id
*/
@NotNull
private Long environmentId;
}

View File

@@ -0,0 +1,108 @@
package ai.chat2db.server.admin.api.controller.datasource.request;
import java.util.List;
import ai.chat2db.spi.config.DriverConfig;
import ai.chat2db.spi.model.KeyValue;
import ai.chat2db.spi.model.SSHInfo;
import ai.chat2db.spi.model.SSLInfo;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
* @author moji
* @version ConnectionCreateRequest.java, v 0.1 2022年09月16日 14:23 moji Exp $
* @date 2022/09/16
*/
@Data
public class DataSourceUpdateRequest {
/**
* 主键id
*/
@NotNull
private Long id;
/**
* 连接别名
*/
private String alias;
/**
* 连接地址
*/
private String url;
/**
* 连接用户
*/
private String user;
/**
* 密码
*/
private String password;
/**
* 连接类型
*/
private String type;
/**
* 环境类型
*
* @see EnvTypeEnum
*/
private String envType;
/**
* host
*/
private String host;
/**
* port
*/
private String port;
/**
* ssh
*/
private SSHInfo ssh;
/**
* ssh
*/
private SSLInfo ssl;
/**
* sid
*/
private String sid;
/**
* driver
*/
private String driver;
/**
* jdbc版本
*/
private String jdbc;
/**
* 扩展信息
*/
private List<KeyValue> extendInfo;
/**
* 驱动配置
*/
private DriverConfig driverConfig;
/**
* 环境id
*/
@NotNull
private Long environmentId;
}

View File

@@ -0,0 +1,50 @@
package ai.chat2db.server.admin.api.controller.datasource.vo;
import java.io.Serial;
import java.io.Serializable;
import ai.chat2db.server.domain.api.enums.AccessObjectTypeEnum;
import ai.chat2db.server.tools.base.constant.EasyToolsConstant;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
* DataSource Access Object
* It could be a user or a team
*
* @author Jiaju Zhuang
*/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class DataSourceAccessObjectVO implements Serializable {
@Serial
private static final long serialVersionUID = EasyToolsConstant.SERIAL_VERSION_UID;
/**
* 授权id,根据类型区分是用户还是团队
*/
private Long id;
/**
* 授权类型
*
* @see AccessObjectTypeEnum
*/
private String type;
/**
* The name of the code that belongs to the authorization type, such as user account, team code
*/
private String code;
/**
* Code that belongs to the authorization type, such as user name, team name
*/
private String name;
}

View File

@@ -0,0 +1,40 @@
package ai.chat2db.server.admin.api.controller.datasource.vo;
import ai.chat2db.server.domain.api.enums.AccessObjectTypeEnum;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
* Pagination query
*
* @author Jiaju Zhuang
*/
@Data
public class DataSourceAccessPageQueryVO {
/**
* 主键
*/
@NotNull
private Long id;
/**
* 授权类型
*
* @see AccessObjectTypeEnum
*/
@NotNull
private String accessObjectType;
/**
* 授权id,根据类型区分是用户还是团队
*/
@NotNull
private Long accessObjectId;
/**
* 授权对象
*/
@NotNull
private DataSourceAccessObjectVO accessObject;
}

View File

@@ -0,0 +1,39 @@
package ai.chat2db.server.admin.api.controller.datasource.vo;
import ai.chat2db.server.common.api.controller.vo.SimpleEnvironmentVO;
import lombok.Data;
/**
* Pagination query
*
* @author Jiaju Zhuang
*/
@Data
public class DataSourcePageQueryVO {
/**
* 主键id
*/
private Long id;
/**
* 连接别名
*/
private String alias;
/**
* 连接地址
*/
private String url;
/**
* 环境id
*/
private Long environmentId;
/**
* 环境
*/
private SimpleEnvironmentVO environment;
}

View File

@@ -0,0 +1,39 @@
package ai.chat2db.server.admin.api.controller.datasource.vo;
import ai.chat2db.server.common.api.controller.vo.SimpleEnvironmentVO;
import lombok.Data;
/**
* Data Source
*
* @author Jiaju Zhuang
*/
@Data
public class SimpleDataSourceVO {
/**
* 主键id
*/
private Long id;
/**
* 连接别名
*/
private String alias;
/**
* 连接地址
*/
private String url;
/**
* 环境id
*/
private Long environmentId;
/**
* 环境
*/
private SimpleEnvironmentVO environment;
}

View File

@@ -0,0 +1,62 @@
package ai.chat2db.server.admin.api.controller.team.converter;
import ai.chat2db.server.admin.api.controller.team.request.TeamCreateRequest;
import ai.chat2db.server.admin.api.controller.team.request.TeamUpdateRequest;
import ai.chat2db.server.admin.api.controller.team.vo.TeamPageQueryVO;
import ai.chat2db.server.common.api.controller.request.CommonPageQueryRequest;
import ai.chat2db.server.domain.api.enums.DataSourceKindEnum;
import ai.chat2db.server.domain.api.model.Team;
import ai.chat2db.server.domain.api.param.team.TeamCreateParam;
import ai.chat2db.server.domain.api.param.team.TeamPageQueryParam;
import ai.chat2db.server.domain.api.param.team.TeamUpdateParam;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
/**
* converter
*
* @author Jiaju Zhuang
*/
@Mapper(componentModel = "spring",imports = {DataSourceKindEnum.class})
public abstract class TeamAdminConverter {
/**
* conversion
*
* @param request
* @return
*/
@Mappings({
@Mapping(target = "enableReturnCount", expression = "java(true)"),
})
public abstract TeamPageQueryParam request2param(CommonPageQueryRequest request);
/**
* conversion
*
* @param dto
* @return
*/
public abstract TeamPageQueryVO dto2vo(Team dto);
/**
* conversion
*
* @param request
* @return
*/
public abstract TeamCreateParam request2param(TeamCreateRequest request);
/**
* conversion
*
* @param request
* @return
*/
public abstract TeamUpdateParam request2param(TeamUpdateRequest request);
}

View File

@@ -0,0 +1,56 @@
package ai.chat2db.server.admin.api.controller.team.converter;
import ai.chat2db.server.admin.api.controller.datasource.request.DataSourceAccessBatchCreateRequest;
import ai.chat2db.server.admin.api.controller.team.request.TeamPageCommonQueryRequest;
import ai.chat2db.server.admin.api.controller.team.vo.TeamDataSourcePageQueryVO;
import ai.chat2db.server.domain.api.enums.AccessObjectTypeEnum;
import ai.chat2db.server.domain.api.enums.DataSourceKindEnum;
import ai.chat2db.server.domain.api.model.DataSourceAccess;
import ai.chat2db.server.domain.api.param.datasource.access.DataSourceAccessBatchCreatParam;
import ai.chat2db.server.domain.api.param.datasource.access.DataSourceAccessComprehensivePageQueryParam;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
/**
* converter
*
* @author Jiaju Zhuang
*/
@Mapper(componentModel = "spring", imports = {DataSourceKindEnum.class, AccessObjectTypeEnum.class})
public abstract class TeamDataSourcesAdminConverter {
/**
* convert
*
* @param request
* @return
*/
@Mappings({
@Mapping(target = "accessObjectId", source = "teamId"),
@Mapping(target = "accessObjectType", expression = "java(AccessObjectTypeEnum.TEAM.name())"),
@Mapping(source = "searchKey", target = "dataSourceSearchKey"),
@Mapping(target = "enableReturnCount", expression = "java(true)"),
})
public abstract DataSourceAccessComprehensivePageQueryParam request2param(TeamPageCommonQueryRequest request);
/**
* convert
*
* @param request
* @return
*/
public abstract DataSourceAccessBatchCreatParam request2param(DataSourceAccessBatchCreateRequest request);
/**
* conversion
*
* @param dto
* @return
*/
@Mappings({
@Mapping(target = "teamId", source = "accessObjectId"),
})
public abstract TeamDataSourcePageQueryVO dto2vo(DataSourceAccess dto);
}

View File

@@ -0,0 +1,49 @@
package ai.chat2db.server.admin.api.controller.team.converter;
import ai.chat2db.server.admin.api.controller.datasource.request.DataSourceAccessBatchCreateRequest;
import ai.chat2db.server.admin.api.controller.team.request.TeamPageCommonQueryRequest;
import ai.chat2db.server.admin.api.controller.team.vo.TeamUserPageQueryVO;
import ai.chat2db.server.domain.api.model.TeamUser;
import ai.chat2db.server.domain.api.param.datasource.access.DataSourceAccessBatchCreatParam;
import ai.chat2db.server.domain.api.param.team.user.TeamUserComprehensivePageQueryParam;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
/**
* converter
*
* @author Jiaju Zhuang
*/
@Mapper(componentModel = "spring")
public abstract class TeamUserAdminConverter {
/**
* convert
*
* @param request
* @return
*/
@Mappings({
@Mapping(source = "searchKey", target = "userSearchKey"),
@Mapping(target = "enableReturnCount", expression = "java(true)"),
})
public abstract TeamUserComprehensivePageQueryParam request2param(TeamPageCommonQueryRequest request);
/**
* convert
*
* @param request
* @return
*/
public abstract DataSourceAccessBatchCreatParam request2param(DataSourceAccessBatchCreateRequest request);
/**
* conversion
*
* @param dto
* @return
*/
public abstract TeamUserPageQueryVO dto2vo(TeamUser dto);
}

View File

@@ -0,0 +1,38 @@
package ai.chat2db.server.admin.api.controller.team.request;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
* create
*
* @author Jiaju Zhuang
*/
@Data
public class TeamCreateRequest {
/**
* 团队编码
*/
@NotNull
private String code;
/**
* 团队名称
*/
@NotNull
private String name;
/**
* 团队状态
*
* @see ai.chat2db.server.domain.api.enums.ValidStatusEnum
*/
@NotNull
private String status;
/**
* 团队描述
*/
private String description;
}

View File

@@ -0,0 +1,34 @@
package ai.chat2db.server.admin.api.controller.team.request;
import java.util.List;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
* create
*
* @author Jiaju Zhuang
*/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class TeamDataSourceBatchCreateRequest {
/**
* team id
*/
@NotNull
private Long teamId;
/**
* Data Source id list
*/
@NotNull
private List<Long> dataSourceIdList;
}

View File

@@ -0,0 +1,25 @@
package ai.chat2db.server.admin.api.controller.team.request;
import ai.chat2db.server.tools.base.wrapper.request.PageQueryRequest;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
* Pagination query
*
* @author Jiaju Zhuang
*/
@Data
public class TeamPageCommonQueryRequest extends PageQueryRequest {
/**
* team id
*/
@NotNull
private Long teamId;
/**
* searchKey
*/
private String searchKey;
}

View File

@@ -0,0 +1,45 @@
package ai.chat2db.server.admin.api.controller.team.request;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
* update
*
* @author Jiaju Zhuang
*/
@Data
public class TeamUpdateRequest {
/**
* 主键
*/
@NotNull
private Long id;
/**
* 团队名称
*/
@NotNull
private String name;
/**
* 团队状态
*
* @see ai.chat2db.server.domain.api.enums.ValidStatusEnum
*/
@NotNull
private String status;
/**
* 角色编码
*
* @see ai.chat2db.server.domain.api.enums.RoleCodeEnum
*/
@NotNull
private String roleCode;
/**
* 团队描述
*/
private String description;
}

View File

@@ -0,0 +1,33 @@
package ai.chat2db.server.admin.api.controller.team.request;
import java.util.List;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
* create
*
* @author Jiaju Zhuang
*/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class TeamUserBatchCreateRequest {
/**
* team id
*/
@NotNull
private Long teamId;
/**
* user id list
*/
@NotNull
private List<Long> userIdList;
}

View File

@@ -0,0 +1,37 @@
package ai.chat2db.server.admin.api.controller.team.vo;
import lombok.Data;
/**
* team
*
* @author Jiaju Zhuang
*/
@Data
public class SimpleTeamVO {
/**
* 主键
*/
private Long id;
/**
* 团队编码
*/
private String code;
/**
* 团队名称
*/
private String name;
/**
* 团队状态
*
* @see ai.chat2db.server.domain.api.enums.ValidStatusEnum
*/
private String status;
}

View File

@@ -0,0 +1,31 @@
package ai.chat2db.server.admin.api.controller.team.vo;
import ai.chat2db.server.admin.api.controller.datasource.vo.SimpleDataSourceVO;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
* Pagination query
*
* @author Jiaju Zhuang
*/
@Data
public class TeamDataSourcePageQueryVO {
/**
* 主键
*/
@NotNull
private Long id;
/**
* team id
*/
private Long teamId;
/**
* Data Source
*/
private SimpleDataSourceVO dataSource;
}

View File

@@ -0,0 +1,57 @@
package ai.chat2db.server.admin.api.controller.team.vo;
import java.util.Date;
import ai.chat2db.server.common.api.controller.vo.SimpleUserVO;
import lombok.Data;
/**
* Pagination query
*
* @author Jiaju Zhuang
*/
@Data
public class TeamPageQueryVO {
/**
* 主键
*/
private Long id;
/**
* 团队编码
*/
private String code;
/**
* 团队名称
*/
private String name;
/**
* 团队状态
*
* @see ai.chat2db.server.domain.api.enums.ValidStatusEnum
*/
private String status;
/**
* 团队描述
*/
private String description;
/**
* 修改时间
*/
private Date gmtModified;
/**
* 修改人用户id
*/
private Long modifiedUserId;
/**
* 修改人用户
*/
private SimpleUserVO modifiedUser;
}

View File

@@ -0,0 +1,28 @@
package ai.chat2db.server.admin.api.controller.team.vo;
import ai.chat2db.server.admin.api.controller.user.vo.SimpleUserVO;
import lombok.Data;
/**
* Pagination query
*
* @author Jiaju Zhuang
*/
@Data
public class TeamUserPageQueryVO {
/**
* 主键
*/
private Long id;
/**
* team id
*/
private Long teamId;
/**
* user
*/
private SimpleUserVO user;
}

View File

@@ -0,0 +1,57 @@
package ai.chat2db.server.admin.api.controller.user.converter;
import ai.chat2db.server.admin.api.controller.user.request.UserCreateRequest;
import ai.chat2db.server.admin.api.controller.user.request.UserUpdateRequest;
import ai.chat2db.server.admin.api.controller.user.vo.UserPageQueryVO;
import ai.chat2db.server.common.api.controller.request.CommonPageQueryRequest;
import ai.chat2db.server.domain.api.model.User;
import ai.chat2db.server.domain.api.param.user.UserCreateParam;
import ai.chat2db.server.domain.api.param.user.UserPageQueryParam;
import ai.chat2db.server.domain.api.param.user.UserUpdateParam;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
/**
* converter
*
* @author Jiaju Zhuang
*/
@Mapper(componentModel = "spring")
public abstract class UserAdminConverter {
/**
* conversion
*
* @param request
* @return
*/
@Mappings({
@Mapping(target = "enableReturnCount", expression = "java(true)"),
})
public abstract UserPageQueryParam request2param(CommonPageQueryRequest request);
/**
* conversion
*
* @param dto
* @return
*/
public abstract UserPageQueryVO dto2vo(User dto);
/**
* conversion
*
* @param request
* @return
*/
public abstract UserCreateParam request2param(UserCreateRequest request);
/**
* conversion
*
* @param request
* @return
*/
public abstract UserUpdateParam request2param(UserUpdateRequest request);
}

View File

@@ -0,0 +1,56 @@
package ai.chat2db.server.admin.api.controller.user.converter;
import ai.chat2db.server.admin.api.controller.datasource.request.DataSourceAccessBatchCreateRequest;
import ai.chat2db.server.admin.api.controller.user.request.UserPageCommonQueryRequest;
import ai.chat2db.server.admin.api.controller.user.vo.UserDataSourcePageQueryVO;
import ai.chat2db.server.domain.api.enums.AccessObjectTypeEnum;
import ai.chat2db.server.domain.api.enums.DataSourceKindEnum;
import ai.chat2db.server.domain.api.model.DataSourceAccess;
import ai.chat2db.server.domain.api.param.datasource.access.DataSourceAccessBatchCreatParam;
import ai.chat2db.server.domain.api.param.datasource.access.DataSourceAccessComprehensivePageQueryParam;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
/**
* converter
*
* @author Jiaju Zhuang
*/
@Mapper(componentModel = "spring", imports = {DataSourceKindEnum.class, AccessObjectTypeEnum.class})
public abstract class UserDataSourcesAdminConverter {
/**
* convert
*
* @param request
* @return
*/
@Mappings({
@Mapping(source = "userId", target = "accessObjectId"),
@Mapping(target = "accessObjectType", expression = "java(AccessObjectTypeEnum.USER.name())"),
@Mapping(source = "searchKey", target = "userOrTeamSearchKey"),
@Mapping(target = "enableReturnCount", expression = "java(true)"),
})
public abstract DataSourceAccessComprehensivePageQueryParam request2param(UserPageCommonQueryRequest request);
/**
* convert
*
* @param request
* @return
*/
public abstract DataSourceAccessBatchCreatParam request2param(DataSourceAccessBatchCreateRequest request);
/**
* conversion
*
* @param dto
* @return
*/
@Mappings({
@Mapping(target = "userId", source = "accessObjectId"),
})
public abstract UserDataSourcePageQueryVO dto2vo(DataSourceAccess dto);
}

View File

@@ -0,0 +1,38 @@
package ai.chat2db.server.admin.api.controller.user.converter;
import ai.chat2db.server.admin.api.controller.user.request.UserPageCommonQueryRequest;
import ai.chat2db.server.admin.api.controller.user.vo.UserTeamPageQueryVO;
import ai.chat2db.server.domain.api.model.TeamUser;
import ai.chat2db.server.domain.api.param.team.user.TeamUserComprehensivePageQueryParam;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
/**
* converter
*
* @author Jiaju Zhuang
*/
@Mapper(componentModel = "spring")
public abstract class UserTeamAdminConverter {
/**
* convert
*
* @param request
* @return
*/
@Mappings({
@Mapping(source = "searchKey", target = "teamSearchKey"),
@Mapping(target = "enableReturnCount", expression = "java(true)"),
})
public abstract TeamUserComprehensivePageQueryParam request2param(UserPageCommonQueryRequest request);
/**
* conversion
*
* @param dto
* @return
*/
public abstract UserTeamPageQueryVO dto2vo(TeamUser dto);
}

View File

@@ -0,0 +1,54 @@
package ai.chat2db.server.admin.api.controller.user.request;
import ai.chat2db.server.domain.api.enums.RoleCodeEnum;
import ai.chat2db.server.domain.api.enums.ValidStatusEnum;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
* create
*@author Jiaju Zhuang
*/
@Data
public class UserCreateRequest {
/**
* 用户名
*/
@NotNull
private String userName;
/**
* 密码
*/
@NotNull
private String password;
/**
* 昵称
*/
@NotNull
private String nickName;
/**
* 邮箱
*/
@NotNull
private String email;
/**
* 角色编码
*
* @see RoleCodeEnum
*/
@NotNull
private String roleCode;
/**
* 用户状态
*
* @see ValidStatusEnum
*/
@NotNull
private String status;
}

View File

@@ -0,0 +1,32 @@
package ai.chat2db.server.admin.api.controller.user.request;
import java.util.List;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
* create
*
* @author Jiaju Zhuang
*/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class UserDataSourceBatchCreateRequest {
/**
* user id
*/
private Long userId;
/**
* Data Source id list
*/
@NotNull
private List<Long> dataSourceIdList;
}

View File

@@ -0,0 +1,25 @@
package ai.chat2db.server.admin.api.controller.user.request;
import ai.chat2db.server.tools.base.wrapper.request.PageQueryRequest;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
* Pagination query
*
* @author Jiaju Zhuang
*/
@Data
public class UserPageCommonQueryRequest extends PageQueryRequest {
/**
* user id
*/
@NotNull
private Long userId;
/**
* searchKey
*/
private String searchKey;
}

View File

@@ -0,0 +1,32 @@
package ai.chat2db.server.admin.api.controller.user.request;
import java.util.List;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
* create
*
* @author Jiaju Zhuang
*/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class UserTeamBatchCreateRequest {
/**
* user id
*/
private Long userId;
/**
* team id list
*/
@NotNull
private List<Long> teamIdList;
}

View File

@@ -0,0 +1,52 @@
package ai.chat2db.server.admin.api.controller.user.request;
import ai.chat2db.server.domain.api.enums.RoleCodeEnum;
import ai.chat2db.server.domain.api.enums.ValidStatusEnum;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
* create
*@author Jiaju Zhuang
*/
@Data
public class UserUpdateRequest {
/**
* 主键
*/
@NotNull
private Long id;
/**
* 密码
*/
private String password;
/**
* 昵称
*/
@NotNull
private String nickName;
/**
* 邮箱
*/
@NotNull
private String email;
/**
* 角色编码
*
* @see RoleCodeEnum
*/
private String roleCode;
/**
* 用户状态
*
* @see ValidStatusEnum
*/
@NotNull
private String status;
}

View File

@@ -0,0 +1,39 @@
package ai.chat2db.server.admin.api.controller.user.vo;
import ai.chat2db.server.domain.api.enums.ValidStatusEnum;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
* user
*
* @author Jiaju Zhuang
*/
@Data
public class SimpleUserVO {
/**
* 主键
*/
@NotNull
private Long id;
/**
* 用户名
*/
@NotNull
private String userName;
/**
* 昵称
*/
@NotNull
private String nickName;
/**
* 用户状态
*
* @see ValidStatusEnum
*/
private String status;
}

View File

@@ -0,0 +1,31 @@
package ai.chat2db.server.admin.api.controller.user.vo;
import ai.chat2db.server.admin.api.controller.datasource.vo.SimpleDataSourceVO;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
* Pagination query
*
* @author Jiaju Zhuang
*/
@Data
public class UserDataSourcePageQueryVO {
/**
* 主键
*/
@NotNull
private Long id;
/**
* user id
*/
private Long userId;
/**
* Data Source
*/
private SimpleDataSourceVO dataSource;
}

View File

@@ -0,0 +1,73 @@
package ai.chat2db.server.admin.api.controller.user.vo;
import java.util.Date;
import ai.chat2db.server.common.api.controller.vo.SimpleUserVO;
import ai.chat2db.server.domain.api.enums.RoleCodeEnum;
import ai.chat2db.server.domain.api.enums.ValidStatusEnum;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
* Pagination query
*
* @author Jiaju Zhuang
*/
@Data
public class UserPageQueryVO {
/**
* 主键
*/
@NotNull
private Long id;
/**
* 用户名
*/
@NotNull
private String userName;
/**
* 昵称
*/
@NotNull
private String nickName;
/**
* 用户状态
*
* @see ValidStatusEnum
*/
private String status;
/**
* 邮箱
*/
@NotNull
private String email;
/**
* 角色编码
*
* @see RoleCodeEnum
*/
private String roleCode;
/**
* 修改时间
*/
private Date gmtModified;
/**
* 修改人用户id
*/
private Long modifiedUserId;
/**
* 修改人用户
*/
private SimpleUserVO modifiedUser;
}

View File

@@ -0,0 +1,28 @@
package ai.chat2db.server.admin.api.controller.user.vo;
import ai.chat2db.server.admin.api.controller.team.vo.SimpleTeamVO;
import lombok.Data;
/**
* Pagination query
*
* @author Jiaju Zhuang
*/
@Data
public class UserTeamPageQueryVO {
/**
* 主键
*/
private Long id;
/**
* user id
*/
private Long userId;
/**
* 团队
*/
private SimpleTeamVO team;
}

View File

@@ -0,0 +1,42 @@
package ai.chat2db.server.common.api.controller;
import ai.chat2db.server.common.api.controller.converter.EnvironmentCommonConverter;
import ai.chat2db.server.common.api.controller.vo.SimpleEnvironmentVO;
import ai.chat2db.server.domain.api.param.EnvironmentPageQueryParam;
import ai.chat2db.server.domain.api.service.EnvironmentService;
import ai.chat2db.server.tools.base.wrapper.result.ListResult;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Basic interface
*
* @author Jiaju Zhuang
*/
@RequestMapping("/api/common")
@RestController
public class CommonCommonController {
@Resource
private EnvironmentService environmentService;
@Resource
private EnvironmentCommonConverter environmentCommonConverter;
/**
* Query all environments
*
* @return
* @version 2.1.0
*/
@GetMapping("/environment/list_all")
public ListResult<SimpleEnvironmentVO> environmentList() {
EnvironmentPageQueryParam environmentPageQueryParam = new EnvironmentPageQueryParam();
environmentPageQueryParam.setPageSize(Integer.MIN_VALUE);
return ListResult.of(
environmentCommonConverter.dto2vo(environmentService.pageQuery(environmentPageQueryParam).getData()));
}
}

View File

@@ -0,0 +1,27 @@
package ai.chat2db.server.common.api.controller.converter;
import java.util.List;
import ai.chat2db.server.common.api.controller.vo.SimpleEnvironmentVO;
import ai.chat2db.server.domain.api.model.Environment;
import lombok.extern.slf4j.Slf4j;
import org.mapstruct.Mapper;
/**
* converter
*
* @author Jiaju Zhuang
*/
@Slf4j
@Mapper(componentModel = "spring")
public abstract class EnvironmentCommonConverter {
/**
* convert
*
* @param list
* @return
*/
public abstract List<SimpleEnvironmentVO> dto2vo(List<Environment> list);
}

View File

@@ -0,0 +1,20 @@
package ai.chat2db.server.common.api.controller.request;
import ai.chat2db.server.tools.base.wrapper.request.PageQueryRequest;
import lombok.Data;
/**
* Common pagination query
*
* @author Jiaju Zhuang
*/
@Data
public class CommonPageQueryRequest extends PageQueryRequest {
/**
* searchKey
*/
private String searchKey;
}

View File

@@ -0,0 +1,18 @@
package ai.chat2db.server.common.api.controller.request;
import lombok.Data;
/**
* Common query
*
* @author Jiaju Zhuang
*/
@Data
public class CommonQueryRequest {
/**
* searchKey
*/
private String searchKey;
}

View File

@@ -0,0 +1,48 @@
package ai.chat2db.server.common.api.controller.vo;
import java.io.Serial;
import java.io.Serializable;
import ai.chat2db.server.domain.api.enums.EnvironmentStyleEnum;
import ai.chat2db.server.tools.base.constant.EasyToolsConstant;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
* Environment
*
* @author Jiaju Zhuang
*/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class SimpleEnvironmentVO implements Serializable {
@Serial
private static final long serialVersionUID = EasyToolsConstant.SERIAL_VERSION_UID;
/**
* 主键
*/
private Long id;
/**
* 环境名称
*/
private String name;
/**
* 环境缩写
*/
private String shortName;
/**
* 样式类型
*
* @see EnvironmentStyleEnum
*/
private String style;
}

View File

@@ -0,0 +1,41 @@
package ai.chat2db.server.common.api.controller.vo;
import java.io.Serial;
import java.io.Serializable;
import ai.chat2db.server.tools.base.constant.EasyToolsConstant;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
* user
*
* @author Jiaju Zhuang
*/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class
SimpleUserVO implements Serializable {
@Serial
private static final long serialVersionUID = EasyToolsConstant.SERIAL_VERSION_UID;
/**
* 主键
*/
private Long id;
/**
* 用户名
*/
private String userName;
/**
* 昵称
*/
private String nickName;
}

View File

@@ -63,7 +63,7 @@ import org.springframework.web.bind.annotation.RestController;
@Slf4j
public class DataSourceController {
private static final DataSourceSelector DATA_SOURCE_SELECTOR= DataSourceSelector.builder()
private static final DataSourceSelector DATA_SOURCE_SELECTOR = DataSourceSelector.builder()
.environment(Boolean.TRUE)
.build();
@@ -104,7 +104,7 @@ public class DataSourceController {
session = SSHManager.getSSHSession(sshWebConverter.toInfo(request));
} catch (Exception e) {
log.error("sshConnect error", e);
throw new ConnectionException("connection.ssh.error",null,e);
throw new ConnectionException("connection.ssh.error", null, e);
} finally {
if (session != null) {
session.disconnect();
@@ -184,11 +184,11 @@ public class DataSourceController {
*/
@GetMapping("/datasource/{id}")
public DataResult<DataSourceVO> queryById(@PathVariable("id") Long id) {
DataResult<DataSource> dataResult = dataSourceService.queryById(id);
DataResult<DataSource> dataResult = dataSourceService.queryExistent(id, DATA_SOURCE_SELECTOR);
DataSourceVO dataSourceVO = dataSourceWebConverter.dto2vo(dataResult.getData());
if(StringUtils.isNotBlank(dataSourceVO.getUser())){
if (StringUtils.isNotBlank(dataSourceVO.getUser())) {
dataSourceVO.setAuthenticationType("1");
}else {
} else {
dataSourceVO.setAuthenticationType("2");
}
return DataResult.of(dataSourceVO);
@@ -212,7 +212,7 @@ public class DataSourceController {
* @param request
* @return
*/
@RequestMapping(value = "/datasource/update",method = {RequestMethod.POST, RequestMethod.PUT})
@RequestMapping(value = "/datasource/update", method = {RequestMethod.POST, RequestMethod.PUT})
public DataResult<Long> update(@RequestBody DataSourceUpdateRequest request) {
DataSourceUpdateParam param = dataSourceWebConverter.updateReq2param(request);
return dataSourceService.updateWithPermission(param);

View File

@@ -101,6 +101,11 @@ public class DataSourceVO {
*/
private DriverConfig driverConfig;
/**
* 环境id
*/
private Long environmentId;
/**
* 环境
*/