机构管理增加数据源管理

This commit is contained in:
曹磊 2025-04-17 15:10:01 +08:00
parent 60bbc359db
commit 2d18d32907
7 changed files with 286 additions and 19 deletions

View File

@ -61,7 +61,6 @@
showFooter.value = data?.showFooter ?? true;
setDrawerProps({ confirmLoading: false, showFooter: showFooter.value });
isUpdate.value = !!data?.isUpdate;
console.log(unref(isUpdate));
if (unref(isUpdate)){
await getDepartOptions('');
}else{
@ -93,7 +92,6 @@
async function getDepartOptions(addFLag){
departOptions.value = [];
const data = await queryDeparts({ addFLag : addFLag });
console.log(data);
Object.assign(departOptions.value, data);
}

View File

@ -10,6 +10,7 @@ enum Api {
testConnection = '/online/cgreport/api/testConnection',
deleteBatch = '/sys/dataSource/deleteBatch',
departList = '/sys/dataSource/departList',
getByCode = '/sys/dataSource/queryBySysOrgCode',
// exportXlsUrl = 'sys/dataSource/exportXls',
// importExcelUrl = 'sys/dataSource/importExcel',
}
@ -90,3 +91,11 @@ export const batchDeleteDataSource = (params, handleSuccess) => {
export const queryDeparts = (params) => {
return defHttp.get({ url: Api.departList, params });
};
/**
*
* @param params
*/
export const getDataSourceByCode = (params) => {
return defHttp.get({ url: Api.getByCode, params });
};

View File

@ -187,7 +187,7 @@ export const formSchema: FormSchema[] = [
field: 'dbUrl',
label: '数据源地址',
required: true,
component: 'Input',
component: 'InputTextArea',
},
{
field: 'dbUsername',
@ -208,3 +208,80 @@ export const formSchema: FormSchema[] = [
component: 'InputTextArea',
},
];
// 数据源基础表单
export function useDataSourceFormSchema() {
const dataSourceFormSchema: FormSchema[] = [
{
field: 'id',
label: 'id',
component: 'Input',
show: false,
},
{
field: 'sysOrgCode',
label: '所属机构',
component: 'Input',
required: true,
show: false,
},
{
field: 'code',
label: '数据源编码',
component: 'Input',
// required: true,
dynamicDisabled: true
},
{
field: 'name',
label: '数据源名称',
component: 'Input',
required: true,
},
{
field: 'dbType',
label: '数据库类型',
component: 'JDictSelectTag',
required: true,
componentProps: ({ formModel }) => {
return {
dictCode: 'database_type',
onChange: (e: any) => {
formModel = Object.assign(formModel, dbDriverMap[e], dbUrlMap[e]);
},
};
},
},
{
field: 'dbDriver',
label: '驱动类',
required: true,
component: 'Input',
},
{
field: 'dbUrl',
label: '数据源地址',
required: true,
component: 'InputTextArea',
},
{
field: 'dbUsername',
label: '用户名',
required: true,
component: 'Input',
},
{
field: 'dbPassword',
label: '密码',
required: true,
component: 'InputPassword',
slot: 'pwd',
},
{
field: 'remark',
label: '备注',
component: 'InputTextArea',
},
];
return { dataSourceFormSchema };
}

View File

@ -0,0 +1,134 @@
<template>
<a-spin :spinning="loading">
<BasicForm @register="registerForm">
<template #pwd="{ model, field }">
<a-row :gutter="8">
<a-col :sm="15" :md="16" :lg="17" :xl="19">
<a-input-password v-model:value="model[field]" placeholder="请输入密码" />
</a-col>
<a-col :sm="9" :md="7" :lg="7" :xl="5">
<a-button type="primary" style="width: 100%" @click="handleTest">测试</a-button>
</a-col>
</a-row>
</template>
</BasicForm>
<div class="j-box-bottom-button offset-20" style="margin-top: 30px">
<div class="j-box-bottom-button-float" :class="[`${prefixCls}`]">
<a-button preIcon="ant-design:sync-outlined" @click="onReset">重置</a-button>
<a-button type="primary" preIcon="ant-design:save-filled" @click="onSubmit">保存</a-button>
</div>
</div>
</a-spin>
</template>
<script lang="ts" setup>
import { watch, computed, inject, ref, unref, onMounted } from 'vue';
import { BasicForm, useForm } from '/@/components/Form/index';
import {
getDataSourceByCode,
saveOrUpdateDataSource,
testConnection
} from '/@/views/monitor/datasource/datasource.api';
import { useDataSourceFormSchema } from '/@/views/monitor/datasource/datasource.data';
import { useDesign } from '/@/hooks/web/useDesign';
import { useMessage } from "@/hooks/web/useMessage";
const { createMessage } = useMessage();
const { prefixCls } = useDesign('j-depart-form-content');
const emit = defineEmits(['success']);
const props = defineProps({
data: { type: Object, default: () => ({}) },
rootTreeData: { type: Array, default: () => [] },
});
const loading = ref<boolean>(false);
//
const isUpdate = ref<boolean>(true);
//
const model = ref<object>({});
//
const [registerForm, { resetFields, setFieldsValue, validateFields, getFieldsValue, validate, updateSchema }] = useForm({
schemas: useDataSourceFormSchema().dataSourceFormSchema,
showActionButtonGroup: false,
});
onMounted(() => {
// data
watch(
() => props.data,
async () => {
let record = unref(props.data);
if (typeof record !== 'object') {
record = {};
}
model.value = record;
await resetFields();
//
let data = await getDataSourceByCode({ sysOrgCode : model.value.orgCode });
if(data == null){
data = {};
data.code = record.orgCode;
data.sysOrgCode = record.orgCode;
isUpdate.value = false;
}
await setFieldsValue({ ...data });
},
{ deep: true, immediate: true }
);
});
//
async function onReset() {
await resetFields();
await setFieldsValue({ ...model.value });
}
async function handleTest() {
let keys = ['dbType', 'dbDriver', 'dbUrl', 'dbName', 'dbUsername', 'dbPassword'];
//
let fieldsValues = getFieldsValue(keys);
let setFields = {};
keys.forEach((key) => (setFields[key] = { value: fieldsValues[key], errors: null }));
await validateFields(keys).then((values) => {
let loading = createMessage.loading('连接中....', 0);
testConnection(values)
.then((data) => {
if (data.success) {
createMessage.success('连接成功');
}
})
.catch((error) => {})
.finally(() => loading());
});
}
//
async function onSubmit() {
try {
loading.value = true;
let values = await validate();
values = Object.assign({}, model.value, values);
console.log(isUpdate.value);
//
await saveOrUpdateDataSource(values, isUpdate.value);
//
emit('success');
Object.assign(model.value, values);
} finally {
loading.value = false;
}
}
</script>
<style lang="less">
// update-begin-author:liusq date:20230625 for: [issues/563]
@prefix-cls: ~'@{namespace}-j-depart-form-content';
/*begin 兼容暗夜模式*/
.@{prefix-cls} {
background: @component-background;
border-top: 1px solid @border-color-base;
}
/*end 兼容暗夜模式*/
// update-end-author:liusq date:20230625 for: [issues/563]
</style>

View File

@ -1,12 +1,12 @@
<template>
<a-card :bordered="false" style="height: 100%">
<div class="j-table-operator" style="width: 100%">
<a-button type="primary" preIcon="ant-design:plus-outlined" @click="onAddDepart">新增</a-button>
<a-button type="primary" preIcon="ant-design:plus-outlined" @click="onAddChildDepart()">添加下级</a-button>
<a-upload name="file" :showUploadList="false" :customRequest="onImportXls">
<a-button type="primary" preIcon="ant-design:plus-outlined" @click="onAddDepart">新增机构</a-button>
<a-button type="primary" preIcon="ant-design:plus-outlined" @click="onAddChildDepart()">新增区域</a-button>
<!-- <a-upload name="file" :showUploadList="false" :customRequest="onImportXls">
<a-button type="primary" preIcon="ant-design:import-outlined">导入</a-button>
</a-upload>
<a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls">导出</a-button>
<a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls">导出</a-button>-->
<template v-if="checkedKeys.length > 0">
<a-dropdown>
<template #overlay>
@ -37,7 +37,7 @@
</template>
</a-alert>
<a-spin :spinning="loading">
<a-input-search placeholder="按部门名称搜索…" style="margin-bottom: 10px" @search="onSearch" />
<a-input-search placeholder="按机构名称搜索…" style="margin-bottom: 10px" @search="onSearch" />
<!--组织机构树-->
<template v-if="treeData.length > 0">
<a-tree
@ -69,7 +69,7 @@
<template #overlay>
<a-menu @click="">
<a-menu-item key="1" @click="onAddChildDepart(dataRef)">添加子级</a-menu-item>
<a-menu-item key="1" @click="onAddChildDepart(dataRef)">添加区域</a-menu-item>
<a-menu-item key="2" @click="visibleTreeKey = treeKey">
<span style="color: red">删除</span>
</a-menu-item>
@ -226,7 +226,7 @@
//
function onAddChildDepart(data = currentDepart.value) {
if (data == null) {
createMessage.warning('请先选择一个部门');
createMessage.warning('请先选择一个机构');
return;
}
const record = { parentId: data.id };

View File

@ -5,7 +5,7 @@ export function useBasicFormSchema() {
const basicFormSchema: FormSchema[] = [
{
field: 'departName',
label: '机构名称',
label: '名称',
component: 'Input',
componentProps: {
placeholder: '请输入机构/部门名称',
@ -14,7 +14,7 @@ export function useBasicFormSchema() {
},
{
field: 'parentId',
label: '上级部门',
label: '上级',
component: 'TreeSelect',
componentProps: {
treeData: [],
@ -24,7 +24,7 @@ export function useBasicFormSchema() {
},
{
field: 'orgCode',
label: '机构编码',
label: '编码',
component: 'Input',
componentProps: {
placeholder: '请输入机构编码',
@ -32,7 +32,7 @@ export function useBasicFormSchema() {
},
{
field: 'orgCategory',
label: '机构类型',
label: '类型',
component: 'RadioButtonGroup',
componentProps: { options: [] },
},
@ -42,6 +42,50 @@ export function useBasicFormSchema() {
component: 'InputNumber',
componentProps: {},
},
{
field: 'operationStartTime',
label: '运营开始时间',
component: 'DatePicker',
componentProps: {
valueFormat: 'YYYY-MM-DD',
style: {
width: '100%',
},
},
},
{
field: 'operationEndTime',
label: '运营到期时间',
component: 'DatePicker',
componentProps: {
valueFormat: 'YYYY-MM-DD',
style: {
width: '100%',
},
},
},
{
field: 'contractStartTime',
label: '合同开始时间',
component: 'DatePicker',
componentProps: {
valueFormat: 'YYYY-MM-DD',
style: {
width: '100%',
},
},
},
{
field: 'contractEndTime',
label: '合同到期时间',
component: 'DatePicker',
componentProps: {
valueFormat: 'YYYY-MM-DD',
style: {
width: '100%',
},
},
},
{
field: 'mobile',
label: '电话',
@ -81,10 +125,9 @@ export function useBasicFormSchema() {
// 机构类型选项
export const orgCategoryOptions = {
// 一级部门
root: [{ value: '1', label: '公司' }],
root: [{ value: '1', label: '机构' }],
// 子级部门
child: [
{ value: '2', label: '部门' },
{ value: '3', label: '岗位' },
{ value: '2', label: '区域' },
],
};

View File

@ -11,14 +11,19 @@
<DepartFormTab :data="departData" :rootTreeData="rootTreeData" @success="onSuccess" />
</div>
</a-tab-pane>
<a-tab-pane tab="部门权限" key="role-info">
<a-tab-pane tab="机构权限" key="role-info">
<div style="padding: 0 20px 20px">
<DepartRuleTab :data="departData" />
</div>
</a-tab-pane>
<a-tab-pane tab="数据源管理" key="data-info" v-if="departData.orgCategory == 1">
<div style="padding: 0 20px 20px">
<DataSourceTab :data="departData" />
</div>
</a-tab-pane>
</a-tabs>
<div v-show="departData == null" style="padding-top: 40px">
<a-empty description="尚未选择部门" />
<a-empty description="尚未选择机构" />
</div>
</div>
</a-col>
@ -31,6 +36,7 @@
import DepartLeftTree from './components/DepartLeftTree.vue';
import DepartFormTab from './components/DepartFormTab.vue';
import DepartRuleTab from './components/DepartRuleTab.vue';
import DataSourceTab from './components/DataSourceTab.vue';
const { prefixCls } = useDesign('depart-manage');
provide('prefixCls', prefixCls);