mirror of
https://gitee.com/dromara/mayfly-go
synced 2025-11-04 00:10:25 +08:00
refactor: 标签资源重构
This commit is contained in:
@@ -22,6 +22,8 @@ export class EnumValue {
|
|||||||
*/
|
*/
|
||||||
tag: EnumValueTag;
|
tag: EnumValueTag;
|
||||||
|
|
||||||
|
extra: any;
|
||||||
|
|
||||||
constructor(value: any, label: string) {
|
constructor(value: any, label: string) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
this.label = label;
|
this.label = label;
|
||||||
@@ -53,6 +55,11 @@ export class EnumValue {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setExtra(extra: any): EnumValue {
|
||||||
|
this.extra = extra;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public static of(value: any, label: string): EnumValue {
|
public static of(value: any, label: string): EnumValue {
|
||||||
return new EnumValue(value, label);
|
return new EnumValue(value, label);
|
||||||
}
|
}
|
||||||
@@ -60,11 +67,12 @@ export class EnumValue {
|
|||||||
/**
|
/**
|
||||||
* 根据枚举值获取指定枚举值对象
|
* 根据枚举值获取指定枚举值对象
|
||||||
*
|
*
|
||||||
* @param enumValues 所有枚举值
|
* @param enums 枚举对象
|
||||||
* @param value 需要匹配的枚举值
|
* @param value 需要匹配的枚举值
|
||||||
* @returns 枚举值对象
|
* @returns 枚举值对象
|
||||||
*/
|
*/
|
||||||
static getEnumByValue(enumValues: EnumValue[], value: any): EnumValue | null {
|
static getEnumByValue(enums: any, value: any): EnumValue | null {
|
||||||
|
const enumValues = Object.values(enums) as any;
|
||||||
for (let enumValue of enumValues) {
|
for (let enumValue of enumValues) {
|
||||||
if (enumValue.value == value) {
|
if (enumValue.value == value) {
|
||||||
return enumValue;
|
return enumValue;
|
||||||
|
|||||||
@@ -2,8 +2,9 @@ import EnumValue from './Enum';
|
|||||||
|
|
||||||
// 标签关联的资源类型
|
// 标签关联的资源类型
|
||||||
export const TagResourceTypeEnum = {
|
export const TagResourceTypeEnum = {
|
||||||
Machine: EnumValue.of(1, '机器'),
|
Tag: EnumValue.of(-1, '标签').setExtra({ icon: 'CollectionTag' }),
|
||||||
Db: EnumValue.of(2, '数据库'),
|
Machine: EnumValue.of(1, '机器').setExtra({ icon: 'Monitor' }),
|
||||||
Redis: EnumValue.of(3, 'redis'),
|
Db: EnumValue.of(2, '数据库').setExtra({ icon: 'Coin' }),
|
||||||
Mongo: EnumValue.of(4, 'mongo'),
|
Redis: EnumValue.of(3, 'redis').setExtra({ icon: 'iconfont icon-redis' }),
|
||||||
|
Mongo: EnumValue.of(4, 'mongo').setExtra({ icon: 'iconfont icon-mongo' }),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,3 +2,8 @@ export const AccountUsernamePattern = {
|
|||||||
pattern: /^[a-zA-Z0-9_]{5,20}$/g,
|
pattern: /^[a-zA-Z0-9_]{5,20}$/g,
|
||||||
message: '只允许输入5-20位大小写字母、数字、下划线',
|
message: '只允许输入5-20位大小写字母、数字、下划线',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const ResourceCodePattern = {
|
||||||
|
pattern: /^[a-zA-Z0-9_]{1,32}$/g,
|
||||||
|
message: '只允许输入1-32位大小写字母、数字、下划线',
|
||||||
|
};
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ onMounted(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const convert = (value: any) => {
|
const convert = (value: any) => {
|
||||||
const enumValue = EnumValue.getEnumByValue(Object.values(props.enums as any) as any, value) as any;
|
const enumValue = EnumValue.getEnumByValue(props.enums, value) as any;
|
||||||
if (!enumValue) {
|
if (!enumValue) {
|
||||||
state.enumLabel = '-';
|
state.enumLabel = '-';
|
||||||
state.type = 'danger';
|
state.type = 'danger';
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ onMounted(async () => {
|
|||||||
state.selectTags = props.selectTags;
|
state.selectTags = props.selectTags;
|
||||||
}
|
}
|
||||||
|
|
||||||
state.tags = await tagApi.getTagTrees.request(null);
|
state.tags = await tagApi.getTagTrees.request({ type: -1 });
|
||||||
});
|
});
|
||||||
|
|
||||||
const changeTag = () => {
|
const changeTag = () => {
|
||||||
|
|||||||
@@ -47,6 +47,14 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item prop="code" label="编号" required>
|
||||||
|
<el-input
|
||||||
|
:disabled="form.id"
|
||||||
|
v-model.trim="form.code"
|
||||||
|
placeholder="请输入机器编号 (数字字母下划线), 不可修改"
|
||||||
|
auto-complete="off"
|
||||||
|
></el-input>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item prop="name" label="别名" required>
|
<el-form-item prop="name" label="别名" required>
|
||||||
<el-input v-model.trim="form.name" placeholder="请输入数据库别名" auto-complete="off"></el-input>
|
<el-input v-model.trim="form.name" placeholder="请输入数据库别名" auto-complete="off"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -96,6 +104,7 @@ import TagTreeSelect from '../component/TagTreeSelect.vue';
|
|||||||
import type { CheckboxValueType } from 'element-plus';
|
import type { CheckboxValueType } from 'element-plus';
|
||||||
import ProcdefSelectFormItem from '@/views/flow/components/ProcdefSelectFormItem.vue';
|
import ProcdefSelectFormItem from '@/views/flow/components/ProcdefSelectFormItem.vue';
|
||||||
import { DbType } from '@/views/ops/db/dialect';
|
import { DbType } from '@/views/ops/db/dialect';
|
||||||
|
import { ResourceCodePattern } from '@/common/pattern';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
visible: {
|
visible: {
|
||||||
@@ -128,7 +137,18 @@ const rules = {
|
|||||||
trigger: ['change', 'blur'],
|
trigger: ['change', 'blur'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
code: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入编码',
|
||||||
|
trigger: ['change', 'blur'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pattern: ResourceCodePattern.pattern,
|
||||||
|
message: ResourceCodePattern.message,
|
||||||
|
trigger: ['blur'],
|
||||||
|
},
|
||||||
|
],
|
||||||
name: [
|
name: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
|
|||||||
@@ -239,10 +239,15 @@ const perms = {
|
|||||||
restoreDb: 'db:restore',
|
restoreDb: 'db:restore',
|
||||||
};
|
};
|
||||||
|
|
||||||
const searchItems = [getTagPathSearchItem(TagResourceTypeEnum.Db.value), SearchItem.slot('instanceId', '实例', 'instanceSelect')];
|
const searchItems = [
|
||||||
|
getTagPathSearchItem(TagResourceTypeEnum.Db.value),
|
||||||
|
SearchItem.slot('instanceId', '实例', 'instanceSelect'),
|
||||||
|
SearchItem.input('code', '编号'),
|
||||||
|
];
|
||||||
|
|
||||||
const columns = ref([
|
const columns = ref([
|
||||||
TableColumn.new('tags[0].tagPath', '关联标签').isSlot('tagPath').setAddWidth(20),
|
TableColumn.new('tags[0].tagPath', '关联标签').isSlot('tagPath').setAddWidth(20),
|
||||||
|
TableColumn.new('code', '编号'),
|
||||||
TableColumn.new('name', '名称'),
|
TableColumn.new('name', '名称'),
|
||||||
TableColumn.new('type', '类型').isSlot().setAddWidth(-15).alignCenter(),
|
TableColumn.new('type', '类型').isSlot().setAddWidth(-15).alignCenter(),
|
||||||
TableColumn.new('instanceName', '实例名'),
|
TableColumn.new('instanceName', '实例名'),
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<el-dialog :title="title" v-model="dialogVisible" :close-on-click-modal="false" :destroy-on-close="true" :before-close="cancel" width="650px">
|
<el-drawer :title="title" v-model="dialogVisible" :before-close="cancel" :destroy-on-close="true" :close-on-click-modal="false">
|
||||||
|
<template #header>
|
||||||
|
<DrawerHeader :header="title" :back="cancel" />
|
||||||
|
</template>
|
||||||
|
|
||||||
<el-form :model="form" ref="machineForm" :rules="rules" label-width="auto">
|
<el-form :model="form" ref="machineForm" :rules="rules" label-width="auto">
|
||||||
<el-tabs v-model="tabActiveName">
|
<el-tabs v-model="tabActiveName">
|
||||||
<el-tab-pane label="基础信息" name="basic">
|
<el-tab-pane label="基础信息" name="basic">
|
||||||
@@ -18,19 +22,25 @@
|
|||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item prop="protocol" label="机器类型" required>
|
<el-form-item prop="code" label="编号" required>
|
||||||
<el-radio-group v-model="form.protocol" @change="handleChangeProtocol">
|
<el-input
|
||||||
<el-radio :value="1">SSH</el-radio>
|
:disabled="form.id"
|
||||||
<el-radio :value="2">RDP</el-radio>
|
v-model.trim="form.code"
|
||||||
<!-- <el-radio :value="3">VNC</el-radio> -->
|
placeholder="请输入机器编号 (数字字母下划线), 不可修改"
|
||||||
</el-radio-group>
|
auto-complete="off"
|
||||||
|
></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item prop="name" label="名称" required>
|
<el-form-item prop="name" label="名称" required>
|
||||||
<el-input v-model.trim="form.name" placeholder="请输入机器别名" auto-complete="off"></el-input>
|
<el-input v-model.trim="form.name" placeholder="请输入机器别名" auto-complete="off"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item prop="protocol" label="协议" required>
|
||||||
|
<el-radio-group v-model="form.protocol" @change="handleChangeProtocol">
|
||||||
|
<el-radio v-for="item in MachineProtocolEnum" :key="item.value" :label="item.label" :value="item.value"></el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item prop="ip" label="ip" required>
|
<el-form-item prop="ip" label="ip" required>
|
||||||
<el-col :span="18">
|
<el-col :span="18">
|
||||||
<el-input :disabled="form.id" v-model.trim="form.ip" placeholder="主机ip" auto-complete="off"> </el-input>
|
<el-input v-model.trim="form.ip" placeholder="主机ip" auto-complete="off"> </el-input>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col style="text-align: center" :span="1">:</el-col>
|
<el-col style="text-align: center" :span="1">:</el-col>
|
||||||
<el-col :span="5">
|
<el-col :span="5">
|
||||||
@@ -81,7 +91,7 @@
|
|||||||
<el-button type="primary" :loading="saveBtnLoading" @click="btnOk">确 定</el-button>
|
<el-button type="primary" :loading="saveBtnLoading" @click="btnOk">确 定</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-drawer>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -92,6 +102,9 @@ import { ElMessage } from 'element-plus';
|
|||||||
import TagTreeSelect from '../component/TagTreeSelect.vue';
|
import TagTreeSelect from '../component/TagTreeSelect.vue';
|
||||||
import SshTunnelSelect from '../component/SshTunnelSelect.vue';
|
import SshTunnelSelect from '../component/SshTunnelSelect.vue';
|
||||||
import AuthCertSelect from './authcert/AuthCertSelect.vue';
|
import AuthCertSelect from './authcert/AuthCertSelect.vue';
|
||||||
|
import { MachineProtocolEnum } from './enums';
|
||||||
|
import DrawerHeader from '@/components/drawer-header/DrawerHeader.vue';
|
||||||
|
import { ResourceCodePattern } from '@/common/pattern';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
visible: {
|
visible: {
|
||||||
@@ -116,6 +129,18 @@ const rules = {
|
|||||||
trigger: ['change'],
|
trigger: ['change'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
code: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入编码',
|
||||||
|
trigger: ['change', 'blur'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pattern: ResourceCodePattern.pattern,
|
||||||
|
message: ResourceCodePattern.message,
|
||||||
|
trigger: ['blur'],
|
||||||
|
},
|
||||||
|
],
|
||||||
name: [
|
name: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
@@ -134,7 +159,7 @@ const rules = {
|
|||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: '请输入主机ip和端口',
|
message: '请输入主机ip和端口',
|
||||||
trigger: ['change', 'blur'],
|
trigger: ['blur'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
authCertId: [
|
authCertId: [
|
||||||
@@ -263,11 +288,11 @@ const getReqForm = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleChangeProtocol = (val: any) => {
|
const handleChangeProtocol = (val: any) => {
|
||||||
if (val == 1) {
|
if (val == MachineProtocolEnum.Ssh.value) {
|
||||||
state.form.port = 22;
|
state.form.port = 22;
|
||||||
} else if (val == 2) {
|
} else if (val == MachineProtocolEnum.Rdp.value) {
|
||||||
state.form.port = 3389;
|
state.form.port = 3389;
|
||||||
} else if (val == 3) {
|
} else {
|
||||||
state.form.port = 5901;
|
state.form.port = 5901;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -251,10 +251,16 @@ const perms = {
|
|||||||
terminal: 'machine:terminal',
|
terminal: 'machine:terminal',
|
||||||
};
|
};
|
||||||
|
|
||||||
const searchItems = [getTagPathSearchItem(TagResourceTypeEnum.Machine.value), SearchItem.input('ip', 'IP'), SearchItem.input('name', '名称')];
|
const searchItems = [
|
||||||
|
getTagPathSearchItem(TagResourceTypeEnum.Machine.value),
|
||||||
|
SearchItem.input('code', '编号'),
|
||||||
|
SearchItem.input('ip', 'IP'),
|
||||||
|
SearchItem.input('name', '名称'),
|
||||||
|
];
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
TableColumn.new('tags[0].tagPath', '关联标签').isSlot('tagPath').setAddWidth(20),
|
TableColumn.new('tags[0].tagPath', '关联标签').isSlot('tagPath').setAddWidth(20),
|
||||||
|
TableColumn.new('code', '编号'),
|
||||||
TableColumn.new('name', '名称'),
|
TableColumn.new('name', '名称'),
|
||||||
TableColumn.new('ipPort', 'ip:port').isSlot().setAddWidth(50),
|
TableColumn.new('ipPort', 'ip:port').isSlot().setAddWidth(50),
|
||||||
TableColumn.new('stat', '运行状态').isSlot().setAddWidth(55),
|
TableColumn.new('stat', '运行状态').isSlot().setAddWidth(55),
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
import { EnumValue } from '@/common/Enum';
|
import { EnumValue } from '@/common/Enum';
|
||||||
|
|
||||||
|
export const MachineProtocolEnum = {
|
||||||
|
Ssh: EnumValue.of(1, 'SSH'),
|
||||||
|
Rdp: EnumValue.of(2, 'RDP'),
|
||||||
|
};
|
||||||
|
|
||||||
// 脚本执行结果类型
|
// 脚本执行结果类型
|
||||||
export const ScriptResultEnum = {
|
export const ScriptResultEnum = {
|
||||||
Result: EnumValue.of(1, '有结果'),
|
Result: EnumValue.of(1, '有结果'),
|
||||||
|
|||||||
@@ -17,7 +17,14 @@
|
|||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item prop="code" label="编号" required>
|
||||||
|
<el-input
|
||||||
|
:disabled="form.id"
|
||||||
|
v-model.trim="form.code"
|
||||||
|
placeholder="请输入机器编号 (数字字母下划线), 不可修改"
|
||||||
|
auto-complete="off"
|
||||||
|
></el-input>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item prop="name" label="名称" required>
|
<el-form-item prop="name" label="名称" required>
|
||||||
<el-input v-model.trim="form.name" placeholder="请输入名称" auto-complete="off"></el-input>
|
<el-input v-model.trim="form.name" placeholder="请输入名称" auto-complete="off"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -57,6 +64,7 @@ import { mongoApi } from './api';
|
|||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
||||||
import TagTreeSelect from '../component/TagTreeSelect.vue';
|
import TagTreeSelect from '../component/TagTreeSelect.vue';
|
||||||
import SshTunnelSelect from '../component/SshTunnelSelect.vue';
|
import SshTunnelSelect from '../component/SshTunnelSelect.vue';
|
||||||
|
import { ResourceCodePattern } from '@/common/pattern';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
visible: {
|
visible: {
|
||||||
@@ -81,6 +89,18 @@ const rules = {
|
|||||||
trigger: ['change', 'blur'],
|
trigger: ['change', 'blur'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
code: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入编码',
|
||||||
|
trigger: ['change', 'blur'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pattern: ResourceCodePattern.pattern,
|
||||||
|
message: ResourceCodePattern.message,
|
||||||
|
trigger: ['blur'],
|
||||||
|
},
|
||||||
|
],
|
||||||
name: [
|
name: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ import { TableColumn } from '@/components/pagetable';
|
|||||||
import { TagResourceTypeEnum } from '@/common/commonEnum';
|
import { TagResourceTypeEnum } from '@/common/commonEnum';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import { getTagPathSearchItem } from '../component/tag';
|
import { getTagPathSearchItem } from '../component/tag';
|
||||||
|
import { SearchItem } from '@/components/SearchForm';
|
||||||
|
|
||||||
const MongoEdit = defineAsyncComponent(() => import('./MongoEdit.vue'));
|
const MongoEdit = defineAsyncComponent(() => import('./MongoEdit.vue'));
|
||||||
const MongoDbs = defineAsyncComponent(() => import('./MongoDbs.vue'));
|
const MongoDbs = defineAsyncComponent(() => import('./MongoDbs.vue'));
|
||||||
@@ -67,10 +68,11 @@ const props = defineProps({
|
|||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const pageTableRef: Ref<any> = ref(null);
|
const pageTableRef: Ref<any> = ref(null);
|
||||||
|
|
||||||
const searchItems = [getTagPathSearchItem(TagResourceTypeEnum.Mongo.value)];
|
const searchItems = [getTagPathSearchItem(TagResourceTypeEnum.Mongo.value), SearchItem.input('code', '编号')];
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
TableColumn.new('tags[0].tagPath', '关联标签').isSlot('tagPath').setAddWidth(20),
|
TableColumn.new('tags[0].tagPath', '关联标签').isSlot('tagPath').setAddWidth(20),
|
||||||
|
TableColumn.new('code', '编号'),
|
||||||
TableColumn.new('name', '名称'),
|
TableColumn.new('name', '名称'),
|
||||||
TableColumn.new('uri', '连接uri'),
|
TableColumn.new('uri', '连接uri'),
|
||||||
TableColumn.new('createTime', '创建时间').isTime(),
|
TableColumn.new('createTime', '创建时间').isTime(),
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<el-dialog :title="title" v-model="dialogVisible" :before-close="cancel" :close-on-click-modal="false" :destroy-on-close="true" width="38%">
|
<el-drawer :title="title" v-model="dialogVisible" :before-close="cancel" :destroy-on-close="true" :close-on-click-modal="false">
|
||||||
|
<template #header>
|
||||||
|
<DrawerHeader :header="title" :back="cancel" />
|
||||||
|
</template>
|
||||||
|
|
||||||
<el-form :model="form" ref="redisForm" :rules="rules" label-width="auto">
|
<el-form :model="form" ref="redisForm" :rules="rules" label-width="auto">
|
||||||
<el-tabs v-model="tabActiveName">
|
<el-tabs v-model="tabActiveName">
|
||||||
<el-tab-pane label="基础信息" name="basic">
|
<el-tab-pane label="基础信息" name="basic">
|
||||||
@@ -17,6 +21,14 @@
|
|||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item prop="code" label="编号" required>
|
||||||
|
<el-input
|
||||||
|
:disabled="form.id"
|
||||||
|
v-model.trim="form.code"
|
||||||
|
placeholder="请输入机器编号 (数字字母下划线), 不可修改"
|
||||||
|
auto-complete="off"
|
||||||
|
></el-input>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item prop="name" label="名称" required>
|
<el-form-item prop="name" label="名称" required>
|
||||||
<el-input v-model.trim="form.name" placeholder="请输入redis名称" auto-complete="off"></el-input>
|
<el-input v-model.trim="form.name" placeholder="请输入redis名称" auto-complete="off"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -90,7 +102,7 @@
|
|||||||
<el-button type="primary" :loading="saveBtnLoading" @click="btnOk">确 定</el-button>
|
<el-button type="primary" :loading="saveBtnLoading" @click="btnOk">确 定</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-drawer>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -102,6 +114,8 @@ import { RsaEncrypt } from '@/common/rsa';
|
|||||||
import TagTreeSelect from '../component/TagTreeSelect.vue';
|
import TagTreeSelect from '../component/TagTreeSelect.vue';
|
||||||
import SshTunnelSelect from '../component/SshTunnelSelect.vue';
|
import SshTunnelSelect from '../component/SshTunnelSelect.vue';
|
||||||
import ProcdefSelectFormItem from '@/views/flow/components/ProcdefSelectFormItem.vue';
|
import ProcdefSelectFormItem from '@/views/flow/components/ProcdefSelectFormItem.vue';
|
||||||
|
import { ResourceCodePattern } from '@/common/pattern';
|
||||||
|
import DrawerHeader from '@/components/drawer-header/DrawerHeader.vue';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
visible: {
|
visible: {
|
||||||
@@ -125,6 +139,18 @@ const rules = {
|
|||||||
trigger: ['blur', 'change'],
|
trigger: ['blur', 'change'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
code: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入编码',
|
||||||
|
trigger: ['change', 'blur'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pattern: ResourceCodePattern.pattern,
|
||||||
|
message: ResourceCodePattern.message,
|
||||||
|
trigger: ['blur'],
|
||||||
|
},
|
||||||
|
],
|
||||||
name: [
|
name: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
|
|||||||
@@ -161,6 +161,7 @@ import { TableColumn } from '@/components/pagetable';
|
|||||||
import { TagResourceTypeEnum } from '@/common/commonEnum';
|
import { TagResourceTypeEnum } from '@/common/commonEnum';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import { getTagPathSearchItem } from '../component/tag';
|
import { getTagPathSearchItem } from '../component/tag';
|
||||||
|
import { SearchItem } from '@/components/SearchForm';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
lazy: {
|
lazy: {
|
||||||
@@ -172,10 +173,11 @@ const props = defineProps({
|
|||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const pageTableRef: Ref<any> = ref(null);
|
const pageTableRef: Ref<any> = ref(null);
|
||||||
|
|
||||||
const searchItems = [getTagPathSearchItem(TagResourceTypeEnum.Redis.value)];
|
const searchItems = [getTagPathSearchItem(TagResourceTypeEnum.Redis.value), SearchItem.input('code', '编号')];
|
||||||
|
|
||||||
const columns = ref([
|
const columns = ref([
|
||||||
TableColumn.new('tags[0].tagPath', '关联标签').isSlot('tagPath').setAddWidth(20),
|
TableColumn.new('tags[0].tagPath', '关联标签').isSlot('tagPath').setAddWidth(20),
|
||||||
|
TableColumn.new('code', '编号'),
|
||||||
TableColumn.new('name', '名称'),
|
TableColumn.new('name', '名称'),
|
||||||
TableColumn.new('host', 'host:port'),
|
TableColumn.new('host', 'host:port'),
|
||||||
TableColumn.new('mode', 'mode'),
|
TableColumn.new('mode', 'mode'),
|
||||||
|
|||||||
@@ -43,7 +43,9 @@
|
|||||||
>
|
>
|
||||||
<template #default="{ data }">
|
<template #default="{ data }">
|
||||||
<span class="custom-tree-node">
|
<span class="custom-tree-node">
|
||||||
<span style="font-size: 13px">
|
<SvgIcon :name="EnumValue.getEnumByValue(TagResourceTypeEnum, data.type)?.extra.icon" />
|
||||||
|
|
||||||
|
<span class="ml5">
|
||||||
{{ data.code }}
|
{{ data.code }}
|
||||||
<span style="color: #3c8dbc">【</span>
|
<span style="color: #3c8dbc">【</span>
|
||||||
{{ data.name }}
|
{{ data.name }}
|
||||||
@@ -61,6 +63,10 @@
|
|||||||
<el-tabs @tab-change="tabChange" v-model="state.activeTabName" v-if="currentTag">
|
<el-tabs @tab-change="tabChange" v-model="state.activeTabName" v-if="currentTag">
|
||||||
<el-tab-pane label="标签详情" :name="TagDetail">
|
<el-tab-pane label="标签详情" :name="TagDetail">
|
||||||
<el-descriptions :column="2" border>
|
<el-descriptions :column="2" border>
|
||||||
|
<el-descriptions-item label="类型">
|
||||||
|
<EnumTag :enums="TagResourceTypeEnum" :value="currentTag.type" />
|
||||||
|
</el-descriptions-item>
|
||||||
|
|
||||||
<el-descriptions-item label="code">{{ currentTag.code }}</el-descriptions-item>
|
<el-descriptions-item label="code">{{ currentTag.code }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="code路径">{{ currentTag.codePath }}</el-descriptions-item>
|
<el-descriptions-item label="code路径">{{ currentTag.codePath }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="名称">{{ currentTag.name }}</el-descriptions-item>
|
<el-descriptions-item label="名称">{{ currentTag.name }}</el-descriptions-item>
|
||||||
@@ -73,19 +79,19 @@
|
|||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
||||||
<el-tab-pane :label="`机器 (${resourceCount.machine})`" :name="MachineTag">
|
<el-tab-pane v-if="currentTag.type == TagResourceTypeEnum.Tag.value" :label="`机器 (${resourceCount.machine})`" :name="MachineTag">
|
||||||
<MachineList lazy ref="machineListRef" />
|
<MachineList lazy ref="machineListRef" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
||||||
<el-tab-pane :label="`数据库 (${resourceCount.db})`" :name="DbTag">
|
<el-tab-pane v-if="currentTag.type == TagResourceTypeEnum.Tag.value" :label="`数据库 (${resourceCount.db})`" :name="DbTag">
|
||||||
<DbList lazy ref="dbListRef" />
|
<DbList lazy ref="dbListRef" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
||||||
<el-tab-pane :label="`Redis (${resourceCount.redis})`" :name="RedisTag">
|
<el-tab-pane v-if="currentTag.type == TagResourceTypeEnum.Tag.value" :label="`Redis (${resourceCount.redis})`" :name="RedisTag">
|
||||||
<RedisList lazy ref="redisListRef" />
|
<RedisList lazy ref="redisListRef" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
||||||
<el-tab-pane :label="`Mongo (${resourceCount.mongo})`" :name="MongoTag">
|
<el-tab-pane v-if="currentTag.type == TagResourceTypeEnum.Tag.value" :label="`Mongo (${resourceCount.mongo})`" :name="MongoTag">
|
||||||
<MongoList lazy ref="mongoListRef" />
|
<MongoList lazy ref="mongoListRef" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
@@ -129,6 +135,9 @@ import MachineList from '../machine/MachineList.vue';
|
|||||||
import RedisList from '../redis/RedisList.vue';
|
import RedisList from '../redis/RedisList.vue';
|
||||||
import MongoList from '../mongo/MongoList.vue';
|
import MongoList from '../mongo/MongoList.vue';
|
||||||
import DbList from '../db/DbList.vue';
|
import DbList from '../db/DbList.vue';
|
||||||
|
import { TagResourceTypeEnum } from '@/common/commonEnum';
|
||||||
|
import EnumTag from '@/components/enumtag/EnumTag.vue';
|
||||||
|
import EnumValue from '@/common/Enum';
|
||||||
|
|
||||||
interface Tree {
|
interface Tree {
|
||||||
id: number;
|
id: number;
|
||||||
@@ -155,6 +164,10 @@ const MongoTag = 'mongoTag';
|
|||||||
const contextmenuAdd = new ContextmenuItem('addTag', '添加子标签')
|
const contextmenuAdd = new ContextmenuItem('addTag', '添加子标签')
|
||||||
.withIcon('circle-plus')
|
.withIcon('circle-plus')
|
||||||
.withPermission('tag:save')
|
.withPermission('tag:save')
|
||||||
|
.withHideFunc((data: any) => {
|
||||||
|
// 非标签类型不可添加子标签
|
||||||
|
return data.type != -1;
|
||||||
|
})
|
||||||
.withOnClick((data: any) => showSaveTagDialog(data));
|
.withOnClick((data: any) => showSaveTagDialog(data));
|
||||||
|
|
||||||
const contextmenuEdit = new ContextmenuItem('edit', '编辑')
|
const contextmenuEdit = new ContextmenuItem('edit', '编辑')
|
||||||
@@ -167,7 +180,7 @@ const contextmenuDel = new ContextmenuItem('delete', '删除')
|
|||||||
.withPermission('tag:del')
|
.withPermission('tag:del')
|
||||||
.withHideFunc((data: any) => {
|
.withHideFunc((data: any) => {
|
||||||
// 存在子标签,则不允许删除
|
// 存在子标签,则不允许删除
|
||||||
return data.children;
|
return data.children || data.type != -1;
|
||||||
})
|
})
|
||||||
.withOnClick((data: any) => deleteTag(data));
|
.withOnClick((data: any) => deleteTag(data));
|
||||||
|
|
||||||
|
|||||||
@@ -66,7 +66,9 @@
|
|||||||
>
|
>
|
||||||
<template #default="{ data }">
|
<template #default="{ data }">
|
||||||
<span class="custom-tree-node">
|
<span class="custom-tree-node">
|
||||||
<span style="font-size: 13px">
|
<SvgIcon :name="EnumValue.getEnumByValue(TagResourceTypeEnum, data.type)?.extra.icon" />
|
||||||
|
|
||||||
|
<span class="font13 ml5">
|
||||||
{{ data.code }}
|
{{ data.code }}
|
||||||
<span style="color: #3c8dbc">【</span>
|
<span style="color: #3c8dbc">【</span>
|
||||||
{{ data.name }}
|
{{ data.name }}
|
||||||
@@ -128,6 +130,8 @@ import PageTable from '@/components/pagetable/PageTable.vue';
|
|||||||
import { TableColumn } from '@/components/pagetable';
|
import { TableColumn } from '@/components/pagetable';
|
||||||
import { SearchItem } from '@/components/SearchForm';
|
import { SearchItem } from '@/components/SearchForm';
|
||||||
import AccountSelectFormItem from '@/views/system/account/components/AccountSelectFormItem.vue';
|
import AccountSelectFormItem from '@/views/system/account/components/AccountSelectFormItem.vue';
|
||||||
|
import { TagResourceTypeEnum } from '@/common/commonEnum';
|
||||||
|
import EnumValue from '@/common/Enum';
|
||||||
|
|
||||||
const teamForm: any = ref(null);
|
const teamForm: any = ref(null);
|
||||||
const tagTreeRef: any = ref(null);
|
const tagTreeRef: any = ref(null);
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ export const tagApi = {
|
|||||||
delTagTree: Api.newDelete('/tag-trees/{id}'),
|
delTagTree: Api.newDelete('/tag-trees/{id}'),
|
||||||
|
|
||||||
getResourceTagPaths: Api.newGet('/tag-trees/resources/{resourceType}/tag-paths'),
|
getResourceTagPaths: Api.newGet('/tag-trees/resources/{resourceType}/tag-paths'),
|
||||||
getTagResources: Api.newGet('/tag-trees/resources'),
|
|
||||||
countTagResource: Api.newGet('/tag-trees/resources/count'),
|
countTagResource: Api.newGet('/tag-trees/resources/count'),
|
||||||
|
|
||||||
getTeams: Api.newGet('/teams'),
|
getTeams: Api.newGet('/teams'),
|
||||||
|
|||||||
@@ -9,11 +9,6 @@ server:
|
|||||||
enable: false
|
enable: false
|
||||||
key-file: ./default.key
|
key-file: ./default.key
|
||||||
cert-file: ./default.pem
|
cert-file: ./default.pem
|
||||||
machine:
|
|
||||||
# 如果需要添加rdp服务器,需要安装guacd服务,docker跑一个就行 docker run --name guacd -d -p 4822:4822 guacamole/guacd
|
|
||||||
# 如果连接频繁中断,重启一下guacd
|
|
||||||
guacd-host: 127.0.0.1
|
|
||||||
guacd-port: 4822
|
|
||||||
jwt:
|
jwt:
|
||||||
# jwt key,不设置默认使用随机字符串
|
# jwt key,不设置默认使用随机字符串
|
||||||
key:
|
key:
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ require (
|
|||||||
github.com/sijms/go-ora/v2 v2.8.10
|
github.com/sijms/go-ora/v2 v2.8.10
|
||||||
github.com/stretchr/testify v1.8.4
|
github.com/stretchr/testify v1.8.4
|
||||||
go.mongodb.org/mongo-driver v1.14.0 // mongo
|
go.mongodb.org/mongo-driver v1.14.0 // mongo
|
||||||
golang.org/x/crypto v0.21.0 // ssh
|
golang.org/x/crypto v0.22.0 // ssh
|
||||||
golang.org/x/oauth2 v0.18.0
|
golang.org/x/oauth2 v0.18.0
|
||||||
golang.org/x/sync v0.6.0
|
golang.org/x/sync v0.6.0
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
||||||
@@ -89,7 +89,7 @@ require (
|
|||||||
golang.org/x/exp v0.0.0-20230519143937-03e91628a987 // indirect
|
golang.org/x/exp v0.0.0-20230519143937-03e91628a987 // indirect
|
||||||
golang.org/x/image v0.13.0 // indirect
|
golang.org/x/image v0.13.0 // indirect
|
||||||
golang.org/x/net v0.22.0 // indirect
|
golang.org/x/net v0.22.0 // indirect
|
||||||
golang.org/x/sys v0.18.0 // indirect
|
golang.org/x/sys v0.19.0 // indirect
|
||||||
golang.org/x/text v0.14.0 // indirect
|
golang.org/x/text v0.14.0 // indirect
|
||||||
google.golang.org/appengine v1.6.7 // indirect
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
google.golang.org/genproto v0.0.0-20230131230820-1c016267d619 // indirect
|
google.golang.org/genproto v0.0.0-20230131230820-1c016267d619 // indirect
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package form
|
|||||||
|
|
||||||
type DbForm struct {
|
type DbForm struct {
|
||||||
Id uint64 `json:"id"`
|
Id uint64 `json:"id"`
|
||||||
|
Code string `binding:"required" json:"code"`
|
||||||
Name string `binding:"required" json:"name"`
|
Name string `binding:"required" json:"name"`
|
||||||
Database string `json:"database"`
|
Database string `json:"database"`
|
||||||
Remark string `json:"remark"`
|
Remark string `json:"remark"`
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import (
|
|||||||
"mayfly-go/pkg/errorx"
|
"mayfly-go/pkg/errorx"
|
||||||
"mayfly-go/pkg/model"
|
"mayfly-go/pkg/model"
|
||||||
"mayfly-go/pkg/utils/collx"
|
"mayfly-go/pkg/utils/collx"
|
||||||
"mayfly-go/pkg/utils/stringx"
|
|
||||||
"mayfly-go/pkg/utils/structx"
|
"mayfly-go/pkg/utils/structx"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -79,13 +78,18 @@ func (d *dbAppImpl) SaveDb(ctx context.Context, dbEntity *entity.Db, tagIds ...u
|
|||||||
return errorx.NewBiz("该实例下数据库名已存在")
|
return errorx.NewBiz("该实例下数据库名已存在")
|
||||||
}
|
}
|
||||||
|
|
||||||
resouceCode := stringx.Rand(16)
|
if d.CountByCond(&entity.Db{Code: dbEntity.Code}) > 0 {
|
||||||
dbEntity.Code = resouceCode
|
return errorx.NewBiz("该编码已存在")
|
||||||
|
}
|
||||||
|
|
||||||
return d.Tx(ctx, func(ctx context.Context) error {
|
return d.Tx(ctx, func(ctx context.Context) error {
|
||||||
return d.Insert(ctx, dbEntity)
|
return d.Insert(ctx, dbEntity)
|
||||||
}, func(ctx context.Context) error {
|
}, func(ctx context.Context) error {
|
||||||
return d.tagApp.RelateResource(ctx, resouceCode, consts.TagResourceTypeDb, tagIds)
|
return d.tagApp.SaveResource(ctx, &tagapp.SaveResourceTagParam{
|
||||||
|
ResourceCode: dbEntity.Code,
|
||||||
|
ResourceType: consts.TagResourceTypeDb,
|
||||||
|
TagIds: tagIds,
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,10 +120,16 @@ func (d *dbAppImpl) SaveDb(ctx context.Context, dbEntity *entity.Db, tagIds ...u
|
|||||||
d.dbSqlRepo.DeleteByCond(ctx, &entity.DbSql{DbId: dbId, Db: v})
|
d.dbSqlRepo.DeleteByCond(ctx, &entity.DbSql{DbId: dbId, Db: v})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 防止误传修改
|
||||||
|
dbEntity.Code = ""
|
||||||
return d.Tx(ctx, func(ctx context.Context) error {
|
return d.Tx(ctx, func(ctx context.Context) error {
|
||||||
return d.UpdateById(ctx, dbEntity)
|
return d.UpdateById(ctx, dbEntity)
|
||||||
}, func(ctx context.Context) error {
|
}, func(ctx context.Context) error {
|
||||||
return d.tagApp.RelateResource(ctx, old.Code, consts.TagResourceTypeDb, tagIds)
|
return d.tagApp.SaveResource(ctx, &tagapp.SaveResourceTagParam{
|
||||||
|
ResourceCode: old.Code,
|
||||||
|
ResourceType: consts.TagResourceTypeDb,
|
||||||
|
TagIds: tagIds,
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,8 +152,10 @@ func (d *dbAppImpl) Delete(ctx context.Context, id uint64) error {
|
|||||||
// 删除该库下用户保存的所有sql信息
|
// 删除该库下用户保存的所有sql信息
|
||||||
return d.dbSqlRepo.DeleteByCond(ctx, &entity.DbSql{DbId: id})
|
return d.dbSqlRepo.DeleteByCond(ctx, &entity.DbSql{DbId: id})
|
||||||
}, func(ctx context.Context) error {
|
}, func(ctx context.Context) error {
|
||||||
var tagIds []uint64
|
return d.tagApp.SaveResource(ctx, &tagapp.SaveResourceTagParam{
|
||||||
return d.tagApp.RelateResource(ctx, db.Code, consts.TagResourceTypeDb, tagIds)
|
ResourceCode: db.Code,
|
||||||
|
ResourceType: consts.TagResourceTypeDb,
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ type DbTransferLogQuery struct {
|
|||||||
// 数据库查询实体,不与数据库表字段一一对应
|
// 数据库查询实体,不与数据库表字段一一对应
|
||||||
type DbQuery struct {
|
type DbQuery struct {
|
||||||
Id uint64 `form:"id"`
|
Id uint64 `form:"id"`
|
||||||
|
Code string `json:"code" form:"code"`
|
||||||
Name string `orm:"column(name)" json:"name"`
|
Name string `orm:"column(name)" json:"name"`
|
||||||
Database string `orm:"column(database)" json:"database"`
|
Database string `orm:"column(database)" json:"database"`
|
||||||
Remark string `json:"remark"`
|
Remark string `json:"remark"`
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ func (d *dbRepoImpl) GetDbList(condition *entity.DbQuery, pageParam *model.PageP
|
|||||||
Eq("db.instance_id", condition.InstanceId).
|
Eq("db.instance_id", condition.InstanceId).
|
||||||
Eq("db.id", condition.Id).
|
Eq("db.id", condition.Id).
|
||||||
Like("db.database", condition.Database).
|
Like("db.database", condition.Database).
|
||||||
|
Eq("db.code", condition.Code).
|
||||||
In("db.code", condition.Codes).
|
In("db.code", condition.Codes).
|
||||||
Eq0("db."+model.DeletedColumn, model.ModelUndeleted).
|
Eq0("db."+model.DeletedColumn, model.ModelUndeleted).
|
||||||
Eq0("inst."+model.DeletedColumn, model.ModelUndeleted)
|
Eq0("inst."+model.DeletedColumn, model.ModelUndeleted)
|
||||||
@@ -39,5 +40,8 @@ func (d *dbRepoImpl) Count(condition *entity.DbQuery) int64 {
|
|||||||
if condition.InstanceId > 0 {
|
if condition.InstanceId > 0 {
|
||||||
where["instance_id"] = condition.InstanceId
|
where["instance_id"] = condition.InstanceId
|
||||||
}
|
}
|
||||||
|
if condition.Code != "" {
|
||||||
|
where["code"] = condition.Code
|
||||||
|
}
|
||||||
return d.CountByCond(where)
|
return d.CountByCond(where)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package form
|
|||||||
type MachineForm struct {
|
type MachineForm struct {
|
||||||
Id uint64 `json:"id"`
|
Id uint64 `json:"id"`
|
||||||
Protocol int `json:"protocol" binding:"required"`
|
Protocol int `json:"protocol" binding:"required"`
|
||||||
|
Code string `json:"code" binding:"required"`
|
||||||
Name string `json:"name" binding:"required"`
|
Name string `json:"name" binding:"required"`
|
||||||
Ip string `json:"ip" binding:"required"` // IP地址
|
Ip string `json:"ip" binding:"required"` // IP地址
|
||||||
Port int `json:"port" binding:"required"` // 端口号
|
Port int `json:"port" binding:"required"` // 端口号
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import (
|
|||||||
"mayfly-go/pkg/logx"
|
"mayfly-go/pkg/logx"
|
||||||
"mayfly-go/pkg/model"
|
"mayfly-go/pkg/model"
|
||||||
"mayfly-go/pkg/scheduler"
|
"mayfly-go/pkg/scheduler"
|
||||||
"mayfly-go/pkg/utils/stringx"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -88,15 +87,21 @@ func (m *machineAppImpl) SaveMachine(ctx context.Context, me *entity.Machine, ta
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
return errorx.NewBiz("该机器信息已存在")
|
return errorx.NewBiz("该机器信息已存在")
|
||||||
}
|
}
|
||||||
resouceCode := stringx.Rand(16)
|
if m.CountByCond(&entity.Machine{Code: me.Code}) > 0 {
|
||||||
me.Code = resouceCode
|
return errorx.NewBiz("该编码已存在")
|
||||||
|
}
|
||||||
|
|
||||||
// 新增机器,默认启用状态
|
// 新增机器,默认启用状态
|
||||||
me.Status = entity.MachineStatusEnable
|
me.Status = entity.MachineStatusEnable
|
||||||
|
|
||||||
return m.Tx(ctx, func(ctx context.Context) error {
|
return m.Tx(ctx, func(ctx context.Context) error {
|
||||||
return m.Insert(ctx, me)
|
return m.Insert(ctx, me)
|
||||||
}, func(ctx context.Context) error {
|
}, func(ctx context.Context) error {
|
||||||
return m.tagApp.RelateResource(ctx, resouceCode, consts.TagResourceTypeMachine, tagIds)
|
return m.tagApp.SaveResource(ctx, &tagapp.SaveResourceTagParam{
|
||||||
|
ResourceCode: me.Code,
|
||||||
|
ResourceType: consts.TagResourceTypeMachine,
|
||||||
|
TagIds: tagIds,
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,10 +116,16 @@ func (m *machineAppImpl) SaveMachine(ctx context.Context, me *entity.Machine, ta
|
|||||||
|
|
||||||
// 关闭连接
|
// 关闭连接
|
||||||
mcm.DeleteCli(me.Id)
|
mcm.DeleteCli(me.Id)
|
||||||
|
// 防止误传修改
|
||||||
|
me.Code = ""
|
||||||
return m.Tx(ctx, func(ctx context.Context) error {
|
return m.Tx(ctx, func(ctx context.Context) error {
|
||||||
return m.UpdateById(ctx, me)
|
return m.UpdateById(ctx, me)
|
||||||
}, func(ctx context.Context) error {
|
}, func(ctx context.Context) error {
|
||||||
return m.tagApp.RelateResource(ctx, oldMachine.Code, consts.TagResourceTypeMachine, tagIds)
|
return m.tagApp.SaveResource(ctx, &tagapp.SaveResourceTagParam{
|
||||||
|
ResourceCode: oldMachine.Code,
|
||||||
|
ResourceType: consts.TagResourceTypeMachine,
|
||||||
|
TagIds: tagIds,
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,8 +169,10 @@ func (m *machineAppImpl) Delete(ctx context.Context, id uint64) error {
|
|||||||
func(ctx context.Context) error {
|
func(ctx context.Context) error {
|
||||||
return m.DeleteById(ctx, id)
|
return m.DeleteById(ctx, id)
|
||||||
}, func(ctx context.Context) error {
|
}, func(ctx context.Context) error {
|
||||||
var tagIds []uint64
|
return m.tagApp.SaveResource(ctx, &tagapp.SaveResourceTagParam{
|
||||||
return m.tagApp.RelateResource(ctx, machine.Code, consts.TagResourceTypeMachine, tagIds)
|
ResourceCode: machine.Code,
|
||||||
|
ResourceType: consts.TagResourceTypeMachine,
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ func GetMachine() *Machine {
|
|||||||
mc.UploadMaxFileSize = uploadMaxFileSize
|
mc.UploadMaxFileSize = uploadMaxFileSize
|
||||||
mc.TermOpSaveDays = cast.ToIntD(jm["termOpSaveDays"], 30)
|
mc.TermOpSaveDays = cast.ToIntD(jm["termOpSaveDays"], 30)
|
||||||
// guacd
|
// guacd
|
||||||
mc.GuacdHost = cast.ToStringD(jm["guacdHost"], "127.0.0.1")
|
mc.GuacdHost = cast.ToString(jm["guacdHost"])
|
||||||
mc.GuacdPort = cast.ToIntD(jm["guacdPort"], 4822)
|
mc.GuacdPort = cast.ToIntD(jm["guacdPort"], 4822)
|
||||||
mc.GuacdFilePath = cast.ToStringD(jm["guacdFilePath"], "")
|
mc.GuacdFilePath = cast.ToStringD(jm["guacdFilePath"], "")
|
||||||
mc.GuacdRecPath = cast.ToStringD(jm["guacdRecPath"], "")
|
mc.GuacdRecPath = cast.ToStringD(jm["guacdRecPath"], "")
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import "time"
|
|||||||
|
|
||||||
type MachineQuery struct {
|
type MachineQuery struct {
|
||||||
Ids string `json:"ids" form:"ids"`
|
Ids string `json:"ids" form:"ids"`
|
||||||
|
Code string `json:"code" form:"code"`
|
||||||
Name string `json:"name" form:"name"`
|
Name string `json:"name" form:"name"`
|
||||||
Status int8 `json:"status" form:"status"`
|
Status int8 `json:"status" form:"status"`
|
||||||
Ip string `json:"ip" form:"ip"` // IP地址
|
Ip string `json:"ip" form:"ip"` // IP地址
|
||||||
|
|||||||
@@ -4,13 +4,15 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gorilla/websocket"
|
|
||||||
"io"
|
"io"
|
||||||
"mayfly-go/internal/machine/config"
|
"mayfly-go/internal/machine/config"
|
||||||
|
"mayfly-go/pkg/errorx"
|
||||||
"mayfly-go/pkg/logx"
|
"mayfly-go/pkg/logx"
|
||||||
"net"
|
"net"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/gorilla/websocket"
|
||||||
)
|
)
|
||||||
|
|
||||||
// creates the tunnel to the remote machine (via guacd)
|
// creates the tunnel to the remote machine (via guacd)
|
||||||
@@ -62,7 +64,12 @@ func DoConnect(query url.Values, parameters map[string]string, machineId uint64)
|
|||||||
conf.ImageMimetypes = []string{"image/jpeg", "image/png", "image/webp"}
|
conf.ImageMimetypes = []string{"image/jpeg", "image/png", "image/webp"}
|
||||||
|
|
||||||
logx.Debug("Connecting to guacd")
|
logx.Debug("Connecting to guacd")
|
||||||
guacdAddr := fmt.Sprintf("%v:%v", config.GetMachine().GuacdHost, config.GetMachine().GuacdPort)
|
|
||||||
|
machineConfig := config.GetMachine()
|
||||||
|
if machineConfig.GuacdHost == "" {
|
||||||
|
return nil, errorx.NewBiz("请前往'系统配置-机器配置'中配置guacd相关信息")
|
||||||
|
}
|
||||||
|
guacdAddr := fmt.Sprintf("%v:%v", machineConfig.GuacdHost, machineConfig.GuacdPort)
|
||||||
addr, err := net.ResolveTCPAddr("tcp", guacdAddr)
|
addr, err := net.ResolveTCPAddr("tcp", guacdAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logx.Error("error resolving guacd address", err)
|
logx.Error("error resolving guacd address", err)
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ func (m *machineRepoImpl) GetMachineList(condition *entity.MachineQuery, pagePar
|
|||||||
Eq("status", condition.Status).
|
Eq("status", condition.Status).
|
||||||
Like("ip", condition.Ip).
|
Like("ip", condition.Ip).
|
||||||
Like("name", condition.Name).
|
Like("name", condition.Name).
|
||||||
In("code", condition.Codes)
|
In("code", condition.Codes).
|
||||||
|
Eq("code", condition.Code)
|
||||||
|
|
||||||
// 只查询ssh服务器
|
// 只查询ssh服务器
|
||||||
if condition.Ssh == entity.MachineProtocolSsh {
|
if condition.Ssh == entity.MachineProtocolSsh {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package form
|
|||||||
|
|
||||||
type Mongo struct {
|
type Mongo struct {
|
||||||
Id uint64 `json:"id"`
|
Id uint64 `json:"id"`
|
||||||
|
Code uint64 `json:"code" binding:"required"`
|
||||||
Uri string `binding:"required" json:"uri"`
|
Uri string `binding:"required" json:"uri"`
|
||||||
SshTunnelMachineId int `json:"sshTunnelMachineId"` // ssh隧道机器id
|
SshTunnelMachineId int `json:"sshTunnelMachineId"` // ssh隧道机器id
|
||||||
Name string `binding:"required" json:"name"`
|
Name string `binding:"required" json:"name"`
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import (
|
|||||||
"mayfly-go/pkg/base"
|
"mayfly-go/pkg/base"
|
||||||
"mayfly-go/pkg/errorx"
|
"mayfly-go/pkg/errorx"
|
||||||
"mayfly-go/pkg/model"
|
"mayfly-go/pkg/model"
|
||||||
"mayfly-go/pkg/utils/stringx"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Mongo interface {
|
type Mongo interface {
|
||||||
@@ -59,8 +58,10 @@ func (d *mongoAppImpl) Delete(ctx context.Context, id uint64) error {
|
|||||||
return d.DeleteById(ctx, id)
|
return d.DeleteById(ctx, id)
|
||||||
},
|
},
|
||||||
func(ctx context.Context) error {
|
func(ctx context.Context) error {
|
||||||
var tagIds []uint64
|
return d.tagApp.SaveResource(ctx, &tagapp.SaveResourceTagParam{
|
||||||
return d.tagApp.RelateResource(ctx, mongoEntity.Code, consts.TagResourceTypeMongo, tagIds)
|
ResourceType: consts.TagResourceTypeMongo,
|
||||||
|
ResourceCode: mongoEntity.Code,
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,14 +82,18 @@ func (d *mongoAppImpl) SaveMongo(ctx context.Context, m *entity.Mongo, tagIds ..
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
return errorx.NewBiz("该名称已存在")
|
return errorx.NewBiz("该名称已存在")
|
||||||
}
|
}
|
||||||
|
if d.CountByCond(&entity.Mongo{Code: m.Code}) > 0 {
|
||||||
resouceCode := stringx.Rand(16)
|
return errorx.NewBiz("该编码已存在")
|
||||||
m.Code = resouceCode
|
}
|
||||||
|
|
||||||
return d.Tx(ctx, func(ctx context.Context) error {
|
return d.Tx(ctx, func(ctx context.Context) error {
|
||||||
return d.Insert(ctx, m)
|
return d.Insert(ctx, m)
|
||||||
}, func(ctx context.Context) error {
|
}, func(ctx context.Context) error {
|
||||||
return d.tagApp.RelateResource(ctx, resouceCode, consts.TagResourceTypeMongo, tagIds)
|
return d.tagApp.SaveResource(ctx, &tagapp.SaveResourceTagParam{
|
||||||
|
ResourceType: consts.TagResourceTypeMongo,
|
||||||
|
ResourceCode: m.Code,
|
||||||
|
TagIds: tagIds,
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,10 +108,15 @@ func (d *mongoAppImpl) SaveMongo(ctx context.Context, m *entity.Mongo, tagIds ..
|
|||||||
|
|
||||||
// 先关闭连接
|
// 先关闭连接
|
||||||
mgm.CloseConn(m.Id)
|
mgm.CloseConn(m.Id)
|
||||||
|
m.Code = ""
|
||||||
return d.Tx(ctx, func(ctx context.Context) error {
|
return d.Tx(ctx, func(ctx context.Context) error {
|
||||||
return d.UpdateById(ctx, m)
|
return d.UpdateById(ctx, m)
|
||||||
}, func(ctx context.Context) error {
|
}, func(ctx context.Context) error {
|
||||||
return d.tagApp.RelateResource(ctx, oldMongo.Code, consts.TagResourceTypeMongo, tagIds)
|
return d.tagApp.SaveResource(ctx, &tagapp.SaveResourceTagParam{
|
||||||
|
ResourceType: consts.TagResourceTypeMongo,
|
||||||
|
ResourceCode: oldMongo.Code,
|
||||||
|
TagIds: tagIds,
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import "mayfly-go/pkg/model"
|
|||||||
type MongoQuery struct {
|
type MongoQuery struct {
|
||||||
model.Model
|
model.Model
|
||||||
|
|
||||||
|
Code string `json:"code" form:"code"`
|
||||||
Name string
|
Name string
|
||||||
Uri string
|
Uri string
|
||||||
SshTunnelMachineId uint64 // ssh隧道机器id
|
SshTunnelMachineId uint64 // ssh隧道机器id
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ func newMongoRepo() repository.Mongo {
|
|||||||
func (d *mongoRepoImpl) GetList(condition *entity.MongoQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
|
func (d *mongoRepoImpl) GetList(condition *entity.MongoQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
|
||||||
qd := gormx.NewQuery(new(entity.Mongo)).
|
qd := gormx.NewQuery(new(entity.Mongo)).
|
||||||
Like("name", condition.Name).
|
Like("name", condition.Name).
|
||||||
|
Eq("code", condition.Code).
|
||||||
In("code", condition.Codes)
|
In("code", condition.Codes)
|
||||||
return gormx.PageQuery(qd, pageParam, toEntity)
|
return gormx.PageQuery(qd, pageParam, toEntity)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package form
|
|||||||
|
|
||||||
type Redis struct {
|
type Redis struct {
|
||||||
Id uint64 `json:"id"`
|
Id uint64 `json:"id"`
|
||||||
|
Code string `json:"code" binding:"required"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Host string `json:"host" binding:"required"`
|
Host string `json:"host" binding:"required"`
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
|
|||||||
@@ -95,17 +95,22 @@ func (r *redisAppImpl) SaveRedis(ctx context.Context, re *entity.Redis, tagIds .
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
return errorx.NewBiz("该实例已存在")
|
return errorx.NewBiz("该实例已存在")
|
||||||
}
|
}
|
||||||
|
if r.CountByCond(&entity.Redis{Code: re.Code}) > 0 {
|
||||||
|
return errorx.NewBiz("该编码已存在")
|
||||||
|
}
|
||||||
|
|
||||||
if errEnc := re.PwdEncrypt(); errEnc != nil {
|
if errEnc := re.PwdEncrypt(); errEnc != nil {
|
||||||
return errorx.NewBiz(errEnc.Error())
|
return errorx.NewBiz(errEnc.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
resouceCode := stringx.Rand(16)
|
|
||||||
re.Code = resouceCode
|
|
||||||
|
|
||||||
return r.Tx(ctx, func(ctx context.Context) error {
|
return r.Tx(ctx, func(ctx context.Context) error {
|
||||||
return r.Insert(ctx, re)
|
return r.Insert(ctx, re)
|
||||||
}, func(ctx context.Context) error {
|
}, func(ctx context.Context) error {
|
||||||
return r.tagApp.RelateResource(ctx, resouceCode, consts.TagResourceTypeRedis, tagIds)
|
return r.tagApp.SaveResource(ctx, &tagapp.SaveResourceTagParam{
|
||||||
|
ResourceType: consts.TagResourceTypeRedis,
|
||||||
|
ResourceCode: re.Code,
|
||||||
|
TagIds: tagIds,
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,10 +133,15 @@ func (r *redisAppImpl) SaveRedis(ctx context.Context, re *entity.Redis, tagIds .
|
|||||||
if errEnc := re.PwdEncrypt(); errEnc != nil {
|
if errEnc := re.PwdEncrypt(); errEnc != nil {
|
||||||
return errorx.NewBiz(errEnc.Error())
|
return errorx.NewBiz(errEnc.Error())
|
||||||
}
|
}
|
||||||
|
re.Code = ""
|
||||||
return r.Tx(ctx, func(ctx context.Context) error {
|
return r.Tx(ctx, func(ctx context.Context) error {
|
||||||
return r.UpdateById(ctx, re)
|
return r.UpdateById(ctx, re)
|
||||||
}, func(ctx context.Context) error {
|
}, func(ctx context.Context) error {
|
||||||
return r.tagApp.RelateResource(ctx, oldRedis.Code, consts.TagResourceTypeRedis, tagIds)
|
return r.tagApp.SaveResource(ctx, &tagapp.SaveResourceTagParam{
|
||||||
|
ResourceType: consts.TagResourceTypeRedis,
|
||||||
|
ResourceCode: oldRedis.Code,
|
||||||
|
TagIds: tagIds,
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,8 +160,10 @@ func (r *redisAppImpl) Delete(ctx context.Context, id uint64) error {
|
|||||||
return r.Tx(ctx, func(ctx context.Context) error {
|
return r.Tx(ctx, func(ctx context.Context) error {
|
||||||
return r.DeleteById(ctx, id)
|
return r.DeleteById(ctx, id)
|
||||||
}, func(ctx context.Context) error {
|
}, func(ctx context.Context) error {
|
||||||
var tagIds []uint64
|
return r.tagApp.SaveResource(ctx, &tagapp.SaveResourceTagParam{
|
||||||
return r.tagApp.RelateResource(ctx, re.Code, consts.TagResourceTypeRedis, tagIds)
|
ResourceType: consts.TagResourceTypeRedis,
|
||||||
|
ResourceCode: re.Code,
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package entity
|
|||||||
|
|
||||||
type RedisQuery struct {
|
type RedisQuery struct {
|
||||||
Id uint64 `form:"id"`
|
Id uint64 `form:"id"`
|
||||||
|
Code string `json:"code" form:"code"`
|
||||||
Name string `orm:"column(name)" json:"name" form:"name"`
|
Name string `orm:"column(name)" json:"name" form:"name"`
|
||||||
Host string `orm:"column(host)" json:"host" form:"host"`
|
Host string `orm:"column(host)" json:"host" form:"host"`
|
||||||
|
|
||||||
|
|||||||
@@ -16,11 +16,12 @@ func newRedisRepo() repository.Redis {
|
|||||||
return &redisRepoImpl{base.RepoImpl[*entity.Redis]{M: new(entity.Redis)}}
|
return &redisRepoImpl{base.RepoImpl[*entity.Redis]{M: new(entity.Redis)}}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 分页获取机器信息列表
|
// 分页获取redis信息列表
|
||||||
func (r *redisRepoImpl) GetRedisList(condition *entity.RedisQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
|
func (r *redisRepoImpl) GetRedisList(condition *entity.RedisQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
|
||||||
qd := gormx.NewQuery(new(entity.Redis)).
|
qd := gormx.NewQuery(new(entity.Redis)).
|
||||||
Eq("id", condition.Id).
|
Eq("id", condition.Id).
|
||||||
Like("host", condition.Host).
|
Like("host", condition.Host).
|
||||||
|
Eq("code", condition.Code).
|
||||||
In("code", condition.Codes)
|
In("code", condition.Codes)
|
||||||
return gormx.PageQuery(qd, pageParam, toEntity)
|
return gormx.PageQuery(qd, pageParam, toEntity)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,14 +15,14 @@ import (
|
|||||||
|
|
||||||
type TagTree struct {
|
type TagTree struct {
|
||||||
TagTreeApp application.TagTree `inject:""`
|
TagTreeApp application.TagTree `inject:""`
|
||||||
TagResourceApp application.TagResource `inject:""`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *TagTree) GetTagTree(rc *req.Ctx) {
|
func (p *TagTree) GetTagTree(rc *req.Ctx) {
|
||||||
|
tagType := rc.QueryInt("type")
|
||||||
// 超管返回所有标签树
|
// 超管返回所有标签树
|
||||||
if rc.GetLoginAccount().Id == consts.AdminId {
|
if rc.GetLoginAccount().Id == consts.AdminId {
|
||||||
var tagTrees vo.TagTreeVOS
|
var tagTrees vo.TagTreeVOS
|
||||||
p.TagTreeApp.ListByQuery(new(entity.TagTreeQuery), &tagTrees)
|
p.TagTreeApp.ListByQuery(&entity.TagTreeQuery{Type: int8(tagType)}, &tagTrees)
|
||||||
rc.ResData = tagTrees.ToTrees(0)
|
rc.ResData = tagTrees.ToTrees(0)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -36,11 +36,12 @@ func (p *TagTree) GetTagTree(rc *req.Ctx) {
|
|||||||
tags := rootTag[root]
|
tags := rootTag[root]
|
||||||
tags = append(tags, accountTagPath)
|
tags = append(tags, accountTagPath)
|
||||||
rootTag[root] = tags
|
rootTag[root] = tags
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取所有以root标签开头的子标签
|
// 获取所有以root标签开头的子标签
|
||||||
tags := p.TagTreeApp.ListTagByPath(collx.MapKeys(rootTag)...)
|
var tags []*entity.TagTree
|
||||||
|
p.TagTreeApp.ListByQuery(&entity.TagTreeQuery{CodePathLikes: collx.MapKeys(rootTag), Type: int8(tagType)}, &tags)
|
||||||
|
|
||||||
tagTrees := make(vo.TagTreeVOS, 0)
|
tagTrees := make(vo.TagTreeVOS, 0)
|
||||||
for _, tag := range tags {
|
for _, tag := range tags {
|
||||||
tagPath := tag.CodePath
|
tagPath := tag.CodePath
|
||||||
@@ -84,8 +85,8 @@ func (p *TagTree) DelTagTree(rc *req.Ctx) {
|
|||||||
func (p *TagTree) TagResources(rc *req.Ctx) {
|
func (p *TagTree) TagResources(rc *req.Ctx) {
|
||||||
resourceType := int8(rc.PathParamInt("rtype"))
|
resourceType := int8(rc.PathParamInt("rtype"))
|
||||||
tagResources := p.TagTreeApp.GetAccountTagResources(rc.GetLoginAccount().Id, resourceType, "")
|
tagResources := p.TagTreeApp.GetAccountTagResources(rc.GetLoginAccount().Id, resourceType, "")
|
||||||
tagPath2Resource := collx.ArrayToMap[entity.TagResource, string](tagResources, func(tagResource entity.TagResource) string {
|
tagPath2Resource := collx.ArrayToMap[entity.TagTree, string](tagResources, func(tagResource entity.TagTree) string {
|
||||||
return tagResource.TagPath
|
return tagResource.GetParentPath()
|
||||||
})
|
})
|
||||||
|
|
||||||
tagPaths := collx.MapKeys(tagPath2Resource)
|
tagPaths := collx.MapKeys(tagPath2Resource)
|
||||||
@@ -104,10 +105,3 @@ func (p *TagTree) CountTagResource(rc *req.Ctx) {
|
|||||||
"mongo": len(p.TagTreeApp.GetAccountResourceCodes(accountId, consts.TagResourceTypeMongo, tagPath)),
|
"mongo": len(p.TagTreeApp.GetAccountResourceCodes(accountId, consts.TagResourceTypeMongo, tagPath)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 资源标签关联信息查询
|
|
||||||
func (p *TagTree) QueryTagResources(rc *req.Ctx) {
|
|
||||||
var trs []*entity.TagResource
|
|
||||||
p.TagResourceApp.ListByQuery(req.BindQuery(rc, new(entity.TagResourceQuery)), &trs)
|
|
||||||
rc.ResData = trs
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -7,5 +7,4 @@ import (
|
|||||||
func InitIoc() {
|
func InitIoc() {
|
||||||
ioc.Register(new(tagTreeAppImpl), ioc.WithComponentName("TagTreeApp"))
|
ioc.Register(new(tagTreeAppImpl), ioc.WithComponentName("TagTreeApp"))
|
||||||
ioc.Register(new(teamAppImpl), ioc.WithComponentName("TeamApp"))
|
ioc.Register(new(teamAppImpl), ioc.WithComponentName("TeamApp"))
|
||||||
ioc.Register(new(tagResourceAppImpl), ioc.WithComponentName("TagResourceApp"))
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
package application
|
|
||||||
|
|
||||||
import (
|
|
||||||
"mayfly-go/internal/tag/domain/entity"
|
|
||||||
"mayfly-go/internal/tag/domain/repository"
|
|
||||||
"mayfly-go/pkg/base"
|
|
||||||
)
|
|
||||||
|
|
||||||
type TagResource interface {
|
|
||||||
base.App[*entity.TagResource]
|
|
||||||
|
|
||||||
ListByQuery(condition *entity.TagResourceQuery, toEntity any)
|
|
||||||
}
|
|
||||||
|
|
||||||
type tagResourceAppImpl struct {
|
|
||||||
base.AppImpl[*entity.TagResource, repository.TagResource]
|
|
||||||
}
|
|
||||||
|
|
||||||
// 注入TagResourceRepo
|
|
||||||
func (tr *tagResourceAppImpl) InjectTagResourceRepo(repo repository.TagResource) {
|
|
||||||
tr.Repo = repo
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tr *tagResourceAppImpl) ListByQuery(condition *entity.TagResourceQuery, toEntity any) {
|
|
||||||
tr.Repo.SelectByCondition(condition, toEntity)
|
|
||||||
}
|
|
||||||
@@ -12,6 +12,15 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 保存资源标签参数
|
||||||
|
type SaveResourceTagParam struct {
|
||||||
|
ResourceCode string
|
||||||
|
ResourceName string
|
||||||
|
ResourceType int8
|
||||||
|
|
||||||
|
TagIds []uint64 // 关联标签,相当于父标签 pid
|
||||||
|
}
|
||||||
|
|
||||||
type TagTree interface {
|
type TagTree interface {
|
||||||
base.App[*entity.TagTree]
|
base.App[*entity.TagTree]
|
||||||
|
|
||||||
@@ -25,23 +34,17 @@ type TagTree interface {
|
|||||||
// @param accountId 账号id
|
// @param accountId 账号id
|
||||||
// @param resourceType 资源类型
|
// @param resourceType 资源类型
|
||||||
// @param tagPath 访问指定的标签路径下关联的资源
|
// @param tagPath 访问指定的标签路径下关联的资源
|
||||||
GetAccountTagResources(accountId uint64, resourceType int8, tagPath string) []entity.TagResource
|
GetAccountTagResources(accountId uint64, resourceType int8, tagPath string) []entity.TagTree
|
||||||
|
|
||||||
// 获取指定账号有权限操作的资源codes
|
// 获取指定账号有权限操作的资源codes
|
||||||
GetAccountResourceCodes(accountId uint64, resourceType int8, tagPath string) []string
|
GetAccountResourceCodes(accountId uint64, resourceType int8, tagPath string) []string
|
||||||
|
|
||||||
// 关联资源
|
// SaveResource 保存资源标签
|
||||||
// @resourceCode 资源唯一编号
|
SaveResource(ctx context.Context, req *SaveResourceTagParam) error
|
||||||
// @resourceType 资源类型
|
|
||||||
// @tagIds 资源关联的标签
|
|
||||||
RelateResource(ctx context.Context, resourceCode string, resourceType int8, tagIds []uint64) error
|
|
||||||
|
|
||||||
// 根据资源信息获取对应的标签路径列表
|
// 根据资源信息获取对应的标签路径列表
|
||||||
ListTagPathByResource(resourceType int8, resourceCode string) []string
|
ListTagPathByResource(resourceType int8, resourceCode string) []string
|
||||||
|
|
||||||
// 根据tagPath获取自身及其所有子标签信息
|
|
||||||
ListTagByPath(tagPath ...string) []*entity.TagTree
|
|
||||||
|
|
||||||
// 根据账号id获取其可访问标签信息
|
// 根据账号id获取其可访问标签信息
|
||||||
ListTagByAccountId(accountId uint64) []string
|
ListTagByAccountId(accountId uint64) []string
|
||||||
|
|
||||||
@@ -56,7 +59,6 @@ type tagTreeAppImpl struct {
|
|||||||
base.AppImpl[*entity.TagTree, repository.TagTree]
|
base.AppImpl[*entity.TagTree, repository.TagTree]
|
||||||
|
|
||||||
tagTreeTeamRepo repository.TagTreeTeam `inject:"TagTreeTeamRepo"`
|
tagTreeTeamRepo repository.TagTreeTeam `inject:"TagTreeTeamRepo"`
|
||||||
tagResourceApp TagResource `inject:"TagResourceApp"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 注入TagTreeRepo
|
// 注入TagTreeRepo
|
||||||
@@ -76,9 +78,9 @@ func (p *tagTreeAppImpl) Save(ctx context.Context, tag *entity.TagTree) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return errorx.NewBiz("父节点不存在")
|
return errorx.NewBiz("父节点不存在")
|
||||||
}
|
}
|
||||||
if p.tagResourceApp.CountByCond(&entity.TagResource{TagId: tag.Pid}) > 0 {
|
// if p.tagResourceApp.CountByCond(&entity.TagResource{TagId: tag.Pid}) > 0 {
|
||||||
return errorx.NewBiz("该父标签已关联资源, 无法添加子标签")
|
// return errorx.NewBiz("该父标签已关联资源, 无法添加子标签")
|
||||||
}
|
// }
|
||||||
|
|
||||||
tag.CodePath = parentTag.CodePath + tag.Code + entity.CodePathSeparator
|
tag.CodePath = parentTag.CodePath + tag.Code + entity.CodePathSeparator
|
||||||
} else {
|
} else {
|
||||||
@@ -98,6 +100,8 @@ func (p *tagTreeAppImpl) Save(ctx context.Context, tag *entity.TagTree) error {
|
|||||||
return errorx.NewBiz("已存在该标签路径开头的标签, 请修改该标识code")
|
return errorx.NewBiz("已存在该标签路径开头的标签, 请修改该标识code")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 普通标签类型
|
||||||
|
tag.Type = -1
|
||||||
return p.Insert(ctx, tag)
|
return p.Insert(ctx, tag)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,12 +115,12 @@ func (p *tagTreeAppImpl) ListByQuery(condition *entity.TagTreeQuery, toEntity an
|
|||||||
p.GetRepo().SelectByCondition(condition, toEntity)
|
p.GetRepo().SelectByCondition(condition, toEntity)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *tagTreeAppImpl) GetAccountTagResources(accountId uint64, resourceType int8, tagPath string) []entity.TagResource {
|
func (p *tagTreeAppImpl) GetAccountTagResources(accountId uint64, resourceType int8, tagPath string) []entity.TagTree {
|
||||||
tagResourceQuery := &entity.TagResourceQuery{
|
tagResourceQuery := &entity.TagTreeQuery{
|
||||||
ResourceType: resourceType,
|
Type: resourceType,
|
||||||
}
|
}
|
||||||
|
|
||||||
var tagResources []entity.TagResource
|
var tagResources []entity.TagTree
|
||||||
var accountTagPaths []string
|
var accountTagPaths []string
|
||||||
|
|
||||||
if accountId != consts.AdminId {
|
if accountId != consts.AdminId {
|
||||||
@@ -127,70 +131,82 @@ func (p *tagTreeAppImpl) GetAccountTagResources(accountId uint64, resourceType i
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tagResourceQuery.TagPathLike = tagPath
|
tagResourceQuery.CodePathLike = tagPath
|
||||||
tagResourceQuery.TagPathLikes = accountTagPaths
|
tagResourceQuery.CodePathLikes = accountTagPaths
|
||||||
p.tagResourceApp.ListByQuery(tagResourceQuery, &tagResources)
|
p.ListByQuery(tagResourceQuery, &tagResources)
|
||||||
return tagResources
|
return tagResources
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *tagTreeAppImpl) GetAccountResourceCodes(accountId uint64, resourceType int8, tagPath string) []string {
|
func (p *tagTreeAppImpl) GetAccountResourceCodes(accountId uint64, resourceType int8, tagPath string) []string {
|
||||||
tagResources := p.GetAccountTagResources(accountId, resourceType, tagPath)
|
tagResources := p.GetAccountTagResources(accountId, resourceType, tagPath)
|
||||||
// resouce code去重
|
// resouce code去重
|
||||||
code2Resource := collx.ArrayToMap[entity.TagResource, string](tagResources, func(val entity.TagResource) string {
|
code2Resource := collx.ArrayToMap[entity.TagTree, string](tagResources, func(val entity.TagTree) string {
|
||||||
return val.ResourceCode
|
return val.Code
|
||||||
})
|
})
|
||||||
|
|
||||||
return collx.MapKeys(code2Resource)
|
return collx.MapKeys(code2Resource)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *tagTreeAppImpl) RelateResource(ctx context.Context, resourceCode string, resourceType int8, tagIds []uint64) error {
|
func (p *tagTreeAppImpl) SaveResource(ctx context.Context, req *SaveResourceTagParam) error {
|
||||||
|
resourceCode := req.ResourceCode
|
||||||
|
resourceType := req.ResourceType
|
||||||
|
resourceName := req.ResourceName
|
||||||
|
tagIds := req.TagIds
|
||||||
|
|
||||||
if resourceCode == "" {
|
if resourceCode == "" {
|
||||||
return errorx.NewBiz("资源编号不能为空")
|
return errorx.NewBiz("资源编号不能为空")
|
||||||
}
|
}
|
||||||
// 如果tagIds为空数组,则为解绑该标签资源关联关系
|
if resourceType == 0 {
|
||||||
if len(tagIds) == 0 {
|
return errorx.NewBiz("资源类型不能为空")
|
||||||
return p.tagResourceApp.DeleteByCond(ctx, &entity.TagResource{
|
|
||||||
ResourceCode: resourceCode,
|
|
||||||
ResourceType: resourceType,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var oldTagResources []*entity.TagResource
|
// 如果tagIds为空数组,则为删除该资源标签
|
||||||
p.tagResourceApp.ListByQuery(&entity.TagResourceQuery{ResourceType: resourceType, ResourceCode: resourceCode}, &oldTagResources)
|
if len(tagIds) == 0 {
|
||||||
|
return p.DeleteByCond(ctx, &entity.TagTree{Code: resourceCode, Type: resourceType})
|
||||||
|
}
|
||||||
|
|
||||||
|
if resourceName == "" {
|
||||||
|
resourceName = resourceCode
|
||||||
|
}
|
||||||
|
|
||||||
|
// 该资源对应的旧资源标签信息
|
||||||
|
var oldTagTree []*entity.TagTree
|
||||||
|
p.ListByCond(&entity.TagTree{Type: resourceType, Code: resourceCode}, &oldTagTree)
|
||||||
|
|
||||||
var addTagIds, delTagIds []uint64
|
var addTagIds, delTagIds []uint64
|
||||||
if len(oldTagResources) == 0 {
|
if len(oldTagTree) == 0 {
|
||||||
addTagIds = tagIds
|
addTagIds = tagIds
|
||||||
} else {
|
} else {
|
||||||
oldTagIds := collx.ArrayMap[*entity.TagResource, uint64](oldTagResources, func(tr *entity.TagResource) uint64 {
|
oldTagIds := collx.ArrayMap(oldTagTree, func(tag *entity.TagTree) uint64 {
|
||||||
return tr.TagId
|
return tag.Pid
|
||||||
})
|
})
|
||||||
addTagIds, delTagIds, _ = collx.ArrayCompare[uint64](tagIds, oldTagIds)
|
addTagIds, delTagIds, _ = collx.ArrayCompare[uint64](tagIds, oldTagIds)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(addTagIds) > 0 {
|
if len(addTagIds) > 0 {
|
||||||
addTagResource := make([]*entity.TagResource, 0)
|
addTagResource := make([]*entity.TagTree, 0)
|
||||||
for _, tagId := range addTagIds {
|
for _, tagId := range addTagIds {
|
||||||
tag, err := p.GetById(new(entity.TagTree), tagId)
|
tag, err := p.GetById(new(entity.TagTree), tagId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errorx.NewBiz("存在错误标签id")
|
return errorx.NewBiz("存在错误标签id")
|
||||||
}
|
}
|
||||||
addTagResource = append(addTagResource, &entity.TagResource{
|
addTagResource = append(addTagResource, &entity.TagTree{
|
||||||
ResourceCode: resourceCode,
|
Pid: tagId,
|
||||||
ResourceType: resourceType,
|
Code: resourceCode,
|
||||||
TagId: tagId,
|
Type: resourceType,
|
||||||
TagPath: tag.CodePath,
|
Name: resourceName,
|
||||||
|
CodePath: tag.CodePath + resourceCode + entity.CodePathSeparator,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if err := p.tagResourceApp.BatchInsert(ctx, addTagResource); err != nil {
|
if err := p.BatchInsert(ctx, addTagResource); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(delTagIds) > 0 {
|
if len(delTagIds) > 0 {
|
||||||
for _, tagId := range delTagIds {
|
for _, tagId := range delTagIds {
|
||||||
cond := &entity.TagResource{ResourceCode: resourceCode, ResourceType: resourceType, TagId: tagId}
|
cond := &entity.TagTree{Code: resourceCode, Type: resourceType, Pid: tagId}
|
||||||
if err := p.tagResourceApp.DeleteByCond(ctx, cond); err != nil {
|
if err := p.DeleteByCond(ctx, cond); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -200,19 +216,13 @@ func (p *tagTreeAppImpl) RelateResource(ctx context.Context, resourceCode string
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *tagTreeAppImpl) ListTagPathByResource(resourceType int8, resourceCode string) []string {
|
func (p *tagTreeAppImpl) ListTagPathByResource(resourceType int8, resourceCode string) []string {
|
||||||
var trs []*entity.TagResource
|
var trs []*entity.TagTree
|
||||||
p.tagResourceApp.ListByQuery(&entity.TagResourceQuery{ResourceType: resourceType, ResourceCode: resourceCode}, &trs)
|
p.ListByCond(&entity.TagTree{Type: resourceType, Code: resourceCode}, &trs)
|
||||||
return collx.ArrayMap(trs, func(tr *entity.TagResource) string {
|
return collx.ArrayMap(trs, func(tr *entity.TagTree) string {
|
||||||
return tr.TagPath
|
return tr.CodePath
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *tagTreeAppImpl) ListTagByPath(tagPaths ...string) []*entity.TagTree {
|
|
||||||
var tags []*entity.TagTree
|
|
||||||
p.GetRepo().SelectByCondition(&entity.TagTreeQuery{CodePathLikes: tagPaths}, &tags)
|
|
||||||
return tags
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *tagTreeAppImpl) ListTagByAccountId(accountId uint64) []string {
|
func (p *tagTreeAppImpl) ListTagByAccountId(accountId uint64) []string {
|
||||||
return p.tagTreeTeamRepo.SelectTagPathsByAccountId(accountId)
|
return p.tagTreeTeamRepo.SelectTagPathsByAccountId(accountId)
|
||||||
}
|
}
|
||||||
@@ -245,12 +255,12 @@ func (p *tagTreeAppImpl) FillTagInfo(resources ...entity.ITagResource) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// 获取所有资源code关联的标签列表信息
|
// 获取所有资源code关联的标签列表信息
|
||||||
var tagResources []*entity.TagResource
|
var tagResources []*entity.TagTree
|
||||||
p.tagResourceApp.ListByQuery(&entity.TagResourceQuery{ResourceCodes: collx.MapKeys(resourceCode2Resouce)}, &tagResources)
|
p.ListByQuery(&entity.TagTreeQuery{Codes: collx.MapKeys(resourceCode2Resouce)}, &tagResources)
|
||||||
|
|
||||||
for _, tr := range tagResources {
|
for _, tr := range tagResources {
|
||||||
// 赋值标签信息
|
// 赋值标签信息
|
||||||
resourceCode2Resouce[tr.ResourceCode].SetTagInfo(entity.ResourceTag{TagId: tr.TagId, TagPath: tr.TagPath})
|
resourceCode2Resouce[tr.Code].SetTagInfo(entity.ResourceTag{TagId: tr.Pid, TagPath: tr.GetParentPath()})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,7 +274,7 @@ func (p *tagTreeAppImpl) Delete(ctx context.Context, id uint64) error {
|
|||||||
return errorx.NewBiz("您无权删除该标签")
|
return errorx.NewBiz("您无权删除该标签")
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.tagResourceApp.CountByCond(&entity.TagResource{TagId: id}) > 0 {
|
if p.CountByCond(&entity.TagTree{Pid: id}) > 0 {
|
||||||
return errorx.NewBiz("请先移除该标签关联的资源")
|
return errorx.NewBiz("请先移除该标签关联的资源")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,9 @@ type TagTreeQuery struct {
|
|||||||
model.Model
|
model.Model
|
||||||
|
|
||||||
Pid uint64
|
Pid uint64
|
||||||
|
Type int8 `json:"type"`
|
||||||
Code string `json:"code"` // 标识
|
Code string `json:"code"` // 标识
|
||||||
|
Codes []string
|
||||||
CodePath string `json:"codePath"` // 标识路径
|
CodePath string `json:"codePath"` // 标识路径
|
||||||
CodePaths []string
|
CodePaths []string
|
||||||
Name string `json:"name"` // 名称
|
Name string `json:"name"` // 名称
|
||||||
@@ -14,19 +16,6 @@ type TagTreeQuery struct {
|
|||||||
CodePathLikes []string
|
CodePathLikes []string
|
||||||
}
|
}
|
||||||
|
|
||||||
type TagResourceQuery struct {
|
|
||||||
model.Model
|
|
||||||
|
|
||||||
TagPath string `json:"string"` // 标签路径
|
|
||||||
TagId uint64 `json:"tagId" form:"tagId"`
|
|
||||||
ResourceType int8 `json:"resourceType" form:"resourceType"` // 资源编码
|
|
||||||
ResourceCode string `json:"resourceCode" form:"resourceCode"` // 资源编码
|
|
||||||
ResourceCodes []string // 资源编码列表
|
|
||||||
|
|
||||||
TagPathLike string // 标签路径模糊查询
|
|
||||||
TagPathLikes []string
|
|
||||||
}
|
|
||||||
|
|
||||||
type TeamQuery struct {
|
type TeamQuery struct {
|
||||||
model.Model
|
model.Model
|
||||||
|
|
||||||
|
|||||||
@@ -1,47 +0,0 @@
|
|||||||
package entity
|
|
||||||
|
|
||||||
import (
|
|
||||||
"mayfly-go/pkg/model"
|
|
||||||
)
|
|
||||||
|
|
||||||
// 标签资源关联
|
|
||||||
type TagResource struct {
|
|
||||||
model.Model
|
|
||||||
|
|
||||||
TagId uint64 `json:"tagId"`
|
|
||||||
TagPath string `json:"tagPath"` // 标签路径
|
|
||||||
ResourceCode string `json:"resourceCode"` // 资源标识
|
|
||||||
ResourceType int8 `json:"resourceType"` // 资源类型
|
|
||||||
}
|
|
||||||
|
|
||||||
// 标签接口资源,如果要实现资源结构体填充标签信息,则资源结构体需要实现该接口
|
|
||||||
type ITagResource interface {
|
|
||||||
// 获取资源code
|
|
||||||
GetCode() string
|
|
||||||
|
|
||||||
// 赋值标签基本信息
|
|
||||||
SetTagInfo(rt ResourceTag)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 资源关联的标签信息
|
|
||||||
type ResourceTag struct {
|
|
||||||
TagId uint64 `json:"tagId" gorm:"-"`
|
|
||||||
TagPath string `json:"tagPath" gorm:"-"` // 标签路径
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *ResourceTag) SetTagInfo(rt ResourceTag) {
|
|
||||||
r.TagId = rt.TagId
|
|
||||||
r.TagPath = rt.TagPath
|
|
||||||
}
|
|
||||||
|
|
||||||
// 资源标签列表
|
|
||||||
type ResourceTags struct {
|
|
||||||
Tags []ResourceTag `json:"tags" gorm:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *ResourceTags) SetTagInfo(rt ResourceTag) {
|
|
||||||
if r.Tags == nil {
|
|
||||||
r.Tags = make([]ResourceTag, 0)
|
|
||||||
}
|
|
||||||
r.Tags = append(r.Tags, rt)
|
|
||||||
}
|
|
||||||
@@ -10,7 +10,8 @@ type TagTree struct {
|
|||||||
model.Model
|
model.Model
|
||||||
|
|
||||||
Pid uint64 `json:"pid"`
|
Pid uint64 `json:"pid"`
|
||||||
Code string `json:"code"` // 标识
|
Type int8 `json:"type"` // 类型: -1.普通标签; 其他值则为对应的资源类型
|
||||||
|
Code string `json:"code"` // 标识编码, 若类型不为-1,则为对应资源编码
|
||||||
CodePath string `json:"codePath"` // 标识路径
|
CodePath string `json:"codePath"` // 标识路径
|
||||||
Name string `json:"name"` // 名称
|
Name string `json:"name"` // 名称
|
||||||
Remark string `json:"remark"` // 备注说明
|
Remark string `json:"remark"` // 备注说明
|
||||||
@@ -21,7 +22,54 @@ const (
|
|||||||
CodePathSeparator = "/"
|
CodePathSeparator = "/"
|
||||||
)
|
)
|
||||||
|
|
||||||
// 获取根路径信息
|
// GetRootCode 获取根路径信息
|
||||||
func (pt *TagTree) GetRootCode() string {
|
func (pt *TagTree) GetRootCode() string {
|
||||||
return strings.Split(pt.CodePath, CodePathSeparator)[0]
|
return strings.Split(pt.CodePath, CodePathSeparator)[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetParentPath 获取父标签路径, 如CodePath = test/test1/test2/ -> test/test1/
|
||||||
|
func (pt *TagTree) GetParentPath() string {
|
||||||
|
// 去掉末尾的分隔符
|
||||||
|
input := strings.TrimRight(pt.CodePath, CodePathSeparator)
|
||||||
|
|
||||||
|
// 查找倒数第二个连字符位置
|
||||||
|
lastHyphenIndex := strings.LastIndex(input, CodePathSeparator)
|
||||||
|
if lastHyphenIndex == -1 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// 截取字符串
|
||||||
|
return input[:lastHyphenIndex+1]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 标签接口资源,如果要实现资源结构体填充标签信息,则资源结构体需要实现该接口
|
||||||
|
type ITagResource interface {
|
||||||
|
// 获取资源code
|
||||||
|
GetCode() string
|
||||||
|
|
||||||
|
// 赋值标签基本信息
|
||||||
|
SetTagInfo(rt ResourceTag)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 资源关联的标签信息
|
||||||
|
type ResourceTag struct {
|
||||||
|
TagId uint64 `json:"tagId" gorm:"-"`
|
||||||
|
TagPath string `json:"tagPath" gorm:"-"` // 标签路径
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ResourceTag) SetTagInfo(rt ResourceTag) {
|
||||||
|
r.TagId = rt.TagId
|
||||||
|
r.TagPath = rt.TagPath
|
||||||
|
}
|
||||||
|
|
||||||
|
// 资源标签列表
|
||||||
|
type ResourceTags struct {
|
||||||
|
Tags []ResourceTag `json:"tags" gorm:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ResourceTags) SetTagInfo(rt ResourceTag) {
|
||||||
|
if r.Tags == nil {
|
||||||
|
r.Tags = make([]ResourceTag, 0)
|
||||||
|
}
|
||||||
|
r.Tags = append(r.Tags, rt)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
package repository
|
|
||||||
|
|
||||||
import (
|
|
||||||
"mayfly-go/internal/tag/domain/entity"
|
|
||||||
"mayfly-go/pkg/base"
|
|
||||||
)
|
|
||||||
|
|
||||||
type TagResource interface {
|
|
||||||
base.Repo[*entity.TagResource]
|
|
||||||
|
|
||||||
SelectByCondition(condition *entity.TagResourceQuery, toEntity any, orderBy ...string)
|
|
||||||
}
|
|
||||||
@@ -7,7 +7,6 @@ import (
|
|||||||
func InitIoc() {
|
func InitIoc() {
|
||||||
ioc.Register(newTagTreeRepo(), ioc.WithComponentName("TagTreeRepo"))
|
ioc.Register(newTagTreeRepo(), ioc.WithComponentName("TagTreeRepo"))
|
||||||
ioc.Register(newTagTreeTeamRepo(), ioc.WithComponentName("TagTreeTeamRepo"))
|
ioc.Register(newTagTreeTeamRepo(), ioc.WithComponentName("TagTreeTeamRepo"))
|
||||||
ioc.Register(newTagResourceRepo(), ioc.WithComponentName("TagResourceRepo"))
|
|
||||||
ioc.Register(newTeamRepo(), ioc.WithComponentName("TeamRepo"))
|
ioc.Register(newTeamRepo(), ioc.WithComponentName("TeamRepo"))
|
||||||
ioc.Register(newTeamMemberRepo(), ioc.WithComponentName("TeamMemberRepo"))
|
ioc.Register(newTeamMemberRepo(), ioc.WithComponentName("TeamMemberRepo"))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,65 +0,0 @@
|
|||||||
package persistence
|
|
||||||
|
|
||||||
import (
|
|
||||||
"mayfly-go/internal/tag/domain/entity"
|
|
||||||
"mayfly-go/internal/tag/domain/repository"
|
|
||||||
"mayfly-go/pkg/base"
|
|
||||||
"mayfly-go/pkg/gormx"
|
|
||||||
)
|
|
||||||
|
|
||||||
type tagResourceRepoImpl struct {
|
|
||||||
base.RepoImpl[*entity.TagResource]
|
|
||||||
}
|
|
||||||
|
|
||||||
func newTagResourceRepo() repository.TagResource {
|
|
||||||
return &tagResourceRepoImpl{base.RepoImpl[*entity.TagResource]{M: new(entity.TagResource)}}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *tagResourceRepoImpl) SelectByCondition(condition *entity.TagResourceQuery, toEntity any, orderBy ...string) {
|
|
||||||
sql := "SELECT tr.resource_type, tr.resource_code, tr.tag_id, tr.tag_path FROM t_tag_resource tr WHERE tr.is_deleted = 0 "
|
|
||||||
|
|
||||||
params := make([]any, 0)
|
|
||||||
|
|
||||||
if condition.ResourceType != 0 {
|
|
||||||
sql = sql + " AND tr.resource_type = ?"
|
|
||||||
params = append(params, condition.ResourceType)
|
|
||||||
}
|
|
||||||
|
|
||||||
if condition.ResourceCode != "" {
|
|
||||||
sql = sql + " AND tr.resource_code = ?"
|
|
||||||
params = append(params, condition.ResourceCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(condition.ResourceCodes) > 0 {
|
|
||||||
sql = sql + " AND tr.resource_code IN (?)"
|
|
||||||
params = append(params, condition.ResourceCodes)
|
|
||||||
}
|
|
||||||
|
|
||||||
if condition.TagId != 0 {
|
|
||||||
sql = sql + " AND tr.tag_id = ?"
|
|
||||||
params = append(params, condition.TagId)
|
|
||||||
}
|
|
||||||
if condition.TagPath != "" {
|
|
||||||
sql = sql + " AND tr.tag_path = ?"
|
|
||||||
params = append(params, condition.TagPath)
|
|
||||||
}
|
|
||||||
if condition.TagPathLike != "" {
|
|
||||||
sql = sql + " AND tr.tag_path LIKE ?"
|
|
||||||
params = append(params, condition.TagPathLike+"%")
|
|
||||||
}
|
|
||||||
if len(condition.TagPathLikes) > 0 {
|
|
||||||
sql = sql + " AND ("
|
|
||||||
for i, v := range condition.TagPathLikes {
|
|
||||||
if i == 0 {
|
|
||||||
sql = sql + "tr.tag_path LIKE ?"
|
|
||||||
} else {
|
|
||||||
sql = sql + " OR tr.tag_path LIKE ?"
|
|
||||||
}
|
|
||||||
params = append(params, v+"%")
|
|
||||||
}
|
|
||||||
sql = sql + ")"
|
|
||||||
}
|
|
||||||
|
|
||||||
sql = sql + " ORDER BY tr.tag_path"
|
|
||||||
gormx.GetListBySql2Model(sql, toEntity, params...)
|
|
||||||
}
|
|
||||||
@@ -16,7 +16,7 @@ func newTagTreeRepo() repository.TagTree {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *tagTreeRepoImpl) SelectByCondition(condition *entity.TagTreeQuery, toEntity any, orderBy ...string) {
|
func (p *tagTreeRepoImpl) SelectByCondition(condition *entity.TagTreeQuery, toEntity any, orderBy ...string) {
|
||||||
sql := "SELECT DISTINCT(p.id), p.pid, p.code, p.code_path, p.name, p.remark, p.create_time, p.creator, p.update_time, p.modifier FROM t_tag_tree p WHERE p.is_deleted = 0 "
|
sql := "SELECT DISTINCT(p.id), p.pid, p.type, p.code, p.code_path, p.name, p.remark, p.create_time, p.creator, p.update_time, p.modifier FROM t_tag_tree p WHERE p.is_deleted = 0 "
|
||||||
|
|
||||||
params := make([]any, 0)
|
params := make([]any, 0)
|
||||||
if condition.Name != "" {
|
if condition.Name != "" {
|
||||||
@@ -27,6 +27,10 @@ func (p *tagTreeRepoImpl) SelectByCondition(condition *entity.TagTreeQuery, toEn
|
|||||||
sql = sql + " AND p.code_path = ?"
|
sql = sql + " AND p.code_path = ?"
|
||||||
params = append(params, condition.CodePath)
|
params = append(params, condition.CodePath)
|
||||||
}
|
}
|
||||||
|
if len(condition.Codes) > 0 {
|
||||||
|
sql = sql + " AND p.code IN (?)"
|
||||||
|
params = append(params, condition.Codes)
|
||||||
|
}
|
||||||
if len(condition.CodePaths) > 0 {
|
if len(condition.CodePaths) > 0 {
|
||||||
sql = sql + " AND p.code_path IN (?)"
|
sql = sql + " AND p.code_path IN (?)"
|
||||||
params = append(params, condition.CodePaths)
|
params = append(params, condition.CodePaths)
|
||||||
@@ -39,6 +43,10 @@ func (p *tagTreeRepoImpl) SelectByCondition(condition *entity.TagTreeQuery, toEn
|
|||||||
sql = sql + " AND p.pid = ?"
|
sql = sql + " AND p.pid = ?"
|
||||||
params = append(params, condition.Pid)
|
params = append(params, condition.Pid)
|
||||||
}
|
}
|
||||||
|
if condition.Type != 0 {
|
||||||
|
sql = sql + " AND p.type = ?"
|
||||||
|
params = append(params, condition.Type)
|
||||||
|
}
|
||||||
if len(condition.CodePathLikes) > 0 {
|
if len(condition.CodePathLikes) > 0 {
|
||||||
sql = sql + " AND ("
|
sql = sql + " AND ("
|
||||||
for i, v := range condition.CodePathLikes {
|
for i, v := range condition.CodePathLikes {
|
||||||
@@ -51,6 +59,6 @@ func (p *tagTreeRepoImpl) SelectByCondition(condition *entity.TagTreeQuery, toEn
|
|||||||
}
|
}
|
||||||
sql = sql + ")"
|
sql = sql + ")"
|
||||||
}
|
}
|
||||||
sql = sql + " ORDER BY p.code_path"
|
sql = sql + " ORDER BY p.type, p.code_path"
|
||||||
gormx.GetListBySql2Model(sql, toEntity, params...)
|
gormx.GetListBySql2Model(sql, toEntity, params...)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,8 +29,6 @@ func InitTagTreeRouter(router *gin.RouterGroup) {
|
|||||||
req.NewGet("/resources/:rtype/tag-paths", m.TagResources),
|
req.NewGet("/resources/:rtype/tag-paths", m.TagResources),
|
||||||
|
|
||||||
req.NewGet("/resources/count", m.CountTagResource),
|
req.NewGet("/resources/count", m.CountTagResource),
|
||||||
|
|
||||||
req.NewGet("/resources", m.QueryTagResources),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
req.BatchSetGroup(tagTree, reqs[:])
|
req.BatchSetGroup(tagTree, reqs[:])
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"database/sql/driver"
|
||||||
|
"encoding/json"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -125,3 +127,14 @@ func GetIdByGenType(genType IdGenType) uint64 {
|
|||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Map[K comparable, V any] map[K]V
|
||||||
|
|
||||||
|
func (m *Map[K, V]) Scan(value any) error {
|
||||||
|
return json.Unmarshal(value.([]byte), m)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m Map[K, V]) Value() (driver.Value, error) {
|
||||||
|
return json.Marshal(m)
|
||||||
|
}
|
||||||
|
|||||||
@@ -334,6 +334,7 @@ CREATE TABLE `t_machine` (
|
|||||||
`name` varchar(32) DEFAULT NULL,
|
`name` varchar(32) DEFAULT NULL,
|
||||||
`ip` varchar(50) NOT NULL,
|
`ip` varchar(50) NOT NULL,
|
||||||
`port` int(12) NOT NULL,
|
`port` int(12) NOT NULL,
|
||||||
|
`protocol` tinyint(2) NULL COMMENT '协议 1、SSH 2、RDP',
|
||||||
`username` varchar(12) NOT NULL,
|
`username` varchar(12) NOT NULL,
|
||||||
`auth_method` tinyint(2) DEFAULT NULL COMMENT '1.密码登录2.publickey登录',
|
`auth_method` tinyint(2) DEFAULT NULL COMMENT '1.密码登录2.publickey登录',
|
||||||
`password` varchar(100) DEFAULT NULL,
|
`password` varchar(100) DEFAULT NULL,
|
||||||
@@ -634,7 +635,7 @@ INSERT INTO `t_sys_config` (name, `key`, params, value, remark, create_time, cre
|
|||||||
INSERT INTO `t_sys_config` (name, `key`, params, value, remark, permission, create_time, creator_id, creator, update_time, modifier_id, modifier, is_deleted, delete_time) VALUES('oauth2登录配置', 'Oauth2Login', '[{"name":"是否启用","model":"enable","placeholder":"是否启用oauth2登录","options":"true,false"},{"name":"名称","model":"name","placeholder":"oauth2名称"},{"name":"Client ID","model":"clientId","placeholder":"Client ID"},{"name":"Client Secret","model":"clientSecret","placeholder":"Client Secret"},{"name":"Authorization URL","model":"authorizationURL","placeholder":"Authorization URL"},{"name":"AccessToken URL","model":"accessTokenURL","placeholder":"AccessToken URL"},{"name":"Redirect URL","model":"redirectURL","placeholder":"本系统地址"},{"name":"Scopes","model":"scopes","placeholder":"Scopes"},{"name":"Resource URL","model":"resourceURL","placeholder":"获取用户信息资源地址"},{"name":"UserIdentifier","model":"userIdentifier","placeholder":"用户唯一标识字段;格式为type:fieldPath(string:username)"},{"name":"是否自动注册","model":"autoRegister","placeholder":"","options":"true,false"}]', '', 'oauth2登录相关配置信息', 'admin,', '2023-07-22 13:58:51', 1, 'admin', '2023-07-22 19:34:37', 1, 'admin', 0, NULL);
|
INSERT INTO `t_sys_config` (name, `key`, params, value, remark, permission, create_time, creator_id, creator, update_time, modifier_id, modifier, is_deleted, delete_time) VALUES('oauth2登录配置', 'Oauth2Login', '[{"name":"是否启用","model":"enable","placeholder":"是否启用oauth2登录","options":"true,false"},{"name":"名称","model":"name","placeholder":"oauth2名称"},{"name":"Client ID","model":"clientId","placeholder":"Client ID"},{"name":"Client Secret","model":"clientSecret","placeholder":"Client Secret"},{"name":"Authorization URL","model":"authorizationURL","placeholder":"Authorization URL"},{"name":"AccessToken URL","model":"accessTokenURL","placeholder":"AccessToken URL"},{"name":"Redirect URL","model":"redirectURL","placeholder":"本系统地址"},{"name":"Scopes","model":"scopes","placeholder":"Scopes"},{"name":"Resource URL","model":"resourceURL","placeholder":"获取用户信息资源地址"},{"name":"UserIdentifier","model":"userIdentifier","placeholder":"用户唯一标识字段;格式为type:fieldPath(string:username)"},{"name":"是否自动注册","model":"autoRegister","placeholder":"","options":"true,false"}]', '', 'oauth2登录相关配置信息', 'admin,', '2023-07-22 13:58:51', 1, 'admin', '2023-07-22 19:34:37', 1, 'admin', 0, NULL);
|
||||||
INSERT INTO `t_sys_config` (name, `key`, params, value, remark, permission, create_time, creator_id, creator, update_time, modifier_id, modifier, is_deleted, delete_time) VALUES('ldap登录配置', 'LdapLogin', '[{"name":"是否启用","model":"enable","placeholder":"是否启用","options":"true,false"},{"name":"host","model":"host","placeholder":"host"},{"name":"port","model":"port","placeholder":"port"},{"name":"bindDN","model":"bindDN","placeholder":"LDAP 服务的管理员账号,如: \\"cn=admin,dc=example,dc=com\\""},{"name":"bindPwd","model":"bindPwd","placeholder":"LDAP 服务的管理员密码"},{"name":"baseDN","model":"baseDN","placeholder":"用户所在的 base DN, 如: \\"ou=users,dc=example,dc=com\\""},{"name":"userFilter","model":"userFilter","placeholder":"过滤用户的方式, 如: \\"(uid=%s)、(&(objectClass=organizationalPerson)(uid=%s))\\""},{"name":"uidMap","model":"uidMap","placeholder":"用户id和 LDAP 字段名之间的映射关系,如: cn"},{"name":"udnMap","model":"udnMap","placeholder":"用户姓名(dispalyName)和 LDAP 字段名之间的映射关系,如: displayName"},{"name":"emailMap","model":"emailMap","placeholder":"用户email和 LDAP 字段名之间的映射关系"},{"name":"skipTLSVerify","model":"skipTLSVerify","placeholder":"客户端是否跳过 TLS 证书验证","options":"true,false"},{"name":"安全协议","model":"securityProtocol","placeholder":"安全协议(为Null不使用安全协议),如: StartTLS, LDAPS","options":"Null,StartTLS,LDAPS"}]', '', 'ldap登录相关配置', 'admin,', '2023-08-25 21:47:20', 1, 'admin', '2023-08-25 22:56:07', 1, 'admin', 0, NULL);
|
INSERT INTO `t_sys_config` (name, `key`, params, value, remark, permission, create_time, creator_id, creator, update_time, modifier_id, modifier, is_deleted, delete_time) VALUES('ldap登录配置', 'LdapLogin', '[{"name":"是否启用","model":"enable","placeholder":"是否启用","options":"true,false"},{"name":"host","model":"host","placeholder":"host"},{"name":"port","model":"port","placeholder":"port"},{"name":"bindDN","model":"bindDN","placeholder":"LDAP 服务的管理员账号,如: \\"cn=admin,dc=example,dc=com\\""},{"name":"bindPwd","model":"bindPwd","placeholder":"LDAP 服务的管理员密码"},{"name":"baseDN","model":"baseDN","placeholder":"用户所在的 base DN, 如: \\"ou=users,dc=example,dc=com\\""},{"name":"userFilter","model":"userFilter","placeholder":"过滤用户的方式, 如: \\"(uid=%s)、(&(objectClass=organizationalPerson)(uid=%s))\\""},{"name":"uidMap","model":"uidMap","placeholder":"用户id和 LDAP 字段名之间的映射关系,如: cn"},{"name":"udnMap","model":"udnMap","placeholder":"用户姓名(dispalyName)和 LDAP 字段名之间的映射关系,如: displayName"},{"name":"emailMap","model":"emailMap","placeholder":"用户email和 LDAP 字段名之间的映射关系"},{"name":"skipTLSVerify","model":"skipTLSVerify","placeholder":"客户端是否跳过 TLS 证书验证","options":"true,false"},{"name":"安全协议","model":"securityProtocol","placeholder":"安全协议(为Null不使用安全协议),如: StartTLS, LDAPS","options":"Null,StartTLS,LDAPS"}]', '', 'ldap登录相关配置', 'admin,', '2023-08-25 21:47:20', 1, 'admin', '2023-08-25 22:56:07', 1, 'admin', 0, NULL);
|
||||||
INSERT INTO `t_sys_config` (`name`, `key`, `params`, `value`, `remark`, `permission`, `create_time`, `creator_id`, `creator`, `update_time`, `modifier_id`, `modifier`, `is_deleted`, `delete_time`) VALUES('系统全局样式设置', 'SysStyleConfig', '[{"model":"logoIcon","name":"logo图标","placeholder":"系统logo图标(base64编码, 建议svg格式,不超过10k)","required":false},{"model":"title","name":"菜单栏标题","placeholder":"系统菜单栏标题展示","required":false},{"model":"viceTitle","name":"登录页标题","placeholder":"登录页标题展示","required":false},{"model":"useWatermark","name":"是否启用水印","placeholder":"是否启用系统水印","options":"true,false","required":false},{"model":"watermarkContent","name":"水印补充信息","placeholder":"额外水印信息","required":false}]', '{"title":"mayfly-go","viceTitle":"mayfly-go","logoIcon":"","useWatermark":"true","watermarkContent":""}', '系统icon、标题、水印信息等配置', 'all', '2024-01-04 15:17:18', 1, 'admin', '2024-01-05 09:40:44', 1, 'admin', 0, NULL);
|
INSERT INTO `t_sys_config` (`name`, `key`, `params`, `value`, `remark`, `permission`, `create_time`, `creator_id`, `creator`, `update_time`, `modifier_id`, `modifier`, `is_deleted`, `delete_time`) VALUES('系统全局样式设置', 'SysStyleConfig', '[{"model":"logoIcon","name":"logo图标","placeholder":"系统logo图标(base64编码, 建议svg格式,不超过10k)","required":false},{"model":"title","name":"菜单栏标题","placeholder":"系统菜单栏标题展示","required":false},{"model":"viceTitle","name":"登录页标题","placeholder":"登录页标题展示","required":false},{"model":"useWatermark","name":"是否启用水印","placeholder":"是否启用系统水印","options":"true,false","required":false},{"model":"watermarkContent","name":"水印补充信息","placeholder":"额外水印信息","required":false}]', '{"title":"mayfly-go","viceTitle":"mayfly-go","logoIcon":"","useWatermark":"true","watermarkContent":""}', '系统icon、标题、水印信息等配置', 'all', '2024-01-04 15:17:18', 1, 'admin', '2024-01-05 09:40:44', 1, 'admin', 0, NULL);
|
||||||
INSERT INTO `t_sys_config` (`name`, `key`, `params`, `value`, `remark`, `permission`, `create_time`, `creator_id`, `creator`, `update_time`, `modifier_id`, `modifier`, `is_deleted`, `delete_time`) VALUES('机器相关配置', 'MachineConfig', '[{"name":"终端回放存储路径","model":"terminalRecPath","placeholder":"终端回放存储路径"},{"name":"uploadMaxFileSize","model":"uploadMaxFileSize","placeholder":"允许上传的最大文件大小(1MB\\2GB等)"},{"model":"termOpSaveDays","name":"终端记录保存时间","placeholder":"终端记录保存时间(单位天)"}]', '{"terminalRecPath":"./rec","uploadMaxFileSize":"100MB"}', '机器相关配置,如终端回放路径等', 'all', '2023-07-13 16:26:44', 1, 'admin', '2024-01-15 16:30:22', 1, 'admin', 0, NULL);
|
INSERT INTO t_sys_config ( name, `key`, params, value, remark, permission, create_time, creator_id, creator, update_time, modifier_id, modifier, is_deleted, delete_time) VALUES('机器相关配置', 'MachineConfig', '[{"name":"终端回放存储路径","model":"terminalRecPath","placeholder":"终端回放存储路径"},{"name":"uploadMaxFileSize","model":"uploadMaxFileSize","placeholder":"允许上传的最大文件大小(1MB、2GB等)"},{"model":"termOpSaveDays","name":"终端记录保存时间","placeholder":"终端记录保存时间(单位天)"},{"model":"guacdHost","name":"guacd服务ip","placeholder":"guacd服务ip,默认 127.0.0.1","required":false},{"name":"guacd服务端口","model":"guacdPort","placeholder":"guacd服务端口,默认 4822","required":false},{"model":"guacdFilePath","name":"guacd服务文件存储位置","placeholder":"guacd服务文件存储位置,用于挂载RDP文件夹"},{"name":"guacd服务记录存储位置","model":"guacdRecPath","placeholder":"guacd服务记录存储位置,用于记录rdp操作记录"}]', '{"terminalRecPath":"./rec","uploadMaxFileSize":"1000MB","termOpSaveDays":"30","guacdHost":"","guacdPort":"","guacdFilePath":"./guacd/rdp-file","guacdRecPath":"./guacd/rdp-rec"}', '机器相关配置,如终端回放路径等', 'all', '2023-07-13 16:26:44', 1, 'admin', '2024-04-06 12:25:03', 1, 'admin', 0, NULL);
|
||||||
INSERT INTO `t_sys_config` (`name`, `key`, `params`, `value`, `remark`, `permission`, `create_time`, `creator_id`, `creator`, `update_time`, `modifier_id`, `modifier`, `is_deleted`, `delete_time`) VALUES('数据库备份恢复', 'DbBackupRestore', '[{"model":"backupPath","name":"备份路径","placeholder":"备份文件存储路径"}]', '{"backupPath":"./db/backup"}', '', 'admin,', '2023-12-29 09:55:26', 1, 'admin', '2023-12-29 15:45:24', 1, 'admin', 0, NULL);
|
INSERT INTO `t_sys_config` (`name`, `key`, `params`, `value`, `remark`, `permission`, `create_time`, `creator_id`, `creator`, `update_time`, `modifier_id`, `modifier`, `is_deleted`, `delete_time`) VALUES('数据库备份恢复', 'DbBackupRestore', '[{"model":"backupPath","name":"备份路径","placeholder":"备份文件存储路径"}]', '{"backupPath":"./db/backup"}', '', 'admin,', '2023-12-29 09:55:26', 1, 'admin', '2023-12-29 15:45:24', 1, 'admin', 0, NULL);
|
||||||
INSERT INTO `t_sys_config` (`name`, `key`, `params`, `value`, `remark`, `permission`, `create_time`, `creator_id`, `creator`, `update_time`, `modifier_id`, `modifier`, `is_deleted`, `delete_time`) VALUES('Mysql可执行文件', 'MysqlBin', '[{"model":"path","name":"路径","placeholder":"可执行文件路径","required":true},{"model":"mysql","name":"mysql","placeholder":"mysql命令路径(空则为 路径/mysql)","required":false},{"model":"mysqldump","name":"mysqldump","placeholder":"mysqldump命令路径(空则为 路径/mysqldump)","required":false},{"model":"mysqlbinlog","name":"mysqlbinlog","placeholder":"mysqlbinlog命令路径(空则为 路径/mysqlbinlog)","required":false}]', '{"mysql":"","mysqldump":"","mysqlbinlog":"","path":"./db/mysql/bin"}', '', 'admin,', '2023-12-29 10:01:33', 1, 'admin', '2023-12-29 13:34:40', 1, 'admin', 0, NULL);
|
INSERT INTO `t_sys_config` (`name`, `key`, `params`, `value`, `remark`, `permission`, `create_time`, `creator_id`, `creator`, `update_time`, `modifier_id`, `modifier`, `is_deleted`, `delete_time`) VALUES('Mysql可执行文件', 'MysqlBin', '[{"model":"path","name":"路径","placeholder":"可执行文件路径","required":true},{"model":"mysql","name":"mysql","placeholder":"mysql命令路径(空则为 路径/mysql)","required":false},{"model":"mysqldump","name":"mysqldump","placeholder":"mysqldump命令路径(空则为 路径/mysqldump)","required":false},{"model":"mysqlbinlog","name":"mysqlbinlog","placeholder":"mysqlbinlog命令路径(空则为 路径/mysqlbinlog)","required":false}]', '{"mysql":"","mysqldump":"","mysqlbinlog":"","path":"./db/mysql/bin"}', '', 'admin,', '2023-12-29 10:01:33', 1, 'admin', '2023-12-29 13:34:40', 1, 'admin', 0, NULL);
|
||||||
INSERT INTO `t_sys_config` (`name`, `key`, `params`, `value`, `remark`, `permission`, `create_time`, `creator_id`, `creator`, `update_time`, `modifier_id`, `modifier`, `is_deleted`, `delete_time`) VALUES('MariaDB可执行文件', 'MariadbBin', '[{"model":"path","name":"路径","placeholder":"可执行文件路径","required":true},{"model":"mysql","name":"mysql","placeholder":"mysql命令路径(空则为 路径/mysql)","required":false},{"model":"mysqldump","name":"mysqldump","placeholder":"mysqldump命令路径(空则为 路径/mysqldump)","required":false},{"model":"mysqlbinlog","name":"mysqlbinlog","placeholder":"mysqlbinlog命令路径(空则为 路径/mysqlbinlog)","required":false}]', '{"mysql":"","mysqldump":"","mysqlbinlog":"","path":"./db/mariadb/bin"}', '', 'admin,', '2023-12-29 10:01:33', 1, 'admin', '2023-12-29 13:34:40', 1, 'admin', 0, NULL);
|
INSERT INTO `t_sys_config` (`name`, `key`, `params`, `value`, `remark`, `permission`, `create_time`, `creator_id`, `creator`, `update_time`, `modifier_id`, `modifier`, `is_deleted`, `delete_time`) VALUES('MariaDB可执行文件', 'MariadbBin', '[{"model":"path","name":"路径","placeholder":"可执行文件路径","required":true},{"model":"mysql","name":"mysql","placeholder":"mysql命令路径(空则为 路径/mysql)","required":false},{"model":"mysqldump","name":"mysqldump","placeholder":"mysqldump命令路径(空则为 路径/mysqldump)","required":false},{"model":"mysqlbinlog","name":"mysqlbinlog","placeholder":"mysqlbinlog命令路径(空则为 路径/mysqlbinlog)","required":false}]', '{"mysql":"","mysqldump":"","mysqlbinlog":"","path":"./db/mariadb/bin"}', '', 'admin,', '2023-12-29 10:01:33', 1, 'admin', '2023-12-29 13:34:40', 1, 'admin', 0, NULL);
|
||||||
@@ -936,26 +937,6 @@ CREATE TABLE `t_tag_tree_team` (
|
|||||||
KEY `idx_tag_id` (`tag_id`) USING BTREE
|
KEY `idx_tag_id` (`tag_id`) USING BTREE
|
||||||
) ENGINE=InnoDB AUTO_INCREMENT=32 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='标签树团队关联信息';
|
) ENGINE=InnoDB AUTO_INCREMENT=32 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='标签树团队关联信息';
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `t_tag_resource`;
|
|
||||||
CREATE TABLE `t_tag_resource` (
|
|
||||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
|
||||||
`tag_id` bigint NOT NULL,
|
|
||||||
`tag_path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '标签路径',
|
|
||||||
`resource_code` varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '资源编码',
|
|
||||||
`resource_type` tinyint NOT NULL COMMENT '资源类型',
|
|
||||||
`create_time` datetime NOT NULL,
|
|
||||||
`creator_id` bigint NOT NULL,
|
|
||||||
`creator` varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
|
|
||||||
`update_time` datetime NOT NULL,
|
|
||||||
`modifier_id` bigint NOT NULL,
|
|
||||||
`modifier` varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
|
|
||||||
`is_deleted` tinyint DEFAULT '0',
|
|
||||||
`delete_time` datetime DEFAULT NULL,
|
|
||||||
PRIMARY KEY (`id`),
|
|
||||||
KEY `idx_tag_path` (`tag_path`(100)) USING BTREE,
|
|
||||||
KEY `idx_resource_code` (`resource_code`) USING BTREE
|
|
||||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='标签资源关联表';
|
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of t_tag_tree_team
|
-- Records of t_tag_tree_team
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
|
|||||||
@@ -50,7 +50,43 @@ ALTER TABLE t_sys_log ADD extra varchar(5000) NULL;
|
|||||||
ALTER TABLE t_sys_log MODIFY COLUMN resp text NULL;
|
ALTER TABLE t_sys_log MODIFY COLUMN resp text NULL;
|
||||||
|
|
||||||
-- rdp相关
|
-- rdp相关
|
||||||
ALTER TABLE `t_machine` ADD COLUMN `protocol` tinyint(2) NULL COMMENT '机器类型 1、SSH 2、RDP' AFTER `name`;
|
ALTER TABLE `t_machine` ADD COLUMN `protocol` tinyint(2) NULL COMMENT '协议 1、SSH 2、RDP' AFTER `name`;
|
||||||
update `t_machine` set `protocol` = 1 where `protocol` is NULL;
|
update `t_machine` set `protocol` = 1 where `protocol` is NULL;
|
||||||
delete from `t_sys_config` where `key` = 'MachineConfig';
|
delete from `t_sys_config` where `key` = 'MachineConfig';
|
||||||
INSERT INTO `t_sys_config` (`id`, `name`, `key`, `params`, `value`, `remark`, `permission`, `create_time`, `creator_id`, `creator`, `update_time`, `modifier_id`, `modifier`, `is_deleted`, `delete_time`) VALUES (12, '机器相关配置', 'MachineConfig', '[{\"name\":\"终端回放存储路径\",\"model\":\"terminalRecPath\",\"placeholder\":\"终端回放存储路径\"},{\"name\":\"uploadMaxFileSize\",\"model\":\"uploadMaxFileSize\",\"placeholder\":\"允许上传的最大文件大小(1MB、2GB等)\"},{\"model\":\"termOpSaveDays\",\"name\":\"终端记录保存时间\",\"placeholder\":\"终端记录保存时间(单位天)\"},{\"model\":\"guacdHost\",\"name\":\"guacd服务ip\",\"placeholder\":\"guacd服务ip,默认 127.0.0.1\"},{\"name\":\"guacd服务端口\",\"model\":\"guacdPort\",\"placeholder\":\"guacd服务端口,默认 4822\"},{\"model\":\"guacdFilePath\",\"name\":\"guacd服务文件存储位置\",\"placeholder\":\"guacd服务文件存储位置,用于挂载RDP文件夹\"},{\"name\":\"guacd服务记录存储位置\",\"model\":\"guacdRecPath\",\"placeholder\":\"guacd服务记录存储位置,用于记录rdp操作记录\"}]', '{\"terminalRecPath\":\"./rec\",\"uploadMaxFileSize\":\"1000MB\",\"termOpSaveDays\":\"30\",\"guacdHost\":\"127.0.0.1\",\"guacdPort\":\"4822\",\"guacdFilePath\":\"/Users/leozy/Desktop/developer/service/guacd/rdp-file\",\"guacdRecPath\":\"/Users/leozy/Desktop/developer/service/guacd/rdp-rec\"}', '机器相关配置,如终端回放路径等', 'all', '2023-07-13 16:26:44', 1, 'admin', '2024-04-04 13:11:52', 12, 'liuzongyang', 0, NULL);
|
INSERT INTO t_sys_config ( name, `key`, params, value, remark, permission, create_time, creator_id, creator, update_time, modifier_id, modifier, is_deleted, delete_time) VALUES('机器相关配置', 'MachineConfig', '[{"name":"终端回放存储路径","model":"terminalRecPath","placeholder":"终端回放存储路径"},{"name":"uploadMaxFileSize","model":"uploadMaxFileSize","placeholder":"允许上传的最大文件大小(1MB、2GB等)"},{"model":"termOpSaveDays","name":"终端记录保存时间","placeholder":"终端记录保存时间(单位天)"},{"model":"guacdHost","name":"guacd服务ip","placeholder":"guacd服务ip,默认 127.0.0.1","required":false},{"name":"guacd服务端口","model":"guacdPort","placeholder":"guacd服务端口,默认 4822","required":false},{"model":"guacdFilePath","name":"guacd服务文件存储位置","placeholder":"guacd服务文件存储位置,用于挂载RDP文件夹"},{"name":"guacd服务记录存储位置","model":"guacdRecPath","placeholder":"guacd服务记录存储位置,用于记录rdp操作记录"}]', '{"terminalRecPath":"./rec","uploadMaxFileSize":"1000MB","termOpSaveDays":"30","guacdHost":"","guacdPort":"","guacdFilePath":"./guacd/rdp-file","guacdRecPath":"./guacd/rdp-rec"}', '机器相关配置,如终端回放路径等', 'all', '2023-07-13 16:26:44', 1, 'admin', '2024-04-06 12:25:03', 1, 'admin', 0, NULL);
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
INSERT
|
||||||
|
INTO
|
||||||
|
t_tag_tree (pid,
|
||||||
|
code,
|
||||||
|
code_path,
|
||||||
|
type,
|
||||||
|
name,
|
||||||
|
create_time,
|
||||||
|
creator_id,
|
||||||
|
creator,
|
||||||
|
update_time,
|
||||||
|
modifier_id,
|
||||||
|
modifier,
|
||||||
|
is_deleted)
|
||||||
|
select
|
||||||
|
tag_id,
|
||||||
|
resource_code,
|
||||||
|
CONCAT(tag_path , resource_code, '/'),
|
||||||
|
resource_type,
|
||||||
|
resource_code,
|
||||||
|
DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:%s'),
|
||||||
|
1,
|
||||||
|
'admin',
|
||||||
|
DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:%s'),
|
||||||
|
1,
|
||||||
|
'admin',
|
||||||
|
0
|
||||||
|
from
|
||||||
|
t_tag_resource
|
||||||
|
WHERE
|
||||||
|
is_deleted = 0;
|
||||||
|
|
||||||
|
DROP TABLE t_tag_tree;
|
||||||
|
COMMIT;
|
||||||
Reference in New Issue
Block a user