mirror of
https://gitee.com/dromara/mayfly-go
synced 2025-12-08 00:40:26 +08:00
refactor: 使用泛型重构参数绑定等
This commit is contained in:
@@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
## 前言
|
## 前言
|
||||||
|
|
||||||
Web版 **统一管理操作平台**,集成了对Linux系统的全面操作支持(包括终端管理[终端回放、命令过滤]、文件管理、脚本执行、进程监控及计划任务设置),同时提供了多种数据库(如 MySQL、PostgreSQL、Oracle、SQL Server、达梦、高斯、SQLite 等)的数据操作、数据同步与数据迁移功能。此外,还支持 Redis(单机、哨兵、集群模式)以及 MongoDB 的操作管理,并结合工单流程审批功能,为企业提供一站式的运维与管理解决方案。
|
Web 版 **统一管理操作平台**,集成了对 Linux 系统的全面操作支持(包括终端管理[终端回放、命令过滤]、文件管理、脚本执行、进程监控及计划任务设置),同时提供了多种数据库(如 MySQL、PostgreSQL、Oracle、SQL Server、达梦、高斯、SQLite 等)的数据操作、数据同步与数据迁移功能。此外,还支持 Redis(单机、哨兵、集群模式)、 MongoDB 、Es 的操作管理,并结合工单流程审批功能,为企业提供一站式的运维与管理解决方案。
|
||||||
|
|
||||||
## 开发语言与主要框架
|
## 开发语言与主要框架
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
## Preface
|
## Preface
|
||||||
|
|
||||||
Web-based **Unified Management and Operation Platform**, integrating comprehensive operation support for Linux systems (including terminal management [terminal playback, command filtering], file management, script execution, process monitoring, and cronjob settings). It also provides data operation, data synchronization, and data migration for multiple databases (such as MySQL, PostgreSQL, Oracle, SQL Server, Dameng, Gauss, SQLite, etc.). Additionally, it supports Redis operations (standalone, sentinel, and cluster modes) and MongoDB management, combined with work order process approval functionality to offer enterprises an all-in-one solution for operations and management.
|
Web-based **Unified Management and Operation Platform**, integrating comprehensive operation support for Linux systems (including terminal management [terminal playback, command filtering], file management, script execution, process monitoring, and cronjob settings). It also provides data operation, data synchronization, and data migration for multiple databases (such as MySQL, PostgreSQL, Oracle, SQL Server, Dameng, Gauss, SQLite, etc.). Additionally, it supports Redis operations (standalone, sentinel, and cluster modes) and MongoDB、Es management, combined with work order process approval functionality to offer enterprises an all-in-one solution for operations and management.
|
||||||
|
|
||||||
## Development languages and major frameworks
|
## Development languages and major frameworks
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
"crypto-js": "^4.2.0",
|
"crypto-js": "^4.2.0",
|
||||||
"dayjs": "^1.11.13",
|
"dayjs": "^1.11.13",
|
||||||
"echarts": "^5.6.0",
|
"echarts": "^5.6.0",
|
||||||
"element-plus": "^2.9.10",
|
"element-plus": "^2.9.11",
|
||||||
"js-base64": "^3.7.7",
|
"js-base64": "^3.7.7",
|
||||||
"jsencrypt": "^3.3.2",
|
"jsencrypt": "^3.3.2",
|
||||||
"mitt": "^3.0.1",
|
"mitt": "^3.0.1",
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export const ResourceTypeEnum = {
|
|||||||
Redis: EnumValue.of(3, 'redis').setExtra({ icon: 'icon redis/redis', iconColor: 'var(--el-color-danger)' }).tagTypeInfo(),
|
Redis: EnumValue.of(3, 'redis').setExtra({ icon: 'icon redis/redis', iconColor: 'var(--el-color-danger)' }).tagTypeInfo(),
|
||||||
Mongo: EnumValue.of(4, 'mongo').setExtra({ icon: 'icon mongo/mongo', iconColor: 'var(--el-color-success)' }).tagTypeDanger(),
|
Mongo: EnumValue.of(4, 'mongo').setExtra({ icon: 'icon mongo/mongo', iconColor: 'var(--el-color-success)' }).tagTypeDanger(),
|
||||||
AuthCert: EnumValue.of(5, '授权凭证').setExtra({ icon: 'Ticket', iconColor: 'var(--el-color-success)' }),
|
AuthCert: EnumValue.of(5, '授权凭证').setExtra({ icon: 'Ticket', iconColor: 'var(--el-color-success)' }),
|
||||||
Es: EnumValue.of(6, 'ES实例').setExtra({ icon: 'Coin', iconColor: 'var(--el-color-warning)' }).tagTypeWarning(),
|
Es: EnumValue.of(6, 'ES实例').setExtra({ icon: 'icon es/es-color', iconColor: 'var(--el-color-warning)' }).tagTypeWarning(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// 标签关联的资源类型
|
// 标签关联的资源类型
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-tree-select
|
<el-tree-select
|
||||||
v-bind="$attrs"
|
v-bind="$attrs"
|
||||||
v-model="state.selectTags"
|
v-model="modelValue"
|
||||||
@change="changeTag"
|
|
||||||
:data="tags"
|
:data="tags"
|
||||||
:placeholder="$t('tag.selectTagPlaceholder')"
|
:placeholder="$t('tag.selectTagPlaceholder')"
|
||||||
:default-expanded-keys="defaultExpandedKeys"
|
:default-expanded-keys="defaultExpandedKeys"
|
||||||
@@ -35,44 +34,33 @@ import { tagApi } from '../tag/api';
|
|||||||
import { TagResourceTypeEnum } from '@/common/commonEnum';
|
import { TagResourceTypeEnum } from '@/common/commonEnum';
|
||||||
import EnumValue from '@/common/Enum';
|
import EnumValue from '@/common/Enum';
|
||||||
|
|
||||||
//定义事件
|
|
||||||
const emit = defineEmits(['update:modelValue', 'changeTag', 'input']);
|
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
selectTags: {
|
|
||||||
type: [Array<any>, Object],
|
|
||||||
},
|
|
||||||
tagType: {
|
tagType: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: TagResourceTypeEnum.Tag.value,
|
default: TagResourceTypeEnum.Tag.value,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const modelValue = defineModel<Array<any> | Object>('modelValue');
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
tags: [],
|
tags: [],
|
||||||
// 单选则为codePath,多选为codePath数组
|
|
||||||
selectTags: [] as any,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const { tags } = toRefs(state);
|
const { tags } = toRefs(state);
|
||||||
|
|
||||||
const defaultExpandedKeys = computed(() => {
|
const defaultExpandedKeys = computed(() => {
|
||||||
if (Array.isArray(state.selectTags)) {
|
if (Array.isArray(modelValue.value)) {
|
||||||
// 如果 state.selectTags 是数组,直接返回
|
// 如果 modelValue 是数组,直接返回
|
||||||
return state.selectTags;
|
return modelValue.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果 state.selectTags 不是数组,转换为包含 state.selectTags 的数组
|
// 如果 modelValue 不是数组,转换为包含 state.selectTags 的数组
|
||||||
return [state.selectTags];
|
return [modelValue.value];
|
||||||
});
|
});
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
state.selectTags = props.selectTags;
|
|
||||||
state.tags = await tagApi.getTagTrees.request({ type: props.tagType });
|
state.tags = await tagApi.getTagTrees.request({ type: props.tagType });
|
||||||
});
|
});
|
||||||
|
|
||||||
const changeTag = () => {
|
|
||||||
emit('changeTag', state.selectTags);
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss"></style>
|
<style lang="scss"></style>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
:title="title"
|
:title="title"
|
||||||
v-model="dialogVisible"
|
v-model="dialogVisible"
|
||||||
@open="open"
|
@open="open"
|
||||||
:before-close="cancel"
|
:before-close="onCancel"
|
||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
:destroy-on-close="true"
|
:destroy-on-close="true"
|
||||||
width="38%"
|
width="38%"
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
:loading="state.loadingDbNames"
|
:loading="state.loadingDbNames"
|
||||||
>
|
>
|
||||||
<template #header>
|
<template #header>
|
||||||
<el-checkbox v-model="checkAllDbNames" :indeterminate="indeterminateDbNames" @change="handleCheckAll">
|
<el-checkbox v-model="checkAllDbNames" :indeterminate="indeterminateDbNames" @change="onCheckAll">
|
||||||
{{ $t('db.allSelect') }}
|
{{ $t('db.allSelect') }}
|
||||||
</el-checkbox>
|
</el-checkbox>
|
||||||
</template>
|
</template>
|
||||||
@@ -65,8 +65,8 @@
|
|||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<el-button @click="cancel()">{{ $t('common.cancel') }}</el-button>
|
<el-button @click="onCancel()">{{ $t('common.cancel') }}</el-button>
|
||||||
<el-button type="primary" @click="btnOk">{{ $t('common.confirm') }}</el-button>
|
<el-button type="primary" @click="onConfirm">{{ $t('common.confirm') }}</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
@@ -198,7 +198,7 @@ const open = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const btnOk = async () => {
|
const onConfirm = async () => {
|
||||||
await useI18nFormValidate(dbForm);
|
await useI18nFormValidate(dbForm);
|
||||||
emit('confirm', state.form);
|
emit('confirm', state.form);
|
||||||
};
|
};
|
||||||
@@ -209,7 +209,7 @@ const resetInputDb = () => {
|
|||||||
state.instances = [];
|
state.instances = [];
|
||||||
};
|
};
|
||||||
|
|
||||||
const cancel = () => {
|
const onCancel = () => {
|
||||||
dialogVisible.value = false;
|
dialogVisible.value = false;
|
||||||
emit('cancel');
|
emit('cancel');
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@@ -243,7 +243,7 @@ watch(allDatabases, (val: string[]) => {
|
|||||||
state.dbNamesFiltered = val.map((dbName: string) => dbName);
|
state.dbNamesFiltered = val.map((dbName: string) => dbName);
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleCheckAll = (val: CheckboxValueType) => {
|
const onCheckAll = (val: CheckboxValueType) => {
|
||||||
const otherSelected = state.dbNamesSelected.filter((dbName: string) => {
|
const otherSelected = state.dbNamesSelected.filter((dbName: string) => {
|
||||||
return !state.dbNamesFiltered.includes(dbName);
|
return !state.dbNamesFiltered.includes(dbName);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,17 +8,8 @@
|
|||||||
<el-form :model="form" ref="dbFormRef" :rules="rules" label-width="auto">
|
<el-form :model="form" ref="dbFormRef" :rules="rules" label-width="auto">
|
||||||
<el-divider content-position="left">{{ $t('common.basic') }}</el-divider>
|
<el-divider content-position="left">{{ $t('common.basic') }}</el-divider>
|
||||||
|
|
||||||
<el-form-item ref="tagSelectRef" prop="tagCodePaths" :label="$t('tag.relateTag')">
|
<el-form-item prop="tagCodePaths" :label="$t('tag.relateTag')">
|
||||||
<tag-tree-select
|
<tag-tree-select multiple v-model="form.tagCodePaths" />
|
||||||
multiple
|
|
||||||
@change-tag="
|
|
||||||
(paths: any) => {
|
|
||||||
form.tagCodePaths = paths;
|
|
||||||
tagSelectRef.validate();
|
|
||||||
}
|
|
||||||
"
|
|
||||||
:select-tags="form.tagCodePaths"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item prop="name" :label="$t('common.name')" required>
|
<el-form-item prop="name" :label="$t('common.name')" required>
|
||||||
@@ -114,7 +105,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, reactive, ref, toRefs, watchEffect } from 'vue';
|
import { computed, reactive, toRefs, useTemplateRef, watchEffect } from 'vue';
|
||||||
import { dbApi } from './api';
|
import { dbApi } from './api';
|
||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
||||||
import SshTunnelSelect from '../component/SshTunnelSelect.vue';
|
import SshTunnelSelect from '../component/SshTunnelSelect.vue';
|
||||||
@@ -153,8 +144,7 @@ const rules = {
|
|||||||
host: [Rules.requiredInput('Host:Port')],
|
host: [Rules.requiredInput('Host:Port')],
|
||||||
};
|
};
|
||||||
|
|
||||||
const dbFormRef: any = ref(null);
|
const dbFormRef: any = useTemplateRef('dbFormRef');
|
||||||
const tagSelectRef: any = ref(null);
|
|
||||||
|
|
||||||
const DefaultForm = {
|
const DefaultForm = {
|
||||||
id: null,
|
id: null,
|
||||||
|
|||||||
@@ -1,24 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<el-drawer :title="title" v-model="dialogVisible" :before-close="cancel" :destroy-on-close="true" :close-on-click-modal="false" size="40%">
|
<el-drawer :title="title" v-model="dialogVisible" :before-close="onCancel" :destroy-on-close="true" :close-on-click-modal="false" size="40%">
|
||||||
<template #header>
|
<template #header>
|
||||||
<DrawerHeader :header="title" :back="cancel" />
|
<DrawerHeader :header="title" :back="onCancel" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<el-form :model="form" ref="dbForm" :rules="rules" label-width="auto">
|
<el-form :model="form" ref="dbFormRef" :rules="rules" label-width="auto">
|
||||||
<el-divider content-position="left">{{ t('common.basic') }}</el-divider>
|
<el-divider content-position="left">{{ t('common.basic') }}</el-divider>
|
||||||
|
|
||||||
<el-form-item ref="tagSelectRef" prop="tagCodePaths" :label="t('tag.relateTag')">
|
<el-form-item prop="tagCodePaths" :label="t('tag.relateTag')">
|
||||||
<tag-tree-select
|
<tag-tree-select multiple v-model="form.tagCodePaths" />
|
||||||
multiple
|
|
||||||
@change-tag="
|
|
||||||
(paths: any) => {
|
|
||||||
form.tagCodePaths = paths;
|
|
||||||
tagSelectRef.validate();
|
|
||||||
}
|
|
||||||
"
|
|
||||||
:select-tags="form.tagCodePaths"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item prop="name" :label="t('common.name')" required>
|
<el-form-item prop="name" :label="t('common.name')" required>
|
||||||
@@ -50,7 +41,7 @@
|
|||||||
:resource-code="form.code"
|
:resource-code="form.code"
|
||||||
:resource-type="TagResourceTypeEnum.EsInstance.value"
|
:resource-type="TagResourceTypeEnum.EsInstance.value"
|
||||||
:test-conn-btn-loading="testConnBtnLoading"
|
:test-conn-btn-loading="testConnBtnLoading"
|
||||||
@test-conn="testConn"
|
@test-conn="onTestConn"
|
||||||
:disable-ciphertext-type="[AuthCertCiphertextTypeEnum.PrivateKey.value]"
|
:disable-ciphertext-type="[AuthCertCiphertextTypeEnum.PrivateKey.value]"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -63,16 +54,16 @@
|
|||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<el-button @click="testConn(null)" type="success" v-if="form.authCerts?.length <= 0">{{ t('ac.testConn') }}</el-button>
|
<el-button @click="onTestConn(null)" type="success" v-if="form.authCerts?.length <= 0">{{ t('ac.testConn') }}</el-button>
|
||||||
<el-button @click="cancel()">{{ t('common.cancel') }}</el-button>
|
<el-button @click="onCancel()">{{ t('common.cancel') }}</el-button>
|
||||||
<el-button type="primary" :loading="saveBtnLoading" @click="btnOk">{{ t('common.confirm') }}</el-button>
|
<el-button type="primary" :loading="saveBtnLoading" @click="onConfirm">{{ t('common.confirm') }}</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-drawer>
|
</el-drawer>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive, ref, toRefs, watchEffect } from 'vue';
|
import { reactive, toRefs, useTemplateRef, watchEffect } from 'vue';
|
||||||
import { esApi } from './api';
|
import { esApi } from './api';
|
||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
||||||
import SshTunnelSelect from '../component/SshTunnelSelect.vue';
|
import SshTunnelSelect from '../component/SshTunnelSelect.vue';
|
||||||
@@ -88,9 +79,6 @@ import { Rules } from '@/common/rule';
|
|||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
visible: {
|
|
||||||
type: Boolean,
|
|
||||||
},
|
|
||||||
data: {
|
data: {
|
||||||
type: [Boolean, Object],
|
type: [Boolean, Object],
|
||||||
},
|
},
|
||||||
@@ -99,6 +87,8 @@ const props = defineProps({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const dialogVisible = defineModel<boolean>('visible', { default: false });
|
||||||
|
|
||||||
//定义事件
|
//定义事件
|
||||||
const emit = defineEmits(['update:visible', 'cancel', 'val-change']);
|
const emit = defineEmits(['update:visible', 'cancel', 'val-change']);
|
||||||
|
|
||||||
@@ -109,8 +99,7 @@ const rules = {
|
|||||||
host: [Rules.requiredInput('Host:Port')],
|
host: [Rules.requiredInput('Host:Port')],
|
||||||
};
|
};
|
||||||
|
|
||||||
const dbForm: any = ref(null);
|
const dbFormRef: any = useTemplateRef('dbFormRef');
|
||||||
const tagSelectRef: any = ref(null);
|
|
||||||
|
|
||||||
const DefaultForm = {
|
const DefaultForm = {
|
||||||
id: null,
|
id: null,
|
||||||
@@ -126,19 +115,17 @@ const DefaultForm = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
dialogVisible: false,
|
|
||||||
form: DefaultForm,
|
form: DefaultForm,
|
||||||
submitForm: {} as any,
|
submitForm: {} as any,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { dialogVisible, form, submitForm } = toRefs(state);
|
const { form, submitForm } = toRefs(state);
|
||||||
|
|
||||||
const { isFetching: saveBtnLoading, execute: saveInstanceExec, data: saveInstanceRes } = esApi.saveInstance.useApi(submitForm);
|
const { isFetching: saveBtnLoading, execute: saveInstanceExec, data: saveInstanceRes } = esApi.saveInstance.useApi(submitForm);
|
||||||
const { isFetching: testConnBtnLoading, execute: testConnExec, data: testConnRes } = esApi.testConn.useApi<any>(submitForm);
|
const { isFetching: testConnBtnLoading, execute: testConnExec, data: testConnRes } = esApi.testConn.useApi<any>(submitForm);
|
||||||
|
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
state.dialogVisible = props.visible;
|
if (!dialogVisible.value) {
|
||||||
if (!state.dialogVisible) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const dbInst: any = props.data;
|
const dbInst: any = props.data;
|
||||||
@@ -161,8 +148,8 @@ const getReqForm = async () => {
|
|||||||
return reqForm;
|
return reqForm;
|
||||||
};
|
};
|
||||||
|
|
||||||
const testConn = async (authCert: any) => {
|
const onTestConn = async (authCert: any) => {
|
||||||
await useI18nFormValidate(dbForm);
|
await useI18nFormValidate(dbFormRef);
|
||||||
state.submitForm = await getReqForm();
|
state.submitForm = await getReqForm();
|
||||||
if (authCert) {
|
if (authCert) {
|
||||||
state.submitForm.authCerts = [authCert];
|
state.submitForm.authCerts = [authCert];
|
||||||
@@ -172,23 +159,23 @@ const testConn = async (authCert: any) => {
|
|||||||
ElMessage.success(t('es.connSuccess'));
|
ElMessage.success(t('es.connSuccess'));
|
||||||
};
|
};
|
||||||
|
|
||||||
const btnOk = async () => {
|
const onConfirm = async () => {
|
||||||
if (!state.form.version) {
|
if (!state.form.version) {
|
||||||
ElMessage.warning(t('es.shouldTestConn'));
|
ElMessage.warning(t('es.shouldTestConn'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await useI18nFormValidate(dbForm);
|
await useI18nFormValidate(dbFormRef);
|
||||||
state.submitForm = await getReqForm();
|
state.submitForm = await getReqForm();
|
||||||
await saveInstanceExec();
|
await saveInstanceExec();
|
||||||
useI18nSaveSuccessMsg();
|
useI18nSaveSuccessMsg();
|
||||||
state.form.id = saveInstanceRes as any;
|
state.form.id = saveInstanceRes as any;
|
||||||
emit('val-change', state.form);
|
emit('val-change', state.form);
|
||||||
cancel();
|
onCancel();
|
||||||
};
|
};
|
||||||
|
|
||||||
const cancel = () => {
|
const onCancel = () => {
|
||||||
emit('update:visible', false);
|
dialogVisible.value = false;
|
||||||
emit('cancel');
|
emit('cancel');
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,23 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<el-drawer :title="title" v-model="dialogVisible" :before-close="cancel" :destroy-on-close="true" :close-on-click-modal="false" size="40%">
|
<el-drawer :title="title" v-model="dialogVisible" :before-close="onCancel" :destroy-on-close="true" :close-on-click-modal="false" size="40%">
|
||||||
<template #header>
|
<template #header>
|
||||||
<DrawerHeader :header="title" :back="cancel" />
|
<DrawerHeader :header="title" :back="onCancel" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<el-form :model="form" ref="machineForm" :rules="rules" label-width="auto">
|
<el-form :model="form" ref="machineFormRef" :rules="rules" label-width="auto">
|
||||||
<el-divider content-position="left">{{ $t('common.basic') }}</el-divider>
|
<el-divider content-position="left">{{ $t('common.basic') }}</el-divider>
|
||||||
<el-form-item ref="tagSelectRef" prop="tagCodePaths" :label="$t('tag.relateTag')">
|
<el-form-item prop="tagCodePaths" :label="$t('tag.relateTag')">
|
||||||
<tag-tree-select
|
<tag-tree-select multiple v-model="form.tagCodePaths" />
|
||||||
multiple
|
|
||||||
@change-tag="
|
|
||||||
(paths) => {
|
|
||||||
form.tagCodePaths = paths;
|
|
||||||
tagSelectRef.validate();
|
|
||||||
}
|
|
||||||
"
|
|
||||||
:select-tags="form.tagCodePaths"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item prop="name" :label="$t('common.name')" required>
|
<el-form-item prop="name" :label="$t('common.name')" required>
|
||||||
<el-input v-model.trim="form.name" auto-complete="off"></el-input>
|
<el-input v-model.trim="form.name" auto-complete="off"></el-input>
|
||||||
@@ -48,7 +39,7 @@
|
|||||||
:resource-code="form.code"
|
:resource-code="form.code"
|
||||||
:resource-type="TagResourceTypeEnum.Machine.value"
|
:resource-type="TagResourceTypeEnum.Machine.value"
|
||||||
:test-conn-btn-loading="testConnBtnLoading"
|
:test-conn-btn-loading="testConnBtnLoading"
|
||||||
@test-conn="testConn"
|
@test-conn="onTestConn"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -71,8 +62,8 @@
|
|||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div>
|
<div>
|
||||||
<el-button @click="cancel()">{{ $t('common.cancel') }}</el-button>
|
<el-button @click="onCancel()">{{ $t('common.cancel') }}</el-button>
|
||||||
<el-button type="primary" :loading="saveBtnLoading" @click="btnOk">{{ $t('common.confirm') }}</el-button>
|
<el-button type="primary" :loading="saveBtnLoading" @click="onConfirm">{{ $t('common.confirm') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-drawer>
|
</el-drawer>
|
||||||
@@ -80,7 +71,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive, ref, toRefs, watchEffect } from 'vue';
|
import { reactive, toRefs, useTemplateRef, watchEffect } from 'vue';
|
||||||
import { machineApi } from './api';
|
import { machineApi } from './api';
|
||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
||||||
import TagTreeSelect from '../component/TagTreeSelect.vue';
|
import TagTreeSelect from '../component/TagTreeSelect.vue';
|
||||||
@@ -119,8 +110,7 @@ const rules = {
|
|||||||
ip: [Rules.requiredInput('machine.ipAndPort')],
|
ip: [Rules.requiredInput('machine.ipAndPort')],
|
||||||
};
|
};
|
||||||
|
|
||||||
const machineForm: any = ref(null);
|
const machineFormRef: any = useTemplateRef('machineFormRef');
|
||||||
const tagSelectRef: any = ref(null);
|
|
||||||
|
|
||||||
const defaultForm = {
|
const defaultForm = {
|
||||||
id: null,
|
id: null,
|
||||||
@@ -166,8 +156,8 @@ watchEffect(() => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const testConn = async (authCert: any) => {
|
const onTestConn = async (authCert: any) => {
|
||||||
await useI18nFormValidate(machineForm);
|
await useI18nFormValidate(machineFormRef);
|
||||||
|
|
||||||
state.submitForm = getReqForm();
|
state.submitForm = getReqForm();
|
||||||
state.submitForm.authCerts = [authCert];
|
state.submitForm.authCerts = [authCert];
|
||||||
@@ -175,8 +165,8 @@ const testConn = async (authCert: any) => {
|
|||||||
ElMessage.success(t('machine.connSuccess'));
|
ElMessage.success(t('machine.connSuccess'));
|
||||||
};
|
};
|
||||||
|
|
||||||
const btnOk = async () => {
|
const onConfirm = async () => {
|
||||||
await useI18nFormValidate(machineForm);
|
await useI18nFormValidate(machineFormRef);
|
||||||
|
|
||||||
if (state.form.authCerts.length == 0) {
|
if (state.form.authCerts.length == 0) {
|
||||||
ElMessage.error(t('machine.noAcErrMsg'));
|
ElMessage.error(t('machine.noAcErrMsg'));
|
||||||
@@ -187,7 +177,7 @@ const btnOk = async () => {
|
|||||||
await saveMachineExec();
|
await saveMachineExec();
|
||||||
useI18nSaveSuccessMsg();
|
useI18nSaveSuccessMsg();
|
||||||
emit('val-change', submitForm);
|
emit('val-change', submitForm);
|
||||||
cancel();
|
onCancel();
|
||||||
};
|
};
|
||||||
|
|
||||||
const getReqForm = () => {
|
const getReqForm = () => {
|
||||||
@@ -208,7 +198,7 @@ const handleChangeProtocol = (val: any) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const cancel = () => {
|
const onCancel = () => {
|
||||||
dialogVisible.value = false;
|
dialogVisible.value = false;
|
||||||
emit('cancel');
|
emit('cancel');
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -20,11 +20,12 @@
|
|||||||
<el-table-column :label="$t('common.operation')" min-width="120px">
|
<el-table-column :label="$t('common.operation')" min-width="120px">
|
||||||
<template #header>
|
<template #header>
|
||||||
<el-text tag="b">{{ $t('common.operation') }}</el-text>
|
<el-text tag="b">{{ $t('common.operation') }}</el-text>
|
||||||
<el-button v-auth="'cmdconf:save'" class="ml-1" type="primary" circle size="small" icon="Plus" @click="openFormDialog(false)"> </el-button>
|
<el-button v-auth="'cmdconf:save'" class="ml-1" type="primary" circle size="small" icon="Plus" @click="onOpenFormDialog(false)">
|
||||||
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button v-auth="'cmdconf:save'" @click="openFormDialog(scope.row)" type="primary" link>{{ $t('common.edit') }}</el-button>
|
<el-button v-auth="'cmdconf:save'" @click="onOpenFormDialog(scope.row)" type="primary" link>{{ $t('common.edit') }}</el-button>
|
||||||
<el-button v-auth="'cmdconf:del'" @click="deleteCmdConf(scope.row)" type="danger" link>{{ $t('common.delete') }}</el-button>
|
<el-button v-auth="'cmdconf:del'" @click="onDeleteCmdConf(scope.row)" type="danger" link>{{ $t('common.delete') }}</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@@ -38,7 +39,7 @@
|
|||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
>
|
>
|
||||||
<template #header>
|
<template #header>
|
||||||
<DrawerHeader :header="$t('machine.cmdConfig')" :back="cancelEdit" />
|
<DrawerHeader :header="$t('machine.cmdConfig')" :back="onCancelEdit" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<el-form ref="formRef" :model="state.form" :rules="rules" label-width="auto">
|
<el-form ref="formRef" :model="state.form" :rules="rules" label-width="auto">
|
||||||
@@ -46,7 +47,7 @@
|
|||||||
<el-input v-model="form.name"></el-input>
|
<el-input v-model="form.name"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item prop="cmds" :label="$t('machine.filterCmds')" required>
|
<el-form-item prop="cmds" :label="$t('machine.filterCmds')">
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-tag
|
<el-tag
|
||||||
class="ml-0.5 mt-0.5"
|
class="ml-0.5 mt-0.5"
|
||||||
@@ -54,7 +55,7 @@
|
|||||||
:key="tag"
|
:key="tag"
|
||||||
closable
|
closable
|
||||||
:disable-transitions="false"
|
:disable-transitions="false"
|
||||||
@close="handleCmdClose(tag)"
|
@close="onCmdClose(tag)"
|
||||||
type="danger"
|
type="danger"
|
||||||
>
|
>
|
||||||
{{ tag }}
|
{{ tag }}
|
||||||
@@ -65,11 +66,11 @@
|
|||||||
v-model="state.cmdInputValue"
|
v-model="state.cmdInputValue"
|
||||||
class="mt-0.5"
|
class="mt-0.5"
|
||||||
size="small"
|
size="small"
|
||||||
@keyup.enter="handleCmdInputConfirm"
|
@keyup.enter="onCmdInputConfirm"
|
||||||
@blur="handleCmdInputConfirm"
|
@blur="onCmdInputConfirm"
|
||||||
:placeholder="$t('machine.cmdPlaceholder')"
|
:placeholder="$t('machine.cmdPlaceholder')"
|
||||||
/>
|
/>
|
||||||
<el-button v-else class="ml-0.5 mt-0.5" size="small" @click="showCmdInput"> + {{ $t('machine.newCmd') }} </el-button>
|
<el-button v-else class="ml-0.5 mt-0.5" size="small" @click="onShowCmdInput"> + {{ $t('machine.newCmd') }} </el-button>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
@@ -87,8 +88,8 @@
|
|||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<el-button :loading="submiting" @click="cancelEdit">{{ $t('common.cancel') }}</el-button>
|
<el-button :loading="submiting" @click="onCancelEdit">{{ $t('common.cancel') }}</el-button>
|
||||||
<el-button v-auth="'cmdconf:save'" type="primary" :loading="submiting" @click="submitForm">{{ $t('common.confirm') }}</el-button>
|
<el-button v-auth="'cmdconf:save'" type="primary" :loading="submiting" @click="onSubmitForm">{{ $t('common.confirm') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-drawer>
|
</el-drawer>
|
||||||
@@ -143,18 +144,18 @@ const getCmdConfs = async () => {
|
|||||||
state.cmdConfs = await cmdConfApi.list.request();
|
state.cmdConfs = await cmdConfApi.list.request();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCmdClose = (tag: string) => {
|
const onCmdClose = (tag: string) => {
|
||||||
state.form.cmds.splice(state.form.cmds.indexOf(tag), 1);
|
state.form.cmds.splice(state.form.cmds.indexOf(tag), 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
const showCmdInput = () => {
|
const onShowCmdInput = () => {
|
||||||
state.inputCmdVisible = true;
|
state.inputCmdVisible = true;
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
cmdInputRef.value!.input!.focus();
|
cmdInputRef.value!.input!.focus();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCmdInputConfirm = () => {
|
const onCmdInputConfirm = () => {
|
||||||
if (state.cmdInputValue) {
|
if (state.cmdInputValue) {
|
||||||
state.form.cmds.push(state.cmdInputValue);
|
state.form.cmds.push(state.cmdInputValue);
|
||||||
}
|
}
|
||||||
@@ -162,24 +163,25 @@ const handleCmdInputConfirm = () => {
|
|||||||
state.cmdInputValue = '';
|
state.cmdInputValue = '';
|
||||||
};
|
};
|
||||||
|
|
||||||
const openFormDialog = (data: any) => {
|
const onOpenFormDialog = (data: any) => {
|
||||||
if (!data) {
|
if (!data) {
|
||||||
state.form = { ...DefaultForm };
|
state.form = { ...DefaultForm };
|
||||||
} else {
|
} else {
|
||||||
state.form = deepClone(data);
|
state.form = deepClone(data);
|
||||||
state.form.codePaths = data.tags?.map((tag: any) => tag.codePath);
|
state.form.codePaths = data.tags?.map((tag: any) => tag.codePath);
|
||||||
|
state.form.cmds = data.cmds || [];
|
||||||
}
|
}
|
||||||
state.dialogVisible = true;
|
state.dialogVisible = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const deleteCmdConf = async (data: any) => {
|
const onDeleteCmdConf = async (data: any) => {
|
||||||
await useI18nDeleteConfirm(data.name);
|
await useI18nDeleteConfirm(data.name);
|
||||||
await cmdConfApi.delete.request({ id: data.id });
|
await cmdConfApi.delete.request({ id: data.id });
|
||||||
useI18nDeleteSuccessMsg();
|
useI18nDeleteSuccessMsg();
|
||||||
getCmdConfs();
|
getCmdConfs();
|
||||||
};
|
};
|
||||||
|
|
||||||
const cancelEdit = () => {
|
const onCancelEdit = () => {
|
||||||
state.dialogVisible = false;
|
state.dialogVisible = false;
|
||||||
// 取消表单的校验
|
// 取消表单的校验
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@@ -188,14 +190,14 @@ const cancelEdit = () => {
|
|||||||
}, 200);
|
}, 200);
|
||||||
};
|
};
|
||||||
|
|
||||||
const submitForm = async () => {
|
const onSubmitForm = async () => {
|
||||||
try {
|
try {
|
||||||
await useI18nFormValidate(formRef);
|
await useI18nFormValidate(formRef);
|
||||||
state.submiting = true;
|
state.submiting = true;
|
||||||
await cmdConfApi.save.request(state.form);
|
await cmdConfApi.save.request(state.form);
|
||||||
useI18nSaveSuccessMsg();
|
useI18nSaveSuccessMsg();
|
||||||
|
|
||||||
cancelEdit();
|
onCancelEdit();
|
||||||
getCmdConfs();
|
getCmdConfs();
|
||||||
} finally {
|
} finally {
|
||||||
state.submiting = false;
|
state.submiting = false;
|
||||||
|
|||||||
@@ -1,20 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<el-dialog :title="title" v-model="dialogVisible" :before-close="cancel" :close-on-click-modal="false" width="38%" :destroy-on-close="true">
|
<el-dialog :title="title" v-model="dialogVisible" :before-close="onCancel" :close-on-click-modal="false" width="38%" :destroy-on-close="true">
|
||||||
<el-form :model="form" ref="mongoForm" :rules="rules" label-width="auto">
|
<el-form :model="form" ref="mongoFormRef" :rules="rules" label-width="auto">
|
||||||
<el-tabs v-model="tabActiveName">
|
<el-tabs v-model="tabActiveName">
|
||||||
<el-tab-pane :label="$t('common.basic')" name="basic">
|
<el-tab-pane :label="$t('common.basic')" name="basic">
|
||||||
<el-form-item ref="tagSelectRef" prop="tagCodePaths" :label="$t('tag.relateTag')" required>
|
<el-form-item prop="tagCodePaths" :label="$t('tag.relateTag')" required>
|
||||||
<tag-tree-select
|
<tag-tree-select multiple v-model="form.tagCodePaths" />
|
||||||
@change-tag="
|
|
||||||
(tagCodePaths) => {
|
|
||||||
form.tagCodePaths = tagCodePaths;
|
|
||||||
tagSelectRef.validate();
|
|
||||||
}
|
|
||||||
"
|
|
||||||
multiple
|
|
||||||
:select-tags="form.tagCodePaths"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item prop="name" :label="$t('common.name')" required>
|
<el-form-item prop="name" :label="$t('common.name')" required>
|
||||||
@@ -41,9 +32,9 @@
|
|||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<el-button @click="testConn" :loading="testConnBtnLoading" type="success">{{ $t('ac.testConn') }}</el-button>
|
<el-button @click="onTestConn" :loading="testConnBtnLoading" type="success">{{ $t('ac.testConn') }}</el-button>
|
||||||
<el-button @click="cancel()">{{ $t('common.cancel') }}</el-button>
|
<el-button @click="onCancel()">{{ $t('common.cancel') }}</el-button>
|
||||||
<el-button type="primary" :loading="saveBtnLoading" @click="btnOk">{{ $t('common.confirm') }}</el-button>
|
<el-button type="primary" :loading="saveBtnLoading" @click="onConfirm">{{ $t('common.confirm') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
@@ -51,7 +42,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { toRefs, reactive, ref, watchEffect } from 'vue';
|
import { toRefs, reactive, watchEffect, useTemplateRef } from 'vue';
|
||||||
import { mongoApi } from './api';
|
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';
|
||||||
@@ -63,9 +54,6 @@ import { Rules } from '@/common/rule';
|
|||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
visible: {
|
|
||||||
type: Boolean,
|
|
||||||
},
|
|
||||||
mongo: {
|
mongo: {
|
||||||
type: [Boolean, Object],
|
type: [Boolean, Object],
|
||||||
},
|
},
|
||||||
@@ -74,8 +62,10 @@ const props = defineProps({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const dialogVisible = defineModel<boolean>('visible', { default: false });
|
||||||
|
|
||||||
//定义事件
|
//定义事件
|
||||||
const emit = defineEmits(['update:visible', 'cancel', 'val-change']);
|
const emit = defineEmits(['cancel', 'val-change']);
|
||||||
|
|
||||||
const rules = {
|
const rules = {
|
||||||
tagCodePaths: [Rules.requiredSelect('tag.relateTag')],
|
tagCodePaths: [Rules.requiredSelect('tag.relateTag')],
|
||||||
@@ -83,11 +73,9 @@ const rules = {
|
|||||||
uri: [Rules.requiredInput('mongo.connUrl')],
|
uri: [Rules.requiredInput('mongo.connUrl')],
|
||||||
};
|
};
|
||||||
|
|
||||||
const mongoForm: any = ref(null);
|
const mongoFormRef: any = useTemplateRef('mongoFormRef');
|
||||||
const tagSelectRef: any = ref(null);
|
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
dialogVisible: false,
|
|
||||||
tabActiveName: 'basic',
|
tabActiveName: 'basic',
|
||||||
form: {
|
form: {
|
||||||
id: null,
|
id: null,
|
||||||
@@ -100,14 +88,13 @@ const state = reactive({
|
|||||||
submitForm: {},
|
submitForm: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
const { dialogVisible, tabActiveName, form, submitForm } = toRefs(state);
|
const { tabActiveName, form, submitForm } = toRefs(state);
|
||||||
|
|
||||||
const { isFetching: testConnBtnLoading, execute: testConnExec } = mongoApi.testConn.useApi(submitForm);
|
const { isFetching: testConnBtnLoading, execute: testConnExec } = mongoApi.testConn.useApi(submitForm);
|
||||||
const { isFetching: saveBtnLoading, execute: saveMongoExec } = mongoApi.saveMongo.useApi(submitForm);
|
const { isFetching: saveBtnLoading, execute: saveMongoExec } = mongoApi.saveMongo.useApi(submitForm);
|
||||||
|
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
state.dialogVisible = props.visible;
|
if (!dialogVisible.value) {
|
||||||
if (!state.dialogVisible) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
state.tabActiveName = 'basic';
|
state.tabActiveName = 'basic';
|
||||||
@@ -116,7 +103,7 @@ watchEffect(() => {
|
|||||||
state.form = { ...mongo };
|
state.form = { ...mongo };
|
||||||
state.form.tagCodePaths = mongo.tags.map((t: any) => t.codePath);
|
state.form.tagCodePaths = mongo.tags.map((t: any) => t.codePath);
|
||||||
} else {
|
} else {
|
||||||
state.form = { db: 0 } as any;
|
state.form = { db: 0, tagCodePaths: [] } as any;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -128,24 +115,24 @@ const getReqForm = () => {
|
|||||||
return reqForm;
|
return reqForm;
|
||||||
};
|
};
|
||||||
|
|
||||||
const testConn = async () => {
|
const onTestConn = async () => {
|
||||||
await useI18nFormValidate(mongoForm);
|
await useI18nFormValidate(mongoFormRef);
|
||||||
state.submitForm = getReqForm();
|
state.submitForm = getReqForm();
|
||||||
await testConnExec();
|
await testConnExec();
|
||||||
ElMessage.success(t('ac.connSuccess'));
|
ElMessage.success(t('ac.connSuccess'));
|
||||||
};
|
};
|
||||||
|
|
||||||
const btnOk = async () => {
|
const onConfirm = async () => {
|
||||||
await useI18nFormValidate(mongoForm);
|
await useI18nFormValidate(mongoFormRef);
|
||||||
state.submitForm = getReqForm();
|
state.submitForm = getReqForm();
|
||||||
await saveMongoExec();
|
await saveMongoExec();
|
||||||
useI18nSaveSuccessMsg();
|
useI18nSaveSuccessMsg();
|
||||||
emit('val-change', state.form);
|
emit('val-change', state.form);
|
||||||
cancel();
|
onCancel();
|
||||||
};
|
};
|
||||||
|
|
||||||
const cancel = () => {
|
const onCancel = () => {
|
||||||
emit('update:visible', false);
|
dialogVisible.value = false;
|
||||||
emit('cancel');
|
emit('cancel');
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
lazy
|
lazy
|
||||||
>
|
>
|
||||||
<template #tableHeader>
|
<template #tableHeader>
|
||||||
<el-button type="primary" icon="plus" @click="editMongo(true)" plain>{{ $t('common.create') }}</el-button>
|
<el-button type="primary" icon="plus" @click="editMongo(false)" plain>{{ $t('common.create') }}</el-button>
|
||||||
<el-button type="danger" icon="delete" :disabled="selectionData.length < 1" @click="deleteMongo" plain>{{ $t('common.delete') }}</el-button>
|
<el-button type="danger" icon="delete" :disabled="selectionData.length < 1" @click="deleteMongo" plain>{{ $t('common.delete') }}</el-button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -1,22 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<el-drawer :title="title" v-model="dialogVisible" :before-close="cancel" :destroy-on-close="true" :close-on-click-modal="false" size="40%">
|
<el-drawer :title="title" v-model="dialogVisible" :before-close="onCancel" :destroy-on-close="true" :close-on-click-modal="false" size="40%">
|
||||||
<template #header>
|
<template #header>
|
||||||
<DrawerHeader :header="title" :back="cancel" />
|
<DrawerHeader :header="title" :back="onCancel" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<el-form :model="form" ref="redisForm" :rules="rules" label-width="auto">
|
<el-form :model="form" ref="redisFormRef" :rules="rules" label-width="auto">
|
||||||
<el-form-item ref="tagSelectRef" prop="tagCodePaths" :label="$t('tag.relateTag')" required>
|
<el-form-item prop="tagCodePaths" :label="$t('tag.relateTag')" required>
|
||||||
<tag-tree-select
|
<tag-tree-select multiple v-model="form.tagCodePaths" />
|
||||||
@change-tag="
|
|
||||||
(tagCodePaths) => {
|
|
||||||
form.tagCodePaths = tagCodePaths;
|
|
||||||
tagSelectRef.validate();
|
|
||||||
}
|
|
||||||
"
|
|
||||||
multiple
|
|
||||||
:select-tags="form.tagCodePaths"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item prop="name" :label="$t('common.name')" required>
|
<el-form-item prop="name" :label="$t('common.name')" required>
|
||||||
<el-input v-model.trim="form.name" auto-complete="off"></el-input>
|
<el-input v-model.trim="form.name" auto-complete="off"></el-input>
|
||||||
@@ -55,9 +46,9 @@
|
|||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<el-button @click="testConn" :loading="testConnBtnLoading" type="success">{{ $t('ac.testConn') }}</el-button>
|
<el-button @click="onTestConn" :loading="testConnBtnLoading" type="success">{{ $t('ac.testConn') }}</el-button>
|
||||||
<el-button @click="cancel()">{{ $t('common.cancel') }}</el-button>
|
<el-button @click="onCancel()">{{ $t('common.cancel') }}</el-button>
|
||||||
<el-button type="primary" :loading="saveBtnLoading" @click="btnOk">{{ $t('common.confirm') }}</el-button>
|
<el-button type="primary" :loading="saveBtnLoading" @click="onConfirm">{{ $t('common.confirm') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-drawer>
|
</el-drawer>
|
||||||
@@ -65,7 +56,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { toRefs, reactive, ref, watch } from 'vue';
|
import { toRefs, reactive, watch, useTemplateRef } from 'vue';
|
||||||
import { redisApi } from './api';
|
import { redisApi } from './api';
|
||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
||||||
import TagTreeSelect from '../component/TagTreeSelect.vue';
|
import TagTreeSelect from '../component/TagTreeSelect.vue';
|
||||||
@@ -78,9 +69,6 @@ import { Rules } from '@/common/rule';
|
|||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
visible: {
|
|
||||||
type: Boolean,
|
|
||||||
},
|
|
||||||
redis: {
|
redis: {
|
||||||
type: [Boolean, Object],
|
type: [Boolean, Object],
|
||||||
},
|
},
|
||||||
@@ -89,7 +77,9 @@ const props = defineProps({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(['update:visible', 'val-change', 'cancel']);
|
const dialogVisible = defineModel<boolean>('visible', { default: false });
|
||||||
|
|
||||||
|
const emit = defineEmits(['val-change', 'cancel']);
|
||||||
|
|
||||||
const rules = {
|
const rules = {
|
||||||
tagCodePaths: [Rules.requiredSelect('tag.relateTag')],
|
tagCodePaths: [Rules.requiredSelect('tag.relateTag')],
|
||||||
@@ -99,12 +89,9 @@ const rules = {
|
|||||||
mode: [Rules.requiredSelect('mode')],
|
mode: [Rules.requiredSelect('mode')],
|
||||||
};
|
};
|
||||||
|
|
||||||
const redisForm: any = ref(null);
|
const redisFormRef: any = useTemplateRef('redisFormRef');
|
||||||
const tagSelectRef: any = ref(null);
|
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
dialogVisible: false,
|
|
||||||
tabActiveName: 'basic',
|
|
||||||
form: {
|
form: {
|
||||||
id: null,
|
id: null,
|
||||||
code: '',
|
code: '',
|
||||||
@@ -124,30 +111,26 @@ const state = reactive({
|
|||||||
pwd: '',
|
pwd: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
const { dialogVisible, tabActiveName, form, submitForm, dbList } = toRefs(state);
|
const { form, submitForm, dbList } = toRefs(state);
|
||||||
|
|
||||||
const { isFetching: testConnBtnLoading, execute: testConnExec } = redisApi.testConn.useApi(submitForm);
|
const { isFetching: testConnBtnLoading, execute: testConnExec } = redisApi.testConn.useApi(submitForm);
|
||||||
const { isFetching: saveBtnLoading, execute: saveRedisExec } = redisApi.saveRedis.useApi(submitForm);
|
const { isFetching: saveBtnLoading, execute: saveRedisExec } = redisApi.saveRedis.useApi(submitForm);
|
||||||
|
|
||||||
watch(
|
watch(dialogVisible, () => {
|
||||||
() => props.visible,
|
if (!dialogVisible.value) {
|
||||||
() => {
|
return;
|
||||||
state.dialogVisible = props.visible;
|
|
||||||
if (!state.dialogVisible) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
state.tabActiveName = 'basic';
|
|
||||||
const redis: any = props.redis;
|
|
||||||
if (redis) {
|
|
||||||
state.form = { ...redis };
|
|
||||||
state.form.tagCodePaths = redis.tags.map((t: any) => t.codePath);
|
|
||||||
convertDb(state.form.db);
|
|
||||||
} else {
|
|
||||||
state.form = { db: '0', tagCodePaths: [] } as any;
|
|
||||||
state.dbList = [0];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
|
||||||
|
const redis: any = props.redis;
|
||||||
|
if (redis) {
|
||||||
|
state.form = { ...redis };
|
||||||
|
state.form.tagCodePaths = redis.tags.map((t: any) => t.codePath);
|
||||||
|
convertDb(state.form.db);
|
||||||
|
} else {
|
||||||
|
state.form = { db: '0', tagCodePaths: [] } as any;
|
||||||
|
state.dbList = [0];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const convertDb = (db: string) => {
|
const convertDb = (db: string) => {
|
||||||
state.dbList = db.split(',').map((x) => Number.parseInt(x));
|
state.dbList = db.split(',').map((x) => Number.parseInt(x));
|
||||||
@@ -172,24 +155,24 @@ const getReqForm = async () => {
|
|||||||
return reqForm;
|
return reqForm;
|
||||||
};
|
};
|
||||||
|
|
||||||
const testConn = async () => {
|
const onTestConn = async () => {
|
||||||
await useI18nFormValidate(redisForm);
|
await useI18nFormValidate(redisFormRef);
|
||||||
state.submitForm = await getReqForm();
|
state.submitForm = await getReqForm();
|
||||||
await testConnExec();
|
await testConnExec();
|
||||||
ElMessage.success(t('ac.connSuccess'));
|
ElMessage.success(t('ac.connSuccess'));
|
||||||
};
|
};
|
||||||
|
|
||||||
const btnOk = async () => {
|
const onConfirm = async () => {
|
||||||
await useI18nFormValidate(redisForm);
|
await useI18nFormValidate(redisFormRef);
|
||||||
state.submitForm = await getReqForm();
|
state.submitForm = await getReqForm();
|
||||||
await saveRedisExec();
|
await saveRedisExec();
|
||||||
useI18nSaveSuccessMsg();
|
useI18nSaveSuccessMsg();
|
||||||
emit('val-change', state.form);
|
emit('val-change', state.form);
|
||||||
cancel();
|
onCancel();
|
||||||
};
|
};
|
||||||
|
|
||||||
const cancel = () => {
|
const onCancel = () => {
|
||||||
emit('update:visible', false);
|
dialogVisible.value = false;
|
||||||
emit('cancel');
|
emit('cancel');
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
:columns="state.columns"
|
:columns="state.columns"
|
||||||
>
|
>
|
||||||
<template #tableHeader>
|
<template #tableHeader>
|
||||||
<el-button v-auth="'authcert:save'" type="primary" icon="plus" @click="edit(false)">{{ $t('common.create') }}</el-button>
|
<el-button v-auth="'authcert:save'" type="primary" icon="plus" @click="onEdit(false)">{{ $t('common.create') }}</el-button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #resourceCode="{ data }">
|
<template #resourceCode="{ data }">
|
||||||
@@ -20,9 +20,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #action="{ data }">
|
<template #action="{ data }">
|
||||||
<el-button v-auth="'authcert:save'" @click="edit(data)" type="primary" link>{{ $t('common.edit') }}</el-button>
|
<el-button v-auth="'authcert:save'" @click="onEdit(data)" type="primary" link>{{ $t('common.edit') }}</el-button>
|
||||||
|
|
||||||
<el-button v-auth="'authcert:del'" @click="deleteAc(data)" type="danger" link>{{ $t('common.delete') }}</el-button>
|
<el-button v-auth="'authcert:del'" @click="onDeleteAc(data)" type="danger" link>{{ $t('common.delete') }}</el-button>
|
||||||
</template>
|
</template>
|
||||||
</page-table>
|
</page-table>
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
:title="editor.title"
|
:title="editor.title"
|
||||||
v-model:visible="editor.visible"
|
v-model:visible="editor.visible"
|
||||||
:auth-cert="editor.authcert"
|
:auth-cert="editor.authcert"
|
||||||
@confirm="confirmSave"
|
@confirm="onConfirmSave"
|
||||||
@cancel="editor.authcert = {}"
|
@cancel="editor.authcert = {}"
|
||||||
:disable-type="state.disableAuthCertType"
|
:disable-type="state.disableAuthCertType"
|
||||||
:disable-ciphertext-type="state.disableAuthCertCiphertextType"
|
:disable-ciphertext-type="state.disableAuthCertCiphertextType"
|
||||||
@@ -102,7 +102,7 @@ const search = async () => {
|
|||||||
pageTableRef.value.search();
|
pageTableRef.value.search();
|
||||||
};
|
};
|
||||||
|
|
||||||
const edit = (data: any) => {
|
const onEdit = (data: any) => {
|
||||||
state.disableAuthCertType = [];
|
state.disableAuthCertType = [];
|
||||||
state.disableAuthCertCiphertextType = [];
|
state.disableAuthCertCiphertextType = [];
|
||||||
if (data) {
|
if (data) {
|
||||||
@@ -128,14 +128,14 @@ const edit = (data: any) => {
|
|||||||
state.editor.visible = true;
|
state.editor.visible = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const confirmSave = async (authCert: any) => {
|
const onConfirmSave = async (authCert: any) => {
|
||||||
await resourceAuthCertApi.save.request(authCert);
|
await resourceAuthCertApi.save.request(authCert);
|
||||||
useI18nSaveSuccessMsg();
|
useI18nSaveSuccessMsg();
|
||||||
state.editor.visible = false;
|
state.editor.visible = false;
|
||||||
search();
|
search();
|
||||||
};
|
};
|
||||||
|
|
||||||
const deleteAc = async (data: any) => {
|
const onDeleteAc = async (data: any) => {
|
||||||
try {
|
try {
|
||||||
await useI18nDeleteConfirm(data.name);
|
await useI18nDeleteConfirm(data.name);
|
||||||
await resourceAuthCertApi.delete.request({ id: data.id });
|
await resourceAuthCertApi.delete.request({ id: data.id });
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
v-auth="'tag:save'"
|
v-auth="'tag:save'"
|
||||||
type="primary"
|
type="primary"
|
||||||
icon="plus"
|
icon="plus"
|
||||||
@click="showSaveTagDialog(null)"
|
@click="onShowSaveTagDialog(null)"
|
||||||
></el-button>
|
></el-button>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@@ -33,15 +33,15 @@
|
|||||||
highlight-current
|
highlight-current
|
||||||
:props="props"
|
:props="props"
|
||||||
:data="data"
|
:data="data"
|
||||||
@node-expand="handleNodeExpand"
|
@node-expand="onNodeExpand"
|
||||||
@node-collapse="handleNodeCollapse"
|
@node-collapse="onNodeCollapse"
|
||||||
@node-contextmenu="nodeContextmenu"
|
@node-contextmenu="onNodeContextmenu"
|
||||||
@node-click="treeNodeClick"
|
@node-click="onTreeNodeClick"
|
||||||
:default-expanded-keys="defaultExpandedKeys"
|
:default-expanded-keys="defaultExpandedKeys"
|
||||||
draggable
|
draggable
|
||||||
:allow-drop="allowDrop"
|
:allow-drop="allowDrop"
|
||||||
:allow-drag="allowDrag"
|
:allow-drag="allowDrag"
|
||||||
@node-drop="handleDrop"
|
@node-drop="onNodeDrop"
|
||||||
:expand-on-click-node="false"
|
:expand-on-click-node="false"
|
||||||
:filter-node-method="filterNode"
|
:filter-node-method="filterNode"
|
||||||
>
|
>
|
||||||
@@ -67,7 +67,7 @@
|
|||||||
|
|
||||||
<Pane min-size="40" size="70">
|
<Pane min-size="40" size="70">
|
||||||
<div class="ml-2 h-full">
|
<div class="ml-2 h-full">
|
||||||
<el-tabs class="h-full" @tab-change="tabChange" v-model="state.activeTabName" v-if="currentTag">
|
<el-tabs class="h-full" @tab-change="onTabChange" v-model="state.activeTabName" v-if="currentTag">
|
||||||
<el-tab-pane :label="$t('common.detail')" :name="TagDetail">
|
<el-tab-pane :label="$t('common.detail')" :name="TagDetail">
|
||||||
<el-descriptions :column="2" border>
|
<el-descriptions :column="2" border>
|
||||||
<el-descriptions-item :label="$t('common.type')">
|
<el-descriptions-item :label="$t('common.type')">
|
||||||
@@ -137,7 +137,7 @@
|
|||||||
</Pane>
|
</Pane>
|
||||||
</Splitpanes>
|
</Splitpanes>
|
||||||
|
|
||||||
<el-dialog width="500px" :title="saveTabDialog.title" :before-close="cancelSaveTag" v-model="saveTabDialog.visible">
|
<el-dialog width="500px" :title="saveTabDialog.title" :before-close="onCancelSaveTag" v-model="saveTabDialog.visible">
|
||||||
<el-form ref="tagForm" :rules="rules" :model="saveTabDialog.form" label-width="auto">
|
<el-form ref="tagForm" :rules="rules" :model="saveTabDialog.form" label-width="auto">
|
||||||
<el-form-item prop="code" :label="$t('tag.code')" required>
|
<el-form-item prop="code" :label="$t('tag.code')" required>
|
||||||
<el-input :disabled="saveTabDialog.form.id ? true : false" v-model="saveTabDialog.form.code" auto-complete="off"></el-input>
|
<el-input :disabled="saveTabDialog.form.id ? true : false" v-model="saveTabDialog.form.code" auto-complete="off"></el-input>
|
||||||
@@ -151,8 +151,8 @@
|
|||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<el-button @click="cancelSaveTag()">{{ $t('common.cancel') }}</el-button>
|
<el-button @click="onCancelSaveTag()">{{ $t('common.cancel') }}</el-button>
|
||||||
<el-button @click="saveTag" type="primary">{{ $t('common.confirm') }}</el-button>
|
<el-button @click="onSaveTag" type="primary">{{ $t('common.confirm') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
@@ -223,7 +223,7 @@ const contextmenuAdd = new ContextmenuItem('addTag', 'tag.createSubTag')
|
|||||||
// 非标签类型不可添加子标签
|
// 非标签类型不可添加子标签
|
||||||
return data.type != TagResourceTypeEnum.Tag.value || (data.children && data.children?.[0].type != TagResourceTypeEnum.Tag.value);
|
return data.type != TagResourceTypeEnum.Tag.value || (data.children && data.children?.[0].type != TagResourceTypeEnum.Tag.value);
|
||||||
})
|
})
|
||||||
.withOnClick((data: any) => showSaveTagDialog(data));
|
.withOnClick((data: any) => onShowSaveTagDialog(data));
|
||||||
|
|
||||||
const contextmenuEdit = new ContextmenuItem('edit', 'common.edit')
|
const contextmenuEdit = new ContextmenuItem('edit', 'common.edit')
|
||||||
.withIcon('edit')
|
.withIcon('edit')
|
||||||
@@ -231,7 +231,7 @@ const contextmenuEdit = new ContextmenuItem('edit', 'common.edit')
|
|||||||
.withHideFunc((data: any) => {
|
.withHideFunc((data: any) => {
|
||||||
return data.type != TagResourceTypeEnum.Tag.value;
|
return data.type != TagResourceTypeEnum.Tag.value;
|
||||||
})
|
})
|
||||||
.withOnClick((data: any) => showEditTagDialog(data));
|
.withOnClick((data: any) => onShowEditTagDialog(data));
|
||||||
|
|
||||||
const contextmenuDel = new ContextmenuItem('delete', 'common.delete')
|
const contextmenuDel = new ContextmenuItem('delete', 'common.delete')
|
||||||
.withIcon('delete')
|
.withIcon('delete')
|
||||||
@@ -240,7 +240,7 @@ const contextmenuDel = new ContextmenuItem('delete', 'common.delete')
|
|||||||
// 存在子标签,则不允许删除
|
// 存在子标签,则不允许删除
|
||||||
return data.children || data.type != TagResourceTypeEnum.Tag.value;
|
return data.children || data.type != TagResourceTypeEnum.Tag.value;
|
||||||
})
|
})
|
||||||
.withOnClick((data: any) => deleteTag(data));
|
.withOnClick((data: any) => onDeleteTag(data));
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
data: [],
|
data: [],
|
||||||
@@ -364,7 +364,7 @@ const allowDrag = (node: any) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDrop = async (draggingNode: any, dropNode: any) => {
|
const onNodeDrop = async (draggingNode: any, dropNode: any) => {
|
||||||
const draggingData = draggingNode.data;
|
const draggingData = draggingNode.data;
|
||||||
const dropData = dropNode.data;
|
const dropData = dropNode.data;
|
||||||
|
|
||||||
@@ -378,7 +378,7 @@ const handleDrop = async (draggingNode: any, dropNode: any) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const tabChange = () => {
|
const onTabChange = () => {
|
||||||
setNowTabData();
|
setNowTabData();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -420,20 +420,21 @@ const getDetail = async (id: number) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 树节点右击事件
|
// 树节点右击事件
|
||||||
const nodeContextmenu = (event: any, data: any) => {
|
const onNodeContextmenu = (event: any, data: any) => {
|
||||||
const { clientX, clientY } = event;
|
const { clientX, clientY } = event;
|
||||||
state.contextmenu.dropdown.x = clientX;
|
state.contextmenu.dropdown.x = clientX;
|
||||||
state.contextmenu.dropdown.y = clientY;
|
state.contextmenu.dropdown.y = clientY;
|
||||||
contextmenuRef.value.openContextmenu(data);
|
contextmenuRef.value.openContextmenu(data);
|
||||||
};
|
};
|
||||||
|
|
||||||
const treeNodeClick = async (data: any) => {
|
const onTreeNodeClick = async (data: any) => {
|
||||||
state.currentTag = await getDetail(data.id);
|
state.currentTag = await getDetail(data.id);
|
||||||
|
state.activeTabName = TagDetail;
|
||||||
// 关闭可能存在的右击菜单
|
// 关闭可能存在的右击菜单
|
||||||
contextmenuRef.value.closeContextmenu();
|
contextmenuRef.value.closeContextmenu();
|
||||||
};
|
};
|
||||||
|
|
||||||
const showSaveTagDialog = (data: any) => {
|
const onShowSaveTagDialog = (data: any) => {
|
||||||
if (data) {
|
if (data) {
|
||||||
state.saveTabDialog.form.pid = data.id;
|
state.saveTabDialog.form.pid = data.id;
|
||||||
state.saveTabDialog.title = t('tag.createSubTagTitle', { codePath: data.codePath });
|
state.saveTabDialog.title = t('tag.createSubTagTitle', { codePath: data.codePath });
|
||||||
@@ -443,7 +444,7 @@ const showSaveTagDialog = (data: any) => {
|
|||||||
state.saveTabDialog.visible = true;
|
state.saveTabDialog.visible = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const showEditTagDialog = (data: any) => {
|
const onShowEditTagDialog = (data: any) => {
|
||||||
state.saveTabDialog.form.id = data.id;
|
state.saveTabDialog.form.id = data.id;
|
||||||
state.saveTabDialog.form.code = data.code;
|
state.saveTabDialog.form.code = data.code;
|
||||||
state.saveTabDialog.form.name = data.name;
|
state.saveTabDialog.form.name = data.name;
|
||||||
@@ -452,23 +453,23 @@ const showEditTagDialog = (data: any) => {
|
|||||||
state.saveTabDialog.visible = true;
|
state.saveTabDialog.visible = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const saveTag = async () => {
|
const onSaveTag = async () => {
|
||||||
await useI18nFormValidate(tagForm);
|
await useI18nFormValidate(tagForm);
|
||||||
const form = state.saveTabDialog.form;
|
const form = state.saveTabDialog.form;
|
||||||
await tagApi.saveTagTree.request(form);
|
await tagApi.saveTagTree.request(form);
|
||||||
useI18nSaveSuccessMsg();
|
useI18nSaveSuccessMsg();
|
||||||
search();
|
search();
|
||||||
cancelSaveTag();
|
onCancelSaveTag();
|
||||||
state.currentTag = null;
|
state.currentTag = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
const cancelSaveTag = () => {
|
const onCancelSaveTag = () => {
|
||||||
state.saveTabDialog.visible = false;
|
state.saveTabDialog.visible = false;
|
||||||
state.saveTabDialog.form = {} as any;
|
state.saveTabDialog.form = {} as any;
|
||||||
tagForm.value.resetFields();
|
tagForm.value.resetFields();
|
||||||
};
|
};
|
||||||
|
|
||||||
const deleteTag = async (data: any) => {
|
const onDeleteTag = async (data: any) => {
|
||||||
await useI18nDeleteConfirm(data.codePath);
|
await useI18nDeleteConfirm(data.codePath);
|
||||||
await tagApi.delTagTree.request({ id: data.id });
|
await tagApi.delTagTree.request({ id: data.id });
|
||||||
useI18nDeleteSuccessMsg();
|
useI18nDeleteSuccessMsg();
|
||||||
@@ -476,7 +477,7 @@ const deleteTag = async (data: any) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 节点被展开时触发的事件
|
// 节点被展开时触发的事件
|
||||||
const handleNodeExpand = (data: any, node: any) => {
|
const onNodeExpand = (data: any, node: any) => {
|
||||||
const id: any = node.data.id;
|
const id: any = node.data.id;
|
||||||
if (!state.defaultExpandedKeys.includes(id)) {
|
if (!state.defaultExpandedKeys.includes(id)) {
|
||||||
state.defaultExpandedKeys.push(id);
|
state.defaultExpandedKeys.push(id);
|
||||||
@@ -484,7 +485,7 @@ const handleNodeExpand = (data: any, node: any) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 关闭节点
|
// 关闭节点
|
||||||
const handleNodeCollapse = (data: any, node: any) => {
|
const onNodeCollapse = (data: any, node: any) => {
|
||||||
removeDeafultExpandId(node.data.id);
|
removeDeafultExpandId(node.data.id);
|
||||||
|
|
||||||
let childNodes = node.childNodes;
|
let childNodes = node.childNodes;
|
||||||
@@ -493,7 +494,7 @@ const handleNodeCollapse = (data: any, node: any) => {
|
|||||||
removeDeafultExpandId(cn.data.id);
|
removeDeafultExpandId(cn.data.id);
|
||||||
}
|
}
|
||||||
// 递归删除展开的子节点节点id
|
// 递归删除展开的子节点节点id
|
||||||
handleNodeCollapse(data, cn);
|
onNodeCollapse(data, cn);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -10,8 +10,8 @@
|
|||||||
:columns="columns"
|
:columns="columns"
|
||||||
>
|
>
|
||||||
<template #tableHeader>
|
<template #tableHeader>
|
||||||
<el-button v-auth="'team:save'" type="primary" icon="plus" @click="showSaveTeamDialog(false)">{{ $t('common.create') }}</el-button>
|
<el-button v-auth="'team:save'" type="primary" icon="plus" @click="onShowSaveTeamDialog(false)">{{ $t('common.create') }}</el-button>
|
||||||
<el-button v-auth="'team:del'" :disabled="selectionData.length < 1" @click="deleteTeam()" type="danger" icon="delete">
|
<el-button v-auth="'team:del'" :disabled="selectionData.length < 1" @click="onDeleteTeam()" type="danger" icon="delete">
|
||||||
{{ $t('common.delete') }}
|
{{ $t('common.delete') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
@@ -23,22 +23,22 @@
|
|||||||
<template #validityDate="{ data }"> {{ formatDate(data.validityStartDate) }} ~ {{ formatDate(data.validityEndDate) }} </template>
|
<template #validityDate="{ data }"> {{ formatDate(data.validityStartDate) }} ~ {{ formatDate(data.validityEndDate) }} </template>
|
||||||
|
|
||||||
<template #action="{ data }">
|
<template #action="{ data }">
|
||||||
<el-button @click.prevent="showMembers(data)" link type="primary">{{ $t('team.member') }}</el-button>
|
<el-button @click.prevent="onShowMembers(data)" link type="primary">{{ $t('team.member') }}</el-button>
|
||||||
|
|
||||||
<el-button v-auth="'team:save'" @click.prevent="showSaveTeamDialog(data)" link type="warning">{{ $t('common.edit') }}</el-button>
|
<el-button v-auth="'team:save'" @click.prevent="onShowSaveTeamDialog(data)" link type="warning">{{ $t('common.edit') }}</el-button>
|
||||||
</template>
|
</template>
|
||||||
</page-table>
|
</page-table>
|
||||||
|
|
||||||
<el-drawer
|
<el-drawer
|
||||||
:title="addTeamDialog.title"
|
:title="addTeamDialog.title"
|
||||||
v-model="addTeamDialog.visible"
|
v-model="addTeamDialog.visible"
|
||||||
:before-close="cancelSaveTeam"
|
:before-close="onCancelSaveTeam"
|
||||||
:destroy-on-close="true"
|
:destroy-on-close="true"
|
||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
size="40%"
|
size="40%"
|
||||||
>
|
>
|
||||||
<template #header>
|
<template #header>
|
||||||
<DrawerHeader :header="addTeamDialog.title" :back="cancelSaveTeam" />
|
<DrawerHeader :header="addTeamDialog.title" :back="onCancelSaveTeam" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<el-form ref="teamForm" :model="addTeamDialog.form" :rules="teamFormRules" label-width="auto">
|
<el-form ref="teamForm" :model="addTeamDialog.form" :rules="teamFormRules" label-width="auto">
|
||||||
@@ -69,8 +69,8 @@
|
|||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<el-button @click="cancelSaveTeam()">{{ $t('common.cancel') }}</el-button>
|
<el-button @click="onCancelSaveTeam()">{{ $t('common.cancel') }}</el-button>
|
||||||
<el-button @click="saveTeam" type="primary">{{ $t('common.confirm') }}</el-button>
|
<el-button @click="onSaveTeam" type="primary">{{ $t('common.confirm') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-drawer>
|
</el-drawer>
|
||||||
@@ -85,22 +85,22 @@
|
|||||||
:columns="showMemDialog.columns"
|
:columns="showMemDialog.columns"
|
||||||
>
|
>
|
||||||
<template #tableHeader>
|
<template #tableHeader>
|
||||||
<el-button v-auth="'team:member:save'" @click="showAddMemberDialog()" type="primary" icon="plus">{{ $t('common.add') }}</el-button>
|
<el-button v-auth="'team:member:save'" @click="onShowAddMemberDialog()" type="primary" icon="plus">{{ $t('common.add') }}</el-button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #action="{ data }">
|
<template #action="{ data }">
|
||||||
<el-button v-auth="'team:member:del'" @click="deleteMember(data)" type="danger" link icon="delete"></el-button>
|
<el-button v-auth="'team:member:del'" @click="onDeleteMember(data)" type="danger" link icon="delete"></el-button>
|
||||||
</template>
|
</template>
|
||||||
</page-table>
|
</page-table>
|
||||||
|
|
||||||
<el-dialog width="400px" :title="$t('team.addMember')" :before-close="cancelAddMember" v-model="showMemDialog.addVisible">
|
<el-dialog width="400px" :title="$t('team.addMember')" :before-close="onCancelAddMember" v-model="showMemDialog.addVisible">
|
||||||
<el-form :model="showMemDialog.memForm" label-width="auto">
|
<el-form :model="showMemDialog.memForm" label-width="auto">
|
||||||
<AccountSelectFormItem v-model="showMemDialog.memForm.accountIds" multiple focus />
|
<AccountSelectFormItem v-model="showMemDialog.memForm.accountIds" multiple focus />
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<el-button @click="cancelAddMember()">{{ $t('common.cancel') }}</el-button>
|
<el-button @click="onCancelAddMember()">{{ $t('common.cancel') }}</el-button>
|
||||||
<el-button @click="addMember" type="primary">{{ $t('common.confirm') }}</el-button>
|
<el-button @click="onAddMember" type="primary">{{ $t('common.confirm') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
@@ -207,7 +207,7 @@ const search = async () => {
|
|||||||
pageTableRef.value.search();
|
pageTableRef.value.search();
|
||||||
};
|
};
|
||||||
|
|
||||||
const showSaveTeamDialog = async (data: any) => {
|
const onShowSaveTeamDialog = async (data: any) => {
|
||||||
if (data) {
|
if (data) {
|
||||||
state.addTeamDialog.title = useI18nEditTitle('team.team');
|
state.addTeamDialog.title = useI18nEditTitle('team.team');
|
||||||
state.addTeamDialog.form.id = data.id;
|
state.addTeamDialog.form.id = data.id;
|
||||||
@@ -225,7 +225,7 @@ const showSaveTeamDialog = async (data: any) => {
|
|||||||
state.addTeamDialog.visible = true;
|
state.addTeamDialog.visible = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const saveTeam = async () => {
|
const onSaveTeam = async () => {
|
||||||
await useI18nFormValidate(teamForm);
|
await useI18nFormValidate(teamForm);
|
||||||
const form = state.addTeamDialog.form;
|
const form = state.addTeamDialog.form;
|
||||||
form.validityStartDate = formatDate(form.validityDate[0]);
|
form.validityStartDate = formatDate(form.validityDate[0]);
|
||||||
@@ -233,10 +233,10 @@ const saveTeam = async () => {
|
|||||||
await tagApi.saveTeam.request(form);
|
await tagApi.saveTeam.request(form);
|
||||||
useI18nSaveSuccessMsg();
|
useI18nSaveSuccessMsg();
|
||||||
search();
|
search();
|
||||||
cancelSaveTeam();
|
onCancelSaveTeam();
|
||||||
};
|
};
|
||||||
|
|
||||||
const cancelSaveTeam = () => {
|
const onCancelSaveTeam = () => {
|
||||||
state.addTeamDialog.visible = false;
|
state.addTeamDialog.visible = false;
|
||||||
teamForm.value.resetFields();
|
teamForm.value.resetFields();
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@@ -244,7 +244,7 @@ const cancelSaveTeam = () => {
|
|||||||
}, 500);
|
}, 500);
|
||||||
};
|
};
|
||||||
|
|
||||||
const deleteTeam = async () => {
|
const onDeleteTeam = async () => {
|
||||||
await useI18nDeleteConfirm(state.selectionData.map((x: any) => x.name).join('、'));
|
await useI18nDeleteConfirm(state.selectionData.map((x: any) => x.name).join('、'));
|
||||||
await tagApi.delTeam.request({ id: state.selectionData.map((x: any) => x.id).join(',') });
|
await tagApi.delTeam.request({ id: state.selectionData.map((x: any) => x.id).join(',') });
|
||||||
useI18nDeleteSuccessMsg();
|
useI18nDeleteSuccessMsg();
|
||||||
@@ -253,13 +253,13 @@ const deleteTeam = async () => {
|
|||||||
|
|
||||||
/********** 团队成员相关 ***********/
|
/********** 团队成员相关 ***********/
|
||||||
|
|
||||||
const showMembers = async (team: any) => {
|
const onShowMembers = async (team: any) => {
|
||||||
state.showMemDialog.query.teamId = team.id;
|
state.showMemDialog.query.teamId = team.id;
|
||||||
state.showMemDialog.visible = true;
|
state.showMemDialog.visible = true;
|
||||||
state.showMemDialog.title = t('team.teamMember', { teamName: team.name });
|
state.showMemDialog.title = t('team.teamMember', { teamName: team.name });
|
||||||
};
|
};
|
||||||
|
|
||||||
const deleteMember = async (data: any) => {
|
const onDeleteMember = async (data: any) => {
|
||||||
await tagApi.delTeamMem.request(data);
|
await tagApi.delTeamMem.request(data);
|
||||||
useI18nOperateSuccessMsg();
|
useI18nOperateSuccessMsg();
|
||||||
// 重新赋值成员列表
|
// 重新赋值成员列表
|
||||||
@@ -273,11 +273,11 @@ const setMemebers = async () => {
|
|||||||
showMemPageTableRef.value.search();
|
showMemPageTableRef.value.search();
|
||||||
};
|
};
|
||||||
|
|
||||||
const showAddMemberDialog = () => {
|
const onShowAddMemberDialog = () => {
|
||||||
state.showMemDialog.addVisible = true;
|
state.showMemDialog.addVisible = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const addMember = async () => {
|
const onAddMember = async () => {
|
||||||
const memForm = state.showMemDialog.memForm;
|
const memForm = state.showMemDialog.memForm;
|
||||||
memForm.teamId = state.showMemDialog.query.teamId;
|
memForm.teamId = state.showMemDialog.query.teamId;
|
||||||
notBlank(memForm.accountIds, t('team.selectAccountTips'));
|
notBlank(memForm.accountIds, t('team.selectAccountTips'));
|
||||||
@@ -285,10 +285,10 @@ const addMember = async () => {
|
|||||||
await tagApi.saveTeamMem.request(memForm);
|
await tagApi.saveTeamMem.request(memForm);
|
||||||
useI18nSaveSuccessMsg();
|
useI18nSaveSuccessMsg();
|
||||||
setMemebers();
|
setMemebers();
|
||||||
cancelAddMember();
|
onCancelAddMember();
|
||||||
};
|
};
|
||||||
|
|
||||||
const cancelAddMember = () => {
|
const onCancelAddMember = () => {
|
||||||
state.showMemDialog.memForm = {} as any;
|
state.showMemDialog.memForm = {} as any;
|
||||||
state.showMemDialog.addVisible = false;
|
state.showMemDialog.addVisible = false;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<el-dialog :title="title" v-model="visible" :before-close="cancel" :show-close="false" width="600px" :destroy-on-close="true">
|
<el-dialog :title="title" v-model="visible" :before-close="onCancel" :show-close="false" width="600px" :destroy-on-close="true">
|
||||||
<el-form :model="form" ref="accountForm" :rules="rules" label-width="auto">
|
<el-form :model="form" ref="accountFormRef" :rules="rules" label-width="auto">
|
||||||
<el-form-item prop="name" :label="$t('system.account.name')">
|
<el-form-item prop="name" :label="$t('system.account.name')">
|
||||||
<el-input v-model.trim="form.name" auto-complete="off" clearable></el-input>
|
<el-input v-model.trim="form.name" auto-complete="off" clearable></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -49,15 +49,15 @@
|
|||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<el-button @click="cancel()">{{ $t('common.cancel') }}</el-button>
|
<el-button @click="onCancel()">{{ $t('common.cancel') }}</el-button>
|
||||||
<el-button type="primary" :loading="saveBtnLoading" @click="btnOk">{{ $t('common.confirm') }}</el-button>
|
<el-button type="primary" :loading="saveBtnLoading" @click="onConfirm">{{ $t('common.confirm') }}</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { toRefs, reactive, watch, ref } from 'vue';
|
import { toRefs, reactive, watch, useTemplateRef } from 'vue';
|
||||||
import { accountApi } from '../api';
|
import { accountApi } from '../api';
|
||||||
import { randomPassword } from '@/common/utils/string';
|
import { randomPassword } from '@/common/utils/string';
|
||||||
import { useI18nFormValidate, useI18nSaveSuccessMsg } from '@/hooks/useI18n';
|
import { useI18nFormValidate, useI18nSaveSuccessMsg } from '@/hooks/useI18n';
|
||||||
@@ -77,7 +77,7 @@ const emit = defineEmits(['cancel', 'val-change']);
|
|||||||
|
|
||||||
const visible = defineModel<boolean>('visible', { default: false });
|
const visible = defineModel<boolean>('visible', { default: false });
|
||||||
|
|
||||||
const accountForm: any = ref(null);
|
const accountFormRef: any = useTemplateRef('accountFormRef');
|
||||||
|
|
||||||
const rules = {
|
const rules = {
|
||||||
name: [Rules.requiredInput('system.account.name')],
|
name: [Rules.requiredInput('system.account.name')],
|
||||||
@@ -123,16 +123,16 @@ watch(props, (newValue: any) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const btnOk = async () => {
|
const onConfirm = async () => {
|
||||||
await useI18nFormValidate(accountForm);
|
await useI18nFormValidate(accountFormRef);
|
||||||
await saveAccountExec();
|
await saveAccountExec();
|
||||||
useI18nSaveSuccessMsg();
|
useI18nSaveSuccessMsg();
|
||||||
emit('val-change', state.form);
|
emit('val-change', state.form);
|
||||||
//重置表单域
|
//重置表单域
|
||||||
accountForm.value.resetFields();
|
accountFormRef.value.resetFields();
|
||||||
};
|
};
|
||||||
|
|
||||||
const cancel = () => {
|
const onCancel = () => {
|
||||||
visible.value = false;
|
visible.value = false;
|
||||||
emit('cancel');
|
emit('cancel');
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -10,24 +10,24 @@
|
|||||||
:columns="columns"
|
:columns="columns"
|
||||||
>
|
>
|
||||||
<template #tableHeader>
|
<template #tableHeader>
|
||||||
<el-button v-auth="perms.addAccount" type="primary" icon="plus" @click="editAccount(false)">{{ $t('common.create') }}</el-button>
|
<el-button v-auth="perms.addAccount" type="primary" icon="plus" @click="onEditAccount(false)">{{ $t('common.create') }}</el-button>
|
||||||
<el-button v-auth="perms.delAccount" :disabled="state.selectionData.length < 1" @click="deleteAccount()" type="danger" icon="delete">
|
<el-button v-auth="perms.delAccount" :disabled="state.selectionData.length < 1" @click="onDeleteAccount()" type="danger" icon="delete">
|
||||||
{{ $t('common.delete') }}
|
{{ $t('common.delete') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #action="{ data }">
|
<template #action="{ data }">
|
||||||
<el-button link v-if="actionBtns[perms.addAccount]" @click="editAccount(data)" type="primary">{{ $t('common.edit') }}</el-button>
|
<el-button link v-if="actionBtns[perms.addAccount]" @click="onEditAccount(data)" type="primary">{{ $t('common.edit') }}</el-button>
|
||||||
|
|
||||||
<el-button link v-if="actionBtns[perms.saveAccountRole]" @click="showRoleEdit(data)" type="success">
|
<el-button link v-if="actionBtns[perms.saveAccountRole]" @click="onShowRoleEdit(data)" type="success">
|
||||||
{{ $t('system.account.roleAllocation') }}
|
{{ $t('system.account.roleAllocation') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
||||||
<el-button link v-if="actionBtns[perms.changeAccountStatus] && data.status == 1" @click="changeStatus(data)" type="danger">
|
<el-button link v-if="actionBtns[perms.changeAccountStatus] && data.status == 1" @click="onChangeStatus(data)" type="danger">
|
||||||
{{ $t('common.disable') }}
|
{{ $t('common.disable') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
||||||
<el-button link v-if="actionBtns[perms.changeAccountStatus] && data.status == -1" type="success" @click="changeStatus(data)">
|
<el-button link v-if="actionBtns[perms.changeAccountStatus] && data.status == -1" type="success" @click="onChangeStatus(data)">
|
||||||
{{ $t('common.enable') }}
|
{{ $t('common.enable') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
link
|
link
|
||||||
v-if="actionBtns[perms.addAccount]"
|
v-if="actionBtns[perms.addAccount]"
|
||||||
:disabled="!data.otpSecret || data.otpSecret == '-'"
|
:disabled="!data.otpSecret || data.otpSecret == '-'"
|
||||||
@click="resetOtpSecret(data)"
|
@click="onResetOtpSecret(data)"
|
||||||
type="warning"
|
type="warning"
|
||||||
>
|
>
|
||||||
{{ $t('system.account.resetOtp') }}
|
{{ $t('system.account.resetOtp') }}
|
||||||
@@ -55,8 +55,8 @@
|
|||||||
</el-table>
|
</el-table>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<role-allocation v-model:visible="roleDialog.visible" :account="roleDialog.account" @cancel="cancel()" />
|
<role-allocation v-model:visible="roleDialog.visible" :account="roleDialog.account" @cancel="onCancel()" />
|
||||||
<account-edit :title="accountDialog.title" v-model:visible="accountDialog.visible" v-model:account="accountDialog.data" @val-change="valChange()" />
|
<account-edit :title="accountDialog.title" v-model:visible="accountDialog.visible" v-model:account="accountDialog.data" @val-change="onValChange()" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -150,7 +150,7 @@ const search = async () => {
|
|||||||
pageTableRef.value.search();
|
pageTableRef.value.search();
|
||||||
};
|
};
|
||||||
|
|
||||||
const changeStatus = async (row: any) => {
|
const onChangeStatus = async (row: any) => {
|
||||||
let id = row.id;
|
let id = row.id;
|
||||||
let status = row.status == AccountStatusEnum.Disable.value ? AccountStatusEnum.Enable.value : AccountStatusEnum.Disable.value;
|
let status = row.status == AccountStatusEnum.Disable.value ? AccountStatusEnum.Enable.value : AccountStatusEnum.Disable.value;
|
||||||
await accountApi.changeStatus.request({
|
await accountApi.changeStatus.request({
|
||||||
@@ -161,7 +161,7 @@ const changeStatus = async (row: any) => {
|
|||||||
search();
|
search();
|
||||||
};
|
};
|
||||||
|
|
||||||
const resetOtpSecret = async (row: any) => {
|
const onResetOtpSecret = async (row: any) => {
|
||||||
let id = row.id;
|
let id = row.id;
|
||||||
await accountApi.resetOtpSecret.request({
|
await accountApi.resetOtpSecret.request({
|
||||||
id,
|
id,
|
||||||
@@ -170,7 +170,7 @@ const resetOtpSecret = async (row: any) => {
|
|||||||
row.otpSecret = '-';
|
row.otpSecret = '-';
|
||||||
};
|
};
|
||||||
|
|
||||||
const editAccount = (data: any) => {
|
const onEditAccount = (data: any) => {
|
||||||
if (!data) {
|
if (!data) {
|
||||||
state.accountDialog.title = useI18nCreateTitle('personal.accountInfo');
|
state.accountDialog.title = useI18nCreateTitle('personal.accountInfo');
|
||||||
state.accountDialog.data = null;
|
state.accountDialog.data = null;
|
||||||
@@ -181,22 +181,22 @@ const editAccount = (data: any) => {
|
|||||||
state.accountDialog.visible = true;
|
state.accountDialog.visible = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const showRoleEdit = (data: any) => {
|
const onShowRoleEdit = (data: any) => {
|
||||||
state.roleDialog.visible = true;
|
state.roleDialog.visible = true;
|
||||||
state.roleDialog.account = data;
|
state.roleDialog.account = data;
|
||||||
};
|
};
|
||||||
|
|
||||||
const cancel = () => {
|
const onCancel = () => {
|
||||||
state.roleDialog.visible = false;
|
state.roleDialog.visible = false;
|
||||||
state.roleDialog.account = null;
|
state.roleDialog.account = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
const valChange = () => {
|
const onValChange = () => {
|
||||||
state.accountDialog.visible = false;
|
state.accountDialog.visible = false;
|
||||||
search();
|
search();
|
||||||
};
|
};
|
||||||
|
|
||||||
const deleteAccount = async () => {
|
const onDeleteAccount = async () => {
|
||||||
await useI18nDeleteConfirm(state.selectionData.map((x: any) => x.username).join('、'));
|
await useI18nDeleteConfirm(state.selectionData.map((x: any) => x.username).join('、'));
|
||||||
await accountApi.del.request({ id: state.selectionData.map((x: any) => x.id).join(',') });
|
await accountApi.del.request({ id: state.selectionData.map((x: any) => x.id).join(',') });
|
||||||
useI18nDeleteSuccessMsg();
|
useI18nDeleteSuccessMsg();
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
@open="searchAccountRoles()"
|
@open="searchAccountRoles()"
|
||||||
:title="account == null ? '' : $t('system.account.allocateRoleTitle', { name: account.username })"
|
:title="account == null ? '' : $t('system.account.allocateRoleTitle', { name: account.username })"
|
||||||
v-model="dialogVisible"
|
v-model="dialogVisible"
|
||||||
:before-close="cancel"
|
:before-close="onCancel"
|
||||||
:destroy-on-close="true"
|
:destroy-on-close="true"
|
||||||
width="55%"
|
width="55%"
|
||||||
>
|
>
|
||||||
@@ -20,11 +20,11 @@
|
|||||||
lazy
|
lazy
|
||||||
>
|
>
|
||||||
<template #tableHeader>
|
<template #tableHeader>
|
||||||
<el-button @click="showResources" icon="view" type="primary" link>{{ $t('system.account.menuAndPermission') }}</el-button>
|
<el-button @click="onShowResources" icon="view" type="primary" link>{{ $t('system.account.menuAndPermission') }}</el-button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #action="{ data }">
|
<template #action="{ data }">
|
||||||
<el-button v-auth="'account:saveRoles'" type="danger" @click="relateRole(-1, data.roleId)" icon="delete" link plain>
|
<el-button v-auth="'account:saveRoles'" type="danger" @click="onRelateRole(-1, data.roleId)" icon="delete" link plain>
|
||||||
{{ $t('system.account.remove') }}
|
{{ $t('system.account.remove') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
<template #action="{ data }">
|
<template #action="{ data }">
|
||||||
<el-button
|
<el-button
|
||||||
v-auth="'account:saveRoles'"
|
v-auth="'account:saveRoles'"
|
||||||
@click="relateRole(1, data.id)"
|
@click="onRelateRole(1, data.id)"
|
||||||
:disabled="data.code?.indexOf('COMMON') == 0 || data.status == RoleStatusEnum.Disable.value"
|
:disabled="data.code?.indexOf('COMMON') == 0 || data.status == RoleStatusEnum.Disable.value"
|
||||||
type="success"
|
type="success"
|
||||||
icon="CirclePlus"
|
icon="CirclePlus"
|
||||||
@@ -176,7 +176,7 @@ const onTabChange = () => {
|
|||||||
searchAccountRoles();
|
searchAccountRoles();
|
||||||
};
|
};
|
||||||
|
|
||||||
const relateRole = async (relateType: number, roleId: number) => {
|
const onRelateRole = async (relateType: number, roleId: number) => {
|
||||||
await accountApi.saveRole.request({
|
await accountApi.saveRole.request({
|
||||||
id: props.account!.id,
|
id: props.account!.id,
|
||||||
roleId,
|
roleId,
|
||||||
@@ -191,7 +191,7 @@ const relateRole = async (relateType: number, roleId: number) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const showResources = async () => {
|
const onShowResources = async () => {
|
||||||
let showResourceDialog = state.showResourceDialog;
|
let showResourceDialog = state.showResourceDialog;
|
||||||
showResourceDialog.title = t('system.account.userMenuTitle', { name: props.account?.username });
|
showResourceDialog.title = t('system.account.userMenuTitle', { name: props.account?.username });
|
||||||
showResourceDialog.resources = [];
|
showResourceDialog.resources = [];
|
||||||
@@ -204,7 +204,7 @@ const showResources = async () => {
|
|||||||
/**
|
/**
|
||||||
* 取消
|
* 取消
|
||||||
*/
|
*/
|
||||||
const cancel = () => {
|
const onCancel = () => {
|
||||||
state.unRelatedQuery.pageNum = 1;
|
state.unRelatedQuery.pageNum = 1;
|
||||||
state.unRelatedQuery.name = null;
|
state.unRelatedQuery.name = null;
|
||||||
state.unRelatedQuery.code = null;
|
state.unRelatedQuery.code = null;
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<el-drawer :title="title" v-model="visible" :show-close="false" :before-close="cancel" size="1000px" :destroy-on-close="true">
|
<el-drawer :title="title" v-model="visible" :show-close="false" :before-close="onCancel" size="1000px" :destroy-on-close="true">
|
||||||
<template #header>
|
<template #header>
|
||||||
<DrawerHeader :header="title" :back="cancel" />
|
<DrawerHeader :header="title" :back="onCancel" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<el-form ref="configForm" :model="form" :rules="rules" label-width="auto">
|
<el-form ref="configFormRef" :model="form" :rules="rules" label-width="auto">
|
||||||
<el-form-item prop="name" :label="$t('system.sysconf.confItem')" required>
|
<el-form-item prop="name" :label="$t('system.sysconf.confItem')" required>
|
||||||
<el-input v-model="form.name"></el-input>
|
<el-input v-model="form.name"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -35,8 +35,8 @@
|
|||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<el-button @click="cancel()">{{ $t('common.cancel') }}</el-button>
|
<el-button @click="onCancel()">{{ $t('common.cancel') }}</el-button>
|
||||||
<el-button type="primary" :loading="saveBtnLoading" @click="btnOk">{{ $t('common.confirm') }}</el-button>
|
<el-button type="primary" :loading="saveBtnLoading" @click="onConfirm">{{ $t('common.confirm') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-drawer>
|
</el-drawer>
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, toRefs, reactive, watch } from 'vue';
|
import { toRefs, reactive, watch, useTemplateRef } from 'vue';
|
||||||
import { configApi, accountApi } from '../api';
|
import { configApi, accountApi } from '../api';
|
||||||
import { DynamicFormEdit } from '@/components/dynamic-form';
|
import { DynamicFormEdit } from '@/components/dynamic-form';
|
||||||
import DrawerHeader from '@/components/drawer-header/DrawerHeader.vue';
|
import DrawerHeader from '@/components/drawer-header/DrawerHeader.vue';
|
||||||
@@ -70,7 +70,7 @@ const visible = defineModel<boolean>('visible', { default: false });
|
|||||||
//定义事件
|
//定义事件
|
||||||
const emit = defineEmits(['cancel', 'val-change']);
|
const emit = defineEmits(['cancel', 'val-change']);
|
||||||
|
|
||||||
const configForm: any = ref(null);
|
const configFormRef: any = useTemplateRef('configFormRef');
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
params: [] as any,
|
params: [] as any,
|
||||||
@@ -116,7 +116,7 @@ watch(visible, () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const cancel = () => {
|
const onCancel = () => {
|
||||||
visible.value = false;
|
visible.value = false;
|
||||||
// 若父组件有取消事件,则调用
|
// 若父组件有取消事件,则调用
|
||||||
emit('cancel');
|
emit('cancel');
|
||||||
@@ -131,8 +131,8 @@ const getAccount = (username: any) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const btnOk = async () => {
|
const onConfirm = async () => {
|
||||||
await useI18nFormValidate(configForm);
|
await useI18nFormValidate(configFormRef);
|
||||||
if (state.params) {
|
if (state.params) {
|
||||||
state.form.params = JSON.stringify(state.params);
|
state.form.params = JSON.stringify(state.params);
|
||||||
}
|
}
|
||||||
@@ -144,7 +144,7 @@ const btnOk = async () => {
|
|||||||
|
|
||||||
await saveConfigExec();
|
await saveConfigExec();
|
||||||
emit('val-change', state.form);
|
emit('val-change', state.form);
|
||||||
cancel();
|
onCancel();
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss"></style>
|
<style lang="scss"></style>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
:data-handler-fn="handleData"
|
:data-handler-fn="handleData"
|
||||||
>
|
>
|
||||||
<template #tableHeader>
|
<template #tableHeader>
|
||||||
<el-button v-auth="perms.saveConfig" type="primary" icon="plus" @click="editConfig(false)">{{ $t('common.create') }}</el-button>
|
<el-button v-auth="perms.saveConfig" type="primary" icon="plus" @click="onEditConfig(false)">{{ $t('common.create') }}</el-button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #status="{ data }">
|
<template #status="{ data }">
|
||||||
@@ -19,11 +19,11 @@
|
|||||||
|
|
||||||
<template #action="{ data }">
|
<template #action="{ data }">
|
||||||
<el-button :disabled="data.status == -1" type="warning" @click="showSetConfigDialog(data)" link>{{ $t('system.sysconf.conf') }}</el-button>
|
<el-button :disabled="data.status == -1" type="warning" @click="showSetConfigDialog(data)" link>{{ $t('system.sysconf.conf') }}</el-button>
|
||||||
<el-button v-if="actionBtns[perms.saveConfig]" @click="editConfig(data)" type="primary" link>{{ $t('common.edit') }}</el-button>
|
<el-button v-if="actionBtns[perms.saveConfig]" @click="onEditConfig(data)" type="primary" link>{{ $t('common.edit') }}</el-button>
|
||||||
</template>
|
</template>
|
||||||
</page-table>
|
</page-table>
|
||||||
|
|
||||||
<el-dialog @close="closeSetConfigDialog" :title="$t('system.sysconf.confItemSetting')" v-model="paramsDialog.visible" width="700px">
|
<el-dialog @close="onCloseSetConfigDialog" :title="$t('system.sysconf.confItemSetting')" v-model="paramsDialog.visible" width="700px">
|
||||||
<dynamic-form
|
<dynamic-form
|
||||||
ref="paramsFormRef"
|
ref="paramsFormRef"
|
||||||
v-if="paramsDialog.paramsFormItem.length > 0"
|
v-if="paramsDialog.paramsFormItem.length > 0"
|
||||||
@@ -39,13 +39,13 @@
|
|||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
<el-button @click="closeSetConfigDialog()">{{ $t('common.cancel') }}</el-button>
|
<el-button @click="onCloseSetConfigDialog()">{{ $t('common.cancel') }}</el-button>
|
||||||
<el-button v-auth="'config:save'" type="primary" @click="setConfig()">{{ $t('common.confirm') }}</el-button>
|
<el-button v-auth="'config:save'" type="primary" @click="setConfig()">{{ $t('common.confirm') }}</el-button>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<config-edit :title="$t(configEdit.title)" v-model:visible="configEdit.visible" :data="configEdit.config" @val-change="configEditChange" />
|
<config-edit :title="$t(configEdit.title)" v-model:visible="configEdit.visible" :data="configEdit.config" @val-change="onConfigEditChange" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -143,7 +143,7 @@ const showSetConfigDialog = (row: any) => {
|
|||||||
state.paramsDialog.visible = true;
|
state.paramsDialog.visible = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const closeSetConfigDialog = () => {
|
const onCloseSetConfigDialog = () => {
|
||||||
state.paramsDialog.visible = false;
|
state.paramsDialog.visible = false;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
state.paramsDialog.config = {};
|
state.paramsDialog.config = {};
|
||||||
@@ -182,7 +182,7 @@ const setConfig = async () => {
|
|||||||
value: paramsValue,
|
value: paramsValue,
|
||||||
});
|
});
|
||||||
useI18nSaveSuccessMsg();
|
useI18nSaveSuccessMsg();
|
||||||
closeSetConfigDialog();
|
onCloseSetConfigDialog();
|
||||||
search();
|
search();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -195,12 +195,12 @@ const hasParam = (paramKey: string, paramItems: any) => {
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const configEditChange = () => {
|
const onConfigEditChange = () => {
|
||||||
useI18nSaveSuccessMsg();
|
useI18nSaveSuccessMsg();
|
||||||
search();
|
search();
|
||||||
};
|
};
|
||||||
|
|
||||||
const editConfig = (data: any) => {
|
const onEditConfig = (data: any) => {
|
||||||
if (data) {
|
if (data) {
|
||||||
state.configEdit.title = 'common.edit';
|
state.configEdit.title = 'common.edit';
|
||||||
state.configEdit.config = data;
|
state.configEdit.config = data;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<el-dialog :title="title" :destroy-on-close="true" v-model="visible" width="800px">
|
<el-dialog :title="title" :destroy-on-close="true" v-model="visible" width="800px">
|
||||||
<el-form :model="form" :inline="true" ref="menuForm" :rules="rules" label-width="auto">
|
<el-form :model="form" :inline="true" ref="menuFormRef" :rules="rules" label-width="auto">
|
||||||
<el-row :gutter="35">
|
<el-row :gutter="35">
|
||||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
||||||
<el-form-item class="!w-full" prop="type" :label="$t('common.type')" required>
|
<el-form-item class="!w-full" prop="type" :label="$t('common.type')" required>
|
||||||
@@ -71,7 +71,7 @@
|
|||||||
prop="meta.linkType"
|
prop="meta.linkType"
|
||||||
:tooltip="$t('system.menu.externalLinkTips')"
|
:tooltip="$t('system.menu.externalLinkTips')"
|
||||||
>
|
>
|
||||||
<el-select class="!w-full" @change="changeLinkType" v-model="form.meta.linkType">
|
<el-select class="!w-full" @change="onChangeLinkType" v-model="form.meta.linkType">
|
||||||
<el-option :key="0" :label="$t('system.menu.no')" :value="0"> </el-option>
|
<el-option :key="0" :label="$t('system.menu.no')" :value="0"> </el-option>
|
||||||
<el-option :key="1" :label="$t('system.menu.inline')" :value="1"> </el-option>
|
<el-option :key="1" :label="$t('system.menu.inline')" :value="1"> </el-option>
|
||||||
<el-option :key="2" :label="$t('system.menu.externalLink')" :value="2"> </el-option>
|
<el-option :key="2" :label="$t('system.menu.externalLink')" :value="2"> </el-option>
|
||||||
@@ -87,17 +87,15 @@
|
|||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div>
|
<el-button @click="onCancel()">{{ $t('common.cancel') }}</el-button>
|
||||||
<el-button @click="cancel()">{{ $t('common.cancel') }}</el-button>
|
<el-button type="primary" :loading="saveBtnLoading" @click="onConfirm">{{ $t('common.confirm') }}</el-button>
|
||||||
<el-button type="primary" :loading="saveBtnLoading" @click="btnOk">{{ $t('common.confirm') }}</el-button>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, toRefs, reactive, watchEffect } from 'vue';
|
import { toRefs, reactive, watchEffect, useTemplateRef } from 'vue';
|
||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
||||||
import { resourceApi } from '../api';
|
import { resourceApi } from '../api';
|
||||||
import { ResourceTypeEnum } from '../enums';
|
import { ResourceTypeEnum } from '../enums';
|
||||||
@@ -107,6 +105,7 @@ import { useI18n } from 'vue-i18n';
|
|||||||
import EnumSelect from '@/components/enumselect/EnumSelect.vue';
|
import EnumSelect from '@/components/enumselect/EnumSelect.vue';
|
||||||
import FormItemTooltip from '@/components/form/FormItemTooltip.vue';
|
import FormItemTooltip from '@/components/form/FormItemTooltip.vue';
|
||||||
import { Rules } from '@/common/rule';
|
import { Rules } from '@/common/rule';
|
||||||
|
import { useI18nFormValidate } from '@/hooks/useI18n';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
@@ -127,7 +126,7 @@ const visible = defineModel<boolean>('visible', { default: false });
|
|||||||
//定义事件
|
//定义事件
|
||||||
const emit = defineEmits(['cancel', 'val-change']);
|
const emit = defineEmits(['cancel', 'val-change']);
|
||||||
|
|
||||||
const menuForm: any = ref(null);
|
const menuFormRef: any = useTemplateRef('menuFormRef');
|
||||||
|
|
||||||
const menuTypeValue = ResourceTypeEnum.Menu.value;
|
const menuTypeValue = ResourceTypeEnum.Menu.value;
|
||||||
|
|
||||||
@@ -208,17 +207,12 @@ watchEffect(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 改变外链类型
|
// 改变外链类型
|
||||||
const changeLinkType = () => {
|
const onChangeLinkType = () => {
|
||||||
state.form.meta.component = '';
|
state.form.meta.component = '';
|
||||||
};
|
};
|
||||||
|
|
||||||
const btnOk = async () => {
|
const onConfirm = async () => {
|
||||||
try {
|
await useI18nFormValidate(menuFormRef);
|
||||||
await menuForm.value.validate();
|
|
||||||
} catch (e: any) {
|
|
||||||
ElMessage.error(t('common.formValidationError'));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const submitForm = { ...state.form };
|
const submitForm = { ...state.form };
|
||||||
if (submitForm.type == 1) {
|
if (submitForm.type == 1) {
|
||||||
@@ -233,7 +227,7 @@ const btnOk = async () => {
|
|||||||
|
|
||||||
emit('val-change', submitForm);
|
emit('val-change', submitForm);
|
||||||
ElMessage.success(t('common.saveSuccess'));
|
ElMessage.success(t('common.saveSuccess'));
|
||||||
cancel();
|
onCancel();
|
||||||
};
|
};
|
||||||
|
|
||||||
const parseMenuMeta = (meta: any) => {
|
const parseMenuMeta = (meta: any) => {
|
||||||
@@ -270,7 +264,7 @@ const parseMenuMeta = (meta: any) => {
|
|||||||
return metaForm;
|
return metaForm;
|
||||||
};
|
};
|
||||||
|
|
||||||
const cancel = () => {
|
const onCancel = () => {
|
||||||
visible.value = false;
|
visible.value = false;
|
||||||
emit('cancel');
|
emit('cancel');
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<div class="card !p-1 mr-1 flex justify-between">
|
<div class="card !p-1 mr-1 flex justify-between">
|
||||||
<div class="mb-1">
|
<div class="mb-1">
|
||||||
<el-input v-model="filterResource" clearable :placeholder="$t('system.menu.filterPlaceholder')" class="mr-2 !w-[200px]" />
|
<el-input v-model="filterResource" clearable :placeholder="$t('system.menu.filterPlaceholder')" class="mr-2 !w-[200px]" />
|
||||||
<el-button v-auth="perms.addResource" type="primary" icon="plus" @click="addResource(false)"></el-button>
|
<el-button v-auth="perms.addResource" type="primary" icon="plus" @click="onAddResource(false)"></el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
@node-expand="handleNodeExpand"
|
@node-expand="handleNodeExpand"
|
||||||
@node-collapse="handleNodeCollapse"
|
@node-collapse="handleNodeCollapse"
|
||||||
@node-contextmenu="nodeContextmenu"
|
@node-contextmenu="nodeContextmenu"
|
||||||
@node-click="treeNodeClick"
|
@node-click="onTreeNodeClick"
|
||||||
:default-expanded-keys="defaultExpandedKeys"
|
:default-expanded-keys="defaultExpandedKeys"
|
||||||
:expand-on-click-node="false"
|
:expand-on-click-node="false"
|
||||||
draggable
|
draggable
|
||||||
@@ -136,7 +136,7 @@
|
|||||||
:typeDisabled="dialogForm.typeDisabled"
|
:typeDisabled="dialogForm.typeDisabled"
|
||||||
:departTree="data"
|
:departTree="data"
|
||||||
:type="dialogForm.type"
|
:type="dialogForm.type"
|
||||||
@val-change="valChange"
|
@val-change="onValChange"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<contextmenu :dropdown="state.contextmenu.dropdown" :items="state.contextmenu.items" ref="contextmenuRef" />
|
<contextmenu :dropdown="state.contextmenu.dropdown" :items="state.contextmenu.items" ref="contextmenuRef" />
|
||||||
@@ -186,29 +186,29 @@ const contextmenuAdd = new ContextmenuItem('add', 'system.menu.addSubResource')
|
|||||||
.withIcon('circle-plus')
|
.withIcon('circle-plus')
|
||||||
.withPermission(perms.addResource)
|
.withPermission(perms.addResource)
|
||||||
.withHideFunc((data: any) => data.type !== menuTypeValue)
|
.withHideFunc((data: any) => data.type !== menuTypeValue)
|
||||||
.withOnClick((data: any) => addResource(data));
|
.withOnClick((data: any) => onAddResource(data));
|
||||||
|
|
||||||
const contextmenuEdit = new ContextmenuItem('edit', 'common.edit')
|
const contextmenuEdit = new ContextmenuItem('edit', 'common.edit')
|
||||||
.withIcon('edit')
|
.withIcon('edit')
|
||||||
.withPermission(perms.updateResource)
|
.withPermission(perms.updateResource)
|
||||||
.withOnClick((data: any) => editResource(data));
|
.withOnClick((data: any) => onEditResource(data));
|
||||||
|
|
||||||
const contextmenuEnable = new ContextmenuItem('enable', 'system.menu.enable')
|
const contextmenuEnable = new ContextmenuItem('enable', 'system.menu.enable')
|
||||||
.withIcon('circle-check')
|
.withIcon('circle-check')
|
||||||
.withPermission(perms.updateResource)
|
.withPermission(perms.updateResource)
|
||||||
.withHideFunc((data: any) => data.status === 1)
|
.withHideFunc((data: any) => data.status === 1)
|
||||||
.withOnClick((data: any) => changeStatus(data, 1));
|
.withOnClick((data: any) => onChangeStatus(data, 1));
|
||||||
|
|
||||||
const contextmenuDisable = new ContextmenuItem('disable', 'system.menu.disable')
|
const contextmenuDisable = new ContextmenuItem('disable', 'system.menu.disable')
|
||||||
.withIcon('circle-close')
|
.withIcon('circle-close')
|
||||||
.withPermission(perms.updateResource)
|
.withPermission(perms.updateResource)
|
||||||
.withHideFunc((data: any) => data.status === -1)
|
.withHideFunc((data: any) => data.status === -1)
|
||||||
.withOnClick((data: any) => changeStatus(data, -1));
|
.withOnClick((data: any) => onChangeStatus(data, -1));
|
||||||
|
|
||||||
const contextmenuDel = new ContextmenuItem('delete', 'common.delete')
|
const contextmenuDel = new ContextmenuItem('delete', 'common.delete')
|
||||||
.withIcon('delete')
|
.withIcon('delete')
|
||||||
.withPermission(perms.delResource)
|
.withPermission(perms.delResource)
|
||||||
.withOnClick((data: any) => deleteMenu(data));
|
.withOnClick((data: any) => onDeleteMenu(data));
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
contextmenu: {
|
contextmenu: {
|
||||||
@@ -263,7 +263,7 @@ const nodeContextmenu = (event: any, data: any) => {
|
|||||||
contextmenuRef.value.openContextmenu(data);
|
contextmenuRef.value.openContextmenu(data);
|
||||||
};
|
};
|
||||||
|
|
||||||
const treeNodeClick = async (data: any) => {
|
const onTreeNodeClick = async (data: any) => {
|
||||||
state.activeTabName = ResourceDetail;
|
state.activeTabName = ResourceDetail;
|
||||||
// 关闭可能存在的右击菜单
|
// 关闭可能存在的右击菜单
|
||||||
contextmenuRef.value.closeContextmenu();
|
contextmenuRef.value.closeContextmenu();
|
||||||
@@ -286,7 +286,7 @@ const onTabClick = async (activeTab: any) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const deleteMenu = async (data: any) => {
|
const onDeleteMenu = async (data: any) => {
|
||||||
await useI18nDeleteConfirm(data.name);
|
await useI18nDeleteConfirm(data.name);
|
||||||
await resourceApi.del.request({
|
await resourceApi.del.request({
|
||||||
id: data.id,
|
id: data.id,
|
||||||
@@ -296,7 +296,7 @@ const deleteMenu = async (data: any) => {
|
|||||||
search();
|
search();
|
||||||
};
|
};
|
||||||
|
|
||||||
const addResource = (data: any) => {
|
const onAddResource = (data: any) => {
|
||||||
let dialog = state.dialogForm;
|
let dialog = state.dialogForm;
|
||||||
dialog.data = { pid: 0, type: 1 };
|
dialog.data = { pid: 0, type: 1 };
|
||||||
// 添加顶级菜单情况
|
// 添加顶级菜单情况
|
||||||
@@ -333,7 +333,7 @@ const addResource = (data: any) => {
|
|||||||
dialog.visible = true;
|
dialog.visible = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const editResource = async (data: any) => {
|
const onEditResource = async (data: any) => {
|
||||||
const res = await resourceApi.detail.request({
|
const res = await resourceApi.detail.request({
|
||||||
id: data.id,
|
id: data.id,
|
||||||
});
|
});
|
||||||
@@ -347,12 +347,12 @@ const editResource = async (data: any) => {
|
|||||||
state.dialogForm.visible = true;
|
state.dialogForm.visible = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const valChange = () => {
|
const onValChange = () => {
|
||||||
search();
|
search();
|
||||||
state.dialogForm.visible = false;
|
state.dialogForm.visible = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const changeStatus = async (data: any, status: any) => {
|
const onChangeStatus = async (data: any, status: any) => {
|
||||||
await resourceApi.changeStatus.request({
|
await resourceApi.changeStatus.request({
|
||||||
id: data.id,
|
id: data.id,
|
||||||
status: status,
|
status: status,
|
||||||
|
|||||||
@@ -9,11 +9,11 @@
|
|||||||
>
|
>
|
||||||
<page-table ref="pageTableRef" :page-api="roleApi.roleAccounts" :search-items="searchItems" v-model:query-form="query" :columns="columns" lazy>
|
<page-table ref="pageTableRef" :page-api="roleApi.roleAccounts" :search-items="searchItems" v-model:query-form="query" :columns="columns" lazy>
|
||||||
<template #tableHeader>
|
<template #tableHeader>
|
||||||
<el-button v-auth="perms.saveAccountRole" type="primary" icon="plus" @click="showAddAccount()">{{ $t('common.add') }}</el-button>
|
<el-button v-auth="perms.saveAccountRole" type="primary" icon="plus" @click="onShowAddAccount()">{{ $t('common.add') }}</el-button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #action="{ data }">
|
<template #action="{ data }">
|
||||||
<el-button link v-if="actionBtns[perms.saveAccountRole]" @click="relateAccount(-1, data.accountId)" icon="delete" type="danger">
|
<el-button link v-if="actionBtns[perms.saveAccountRole]" @click="onRelateAccount(-1, data.accountId)" icon="delete" type="danger">
|
||||||
{{ $t('common.remove') }}
|
{{ $t('common.remove') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
<el-dialog
|
<el-dialog
|
||||||
width="400px"
|
width="400px"
|
||||||
:title="$t('system.role.addAccount')"
|
:title="$t('system.role.addAccount')"
|
||||||
:before-close="cancelAddAccount"
|
:before-close="onCancelAddAccount"
|
||||||
v-model="addAccountDialog.visible"
|
v-model="addAccountDialog.visible"
|
||||||
:destroy-on-close="true"
|
:destroy-on-close="true"
|
||||||
>
|
>
|
||||||
@@ -31,8 +31,8 @@
|
|||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<el-button @click="cancelAddAccount()">{{ $t('common.cancel') }}</el-button>
|
<el-button @click="onCancelAddAccount()">{{ $t('common.cancel') }}</el-button>
|
||||||
<el-button @click="relateAccount(1, addAccountDialog.accountId)" type="primary">{{ $t('common.confirm') }}</el-button>
|
<el-button @click="onRelateAccount(1, addAccountDialog.accountId)" type="primary">{{ $t('common.confirm') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
@@ -107,7 +107,7 @@ const searchRoleAccount = () => {
|
|||||||
pageTableRef.value.search();
|
pageTableRef.value.search();
|
||||||
};
|
};
|
||||||
|
|
||||||
const relateAccount = async (relateType: number, accountId: number) => {
|
const onRelateAccount = async (relateType: number, accountId: number) => {
|
||||||
await accountApi.saveRole.request({
|
await accountApi.saveRole.request({
|
||||||
id: accountId,
|
id: accountId,
|
||||||
roleId: props.role?.id,
|
roleId: props.role?.id,
|
||||||
@@ -116,16 +116,16 @@ const relateAccount = async (relateType: number, accountId: number) => {
|
|||||||
useI18nOperateSuccessMsg();
|
useI18nOperateSuccessMsg();
|
||||||
// 如果是新增账号,则关闭新增账号弹窗
|
// 如果是新增账号,则关闭新增账号弹窗
|
||||||
if (relateType == 1) {
|
if (relateType == 1) {
|
||||||
cancelAddAccount();
|
onCancelAddAccount();
|
||||||
}
|
}
|
||||||
searchRoleAccount();
|
searchRoleAccount();
|
||||||
};
|
};
|
||||||
|
|
||||||
const showAddAccount = () => {
|
const onShowAddAccount = () => {
|
||||||
state.addAccountDialog.visible = true;
|
state.addAccountDialog.visible = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const cancelAddAccount = () => {
|
const onCancelAddAccount = () => {
|
||||||
state.addAccountDialog.accountId = null;
|
state.addAccountDialog.accountId = null;
|
||||||
state.addAccountDialog.accounts = [];
|
state.addAccountDialog.accounts = [];
|
||||||
state.addAccountDialog.visible = false;
|
state.addAccountDialog.visible = false;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<el-dialog
|
<el-dialog
|
||||||
:title="$t('system.role.allocateMenuTitle', { roleName: roleInfo?.name })"
|
:title="$t('system.role.allocateMenuTitle', { roleName: roleInfo?.name })"
|
||||||
v-model="visible"
|
v-model="visible"
|
||||||
:before-close="cancel"
|
:before-close="onCancel"
|
||||||
:show-close="false"
|
:show-close="false"
|
||||||
width="400px"
|
width="400px"
|
||||||
>
|
>
|
||||||
@@ -26,8 +26,8 @@
|
|||||||
</el-tree>
|
</el-tree>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<el-button :loading="state.submiting" @click="cancel">{{ $t('common.cancel') }}</el-button>
|
<el-button :loading="state.submiting" @click="onCancel">{{ $t('common.cancel') }}</el-button>
|
||||||
<el-button :loading="state.submiting" type="primary" @click="btnOk">{{ $t('common.confirm') }}</el-button>
|
<el-button :loading="state.submiting" type="primary" @click="onConfirm">{{ $t('common.confirm') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
@@ -88,7 +88,7 @@ watch(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const btnOk = async () => {
|
const onConfirm = async () => {
|
||||||
let menuIds = menuTree.value.getCheckedKeys();
|
let menuIds = menuTree.value.getCheckedKeys();
|
||||||
let halfMenuIds = menuTree.value.getHalfCheckedKeys();
|
let halfMenuIds = menuTree.value.getHalfCheckedKeys();
|
||||||
let resources = [].concat(menuIds, halfMenuIds).join(',');
|
let resources = [].concat(menuIds, halfMenuIds).join(',');
|
||||||
@@ -105,7 +105,7 @@ const btnOk = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const cancel = () => {
|
const onCancel = () => {
|
||||||
visible.value = false;
|
visible.value = false;
|
||||||
emit('cancel');
|
emit('cancel');
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<el-dialog :title="title" v-model="visible" :show-close="false" :before-close="cancel" width="600px" :destroy-on-close="true">
|
<el-dialog :title="title" v-model="visible" :show-close="false" :before-close="onCancel" width="600px" :destroy-on-close="true">
|
||||||
<el-form ref="roleForm" :model="form" :rules="rules" label-width="auto">
|
<el-form ref="roleFormRef" :model="form" :rules="rules" label-width="auto">
|
||||||
<el-form-item prop="name" :label="$t('system.role.roleName')" required>
|
<el-form-item prop="name" :label="$t('system.role.roleName')" required>
|
||||||
<el-input v-model="form.name" auto-complete="off"></el-input>
|
<el-input v-model="form.name" auto-complete="off"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -22,8 +22,8 @@
|
|||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<el-button @click="cancel()">{{ $t('common.cancel') }}</el-button>
|
<el-button @click="onCancel()">{{ $t('common.cancel') }}</el-button>
|
||||||
<el-button type="primary" :loading="saveBtnLoading" @click="btnOk">{{ $t('common.confirm') }}</el-button>
|
<el-button type="primary" :loading="saveBtnLoading" @click="onConfirm">{{ $t('common.confirm') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, toRefs, reactive, watchEffect } from 'vue';
|
import { toRefs, reactive, watchEffect, useTemplateRef } from 'vue';
|
||||||
import { roleApi } from '../api';
|
import { roleApi } from '../api';
|
||||||
import { RoleStatusEnum } from '../enums';
|
import { RoleStatusEnum } from '../enums';
|
||||||
import EnumSelect from '@/components/enumselect/EnumSelect.vue';
|
import EnumSelect from '@/components/enumselect/EnumSelect.vue';
|
||||||
@@ -58,7 +58,8 @@ const visible = defineModel<boolean>('visible', { default: false });
|
|||||||
//定义事件
|
//定义事件
|
||||||
const emit = defineEmits(['cancel', 'val-change']);
|
const emit = defineEmits(['cancel', 'val-change']);
|
||||||
|
|
||||||
const roleForm: any = ref(null);
|
const roleFormRef: any = useTemplateRef('roleFormRef');
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
form: {
|
form: {
|
||||||
id: null,
|
id: null,
|
||||||
@@ -84,17 +85,17 @@ watchEffect(() => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const cancel = () => {
|
const onCancel = () => {
|
||||||
visible.value = false;
|
visible.value = false;
|
||||||
// 若父组件有取消事件,则调用
|
// 若父组件有取消事件,则调用
|
||||||
emit('cancel');
|
emit('cancel');
|
||||||
};
|
};
|
||||||
|
|
||||||
const btnOk = async () => {
|
const onConfirm = async () => {
|
||||||
await useI18nFormValidate(roleForm);
|
await useI18nFormValidate(roleFormRef);
|
||||||
await saveRoleExec();
|
await saveRoleExec();
|
||||||
emit('val-change', state.form);
|
emit('val-change', state.form);
|
||||||
cancel();
|
onCancel();
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss"></style>
|
<style lang="scss"></style>
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ func (a *AccountLogin) ReqConfs() *req.Confs {
|
|||||||
|
|
||||||
// @router /auth/accounts/login [post]
|
// @router /auth/accounts/login [post]
|
||||||
func (a *AccountLogin) Login(rc *req.Ctx) {
|
func (a *AccountLogin) Login(rc *req.Ctx) {
|
||||||
loginForm := req.BindJsonAndValid(rc, new(form.LoginForm))
|
loginForm := req.BindJsonAndValid[*form.LoginForm](rc)
|
||||||
ctx := rc.MetaCtx
|
ctx := rc.MetaCtx
|
||||||
|
|
||||||
accountLoginSecurity := config.GetAccountLoginSecurity()
|
accountLoginSecurity := config.GetAccountLoginSecurity()
|
||||||
@@ -96,8 +96,7 @@ type OtpVerifyInfo struct {
|
|||||||
|
|
||||||
// OTP双因素校验
|
// OTP双因素校验
|
||||||
func (a *AccountLogin) OtpVerify(rc *req.Ctx) {
|
func (a *AccountLogin) OtpVerify(rc *req.Ctx) {
|
||||||
otpVerify := new(form.OtpVerfiy)
|
otpVerify := req.BindJsonAndValid[*form.OtpVerfiy](rc)
|
||||||
req.BindJsonAndValid(rc, otpVerify)
|
|
||||||
ctx := rc.MetaCtx
|
ctx := rc.MetaCtx
|
||||||
|
|
||||||
tokenKey := fmt.Sprintf("otp:token:%s", otpVerify.OtpToken)
|
tokenKey := fmt.Sprintf("otp:token:%s", otpVerify.OtpToken)
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ func (a *LdapLogin) GetLdapEnabled(rc *req.Ctx) {
|
|||||||
|
|
||||||
// @router /auth/ldap/login [post]
|
// @router /auth/ldap/login [post]
|
||||||
func (a *LdapLogin) Login(rc *req.Ctx) {
|
func (a *LdapLogin) Login(rc *req.Ctx) {
|
||||||
loginForm := req.BindJsonAndValid(rc, new(form.LoginForm))
|
loginForm := req.BindJsonAndValid[*form.LoginForm](rc)
|
||||||
ctx := rc.MetaCtx
|
ctx := rc.MetaCtx
|
||||||
accountLoginSecurity := config.GetAccountLoginSecurity()
|
accountLoginSecurity := config.GetAccountLoginSecurity()
|
||||||
// 判断是否有开启登录验证码校验
|
// 判断是否有开启登录验证码校验
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ func (d *Db) ReqConfs() *req.Confs {
|
|||||||
|
|
||||||
// @router /api/dbs [get]
|
// @router /api/dbs [get]
|
||||||
func (d *Db) Dbs(rc *req.Ctx) {
|
func (d *Db) Dbs(rc *req.Ctx) {
|
||||||
queryCond := req.BindQuery[*entity.DbQuery](rc, new(entity.DbQuery))
|
queryCond := req.BindQuery[*entity.DbQuery](rc)
|
||||||
|
|
||||||
// 不存在可访问标签id,即没有可操作数据
|
// 不存在可访问标签id,即没有可操作数据
|
||||||
tags := d.tagApp.GetAccountTags(rc.GetLoginAccount().Id, &tagentity.TagTreeQuery{
|
tags := d.tagApp.GetAccountTags(rc.GetLoginAccount().Id, &tagentity.TagTreeQuery{
|
||||||
@@ -115,9 +115,7 @@ func (d *Db) Dbs(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *Db) Save(rc *req.Ctx) {
|
func (d *Db) Save(rc *req.Ctx) {
|
||||||
form := &form.DbForm{}
|
form, db := req.BindJsonAndCopyTo[*form.DbForm, *entity.Db](rc)
|
||||||
db := req.BindJsonAndCopyTo[*entity.Db](rc, form, new(entity.Db))
|
|
||||||
|
|
||||||
rc.ReqParam = form
|
rc.ReqParam = form
|
||||||
|
|
||||||
biz.ErrIsNil(d.dbApp.SaveDb(rc.MetaCtx, db))
|
biz.ErrIsNil(d.dbApp.SaveDb(rc.MetaCtx, db))
|
||||||
@@ -137,7 +135,7 @@ func (d *Db) DeleteDb(rc *req.Ctx) {
|
|||||||
/** 数据库操作相关、执行sql等 ***/
|
/** 数据库操作相关、执行sql等 ***/
|
||||||
|
|
||||||
func (d *Db) ExecSql(rc *req.Ctx) {
|
func (d *Db) ExecSql(rc *req.Ctx) {
|
||||||
form := req.BindJsonAndValid(rc, new(form.DbSqlExecForm))
|
form := req.BindJsonAndValid[*form.DbSqlExecForm](rc)
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(rc.MetaCtx, time.Duration(config.GetDbms().SqlExecTl)*time.Second)
|
ctx, cancel := context.WithTimeout(rc.MetaCtx, time.Duration(config.GetDbms().SqlExecTl)*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
@@ -351,8 +349,7 @@ func (d *Db) GetSchemas(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *Db) CopyTable(rc *req.Ctx) {
|
func (d *Db) CopyTable(rc *req.Ctx) {
|
||||||
form := &form.DbCopyTableForm{}
|
form, copy := req.BindJsonAndCopyTo[*form.DbCopyTableForm, *dbi.DbCopyTable](rc)
|
||||||
copy := req.BindJsonAndCopyTo[*dbi.DbCopyTable](rc, form, new(dbi.DbCopyTable))
|
|
||||||
|
|
||||||
conn, err := d.dbApp.GetDbConn(rc.MetaCtx, form.Id, form.Db)
|
conn, err := d.dbApp.GetDbConn(rc.MetaCtx, form.Id, form.Db)
|
||||||
biz.ErrIsNilAppendErr(err, "copy table error: %s")
|
biz.ErrIsNilAppendErr(err, "copy table error: %s")
|
||||||
|
|||||||
@@ -50,22 +50,21 @@ func (d *DataSyncTask) ReqConfs() *req.Confs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *DataSyncTask) Tasks(rc *req.Ctx) {
|
func (d *DataSyncTask) Tasks(rc *req.Ctx) {
|
||||||
queryCond := req.BindQuery[*entity.DataSyncTaskQuery](rc, new(entity.DataSyncTaskQuery))
|
queryCond := req.BindQuery[*entity.DataSyncTaskQuery](rc)
|
||||||
res, err := d.dataSyncTaskApp.GetPageList(queryCond)
|
res, err := d.dataSyncTaskApp.GetPageList(queryCond)
|
||||||
biz.ErrIsNil(err)
|
biz.ErrIsNil(err)
|
||||||
rc.ResData = model.PageResultConv[*entity.DataSyncTask, *vo.DataSyncTaskListVO](res)
|
rc.ResData = model.PageResultConv[*entity.DataSyncTask, *vo.DataSyncTaskListVO](res)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DataSyncTask) Logs(rc *req.Ctx) {
|
func (d *DataSyncTask) Logs(rc *req.Ctx) {
|
||||||
queryCond := req.BindQuery(rc, new(entity.DataSyncLogQuery))
|
queryCond := req.BindQuery[*entity.DataSyncLogQuery](rc)
|
||||||
res, err := d.dataSyncTaskApp.GetTaskLogList(queryCond)
|
res, err := d.dataSyncTaskApp.GetTaskLogList(queryCond)
|
||||||
biz.ErrIsNil(err)
|
biz.ErrIsNil(err)
|
||||||
rc.ResData = model.PageResultConv[*entity.DataSyncLog, *vo.DataSyncLogListVO](res)
|
rc.ResData = model.PageResultConv[*entity.DataSyncLog, *vo.DataSyncLogListVO](res)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DataSyncTask) SaveTask(rc *req.Ctx) {
|
func (d *DataSyncTask) SaveTask(rc *req.Ctx) {
|
||||||
form := &form.DataSyncTaskForm{}
|
form, task := req.BindJsonAndCopyTo[*form.DataSyncTaskForm, *entity.DataSyncTask](rc)
|
||||||
task := req.BindJsonAndCopyTo[*entity.DataSyncTask](rc, form, new(entity.DataSyncTask))
|
|
||||||
|
|
||||||
// 解码base64 sql
|
// 解码base64 sql
|
||||||
sqlStr, err := utils.AesDecryptByLa(task.DataSql, rc.GetLoginAccount())
|
sqlStr, err := utils.AesDecryptByLa(task.DataSql, rc.GetLoginAccount())
|
||||||
@@ -89,8 +88,7 @@ func (d *DataSyncTask) DeleteTask(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *DataSyncTask) ChangeStatus(rc *req.Ctx) {
|
func (d *DataSyncTask) ChangeStatus(rc *req.Ctx) {
|
||||||
form := &form.DataSyncTaskStatusForm{}
|
form, task := req.BindJsonAndCopyTo[*form.DataSyncTaskStatusForm, *entity.DataSyncTask](rc)
|
||||||
task := req.BindJsonAndCopyTo[*entity.DataSyncTask](rc, form, new(entity.DataSyncTask))
|
|
||||||
_ = d.dataSyncTaskApp.UpdateById(rc.MetaCtx, task)
|
_ = d.dataSyncTaskApp.UpdateById(rc.MetaCtx, task)
|
||||||
|
|
||||||
if task.Status == entity.DataSyncTaskStatusEnable {
|
if task.Status == entity.DataSyncTaskStatusEnable {
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ func (d *Instance) ReqConfs() *req.Confs {
|
|||||||
// Instances 获取数据库实例信息
|
// Instances 获取数据库实例信息
|
||||||
// @router /api/instances [get]
|
// @router /api/instances [get]
|
||||||
func (d *Instance) Instances(rc *req.Ctx) {
|
func (d *Instance) Instances(rc *req.Ctx) {
|
||||||
queryCond := req.BindQuery(rc, new(entity.InstanceQuery))
|
queryCond := req.BindQuery[*entity.InstanceQuery](rc)
|
||||||
|
|
||||||
tags := d.tagApp.GetAccountTags(rc.GetLoginAccount().Id, &tagentity.TagTreeQuery{
|
tags := d.tagApp.GetAccountTags(rc.GetLoginAccount().Id, &tagentity.TagTreeQuery{
|
||||||
TypePaths: collx.AsArray(tagentity.NewTypePaths(tagentity.TagTypeDbInstance, tagentity.TagTypeAuthCert)),
|
TypePaths: collx.AsArray(tagentity.NewTypePaths(tagentity.TagTypeDbInstance, tagentity.TagTypeAuthCert)),
|
||||||
@@ -90,17 +90,14 @@ func (d *Instance) Instances(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *Instance) TestConn(rc *req.Ctx) {
|
func (d *Instance) TestConn(rc *req.Ctx) {
|
||||||
form := &form.InstanceForm{}
|
form, instance := req.BindJsonAndCopyTo[*form.InstanceForm, *entity.DbInstance](rc)
|
||||||
instance := req.BindJsonAndCopyTo[*entity.DbInstance](rc, form, new(entity.DbInstance))
|
|
||||||
|
|
||||||
biz.ErrIsNil(d.instanceApp.TestConn(rc.MetaCtx, instance, form.AuthCerts[0]))
|
biz.ErrIsNil(d.instanceApp.TestConn(rc.MetaCtx, instance, form.AuthCerts[0]))
|
||||||
}
|
}
|
||||||
|
|
||||||
// SaveInstance 保存数据库实例信息
|
// SaveInstance 保存数据库实例信息
|
||||||
// @router /api/instances [post]
|
// @router /api/instances [post]
|
||||||
func (d *Instance) SaveInstance(rc *req.Ctx) {
|
func (d *Instance) SaveInstance(rc *req.Ctx) {
|
||||||
form := &form.InstanceForm{}
|
form, instance := req.BindJsonAndCopyTo[*form.InstanceForm, *entity.DbInstance](rc)
|
||||||
instance := req.BindJsonAndCopyTo[*entity.DbInstance](rc, form, new(entity.DbInstance))
|
|
||||||
|
|
||||||
rc.ReqParam = form
|
rc.ReqParam = form
|
||||||
id, err := d.instanceApp.SaveDbInstance(rc.MetaCtx, &dto.SaveDbInstance{
|
id, err := d.instanceApp.SaveDbInstance(rc.MetaCtx, &dto.SaveDbInstance{
|
||||||
@@ -135,8 +132,7 @@ func (d *Instance) DeleteInstance(rc *req.Ctx) {
|
|||||||
|
|
||||||
// 获取数据库实例的所有数据库名
|
// 获取数据库实例的所有数据库名
|
||||||
func (d *Instance) GetDatabaseNames(rc *req.Ctx) {
|
func (d *Instance) GetDatabaseNames(rc *req.Ctx) {
|
||||||
form := &form.InstanceDbNamesForm{}
|
form, instance := req.BindJsonAndCopyTo[*form.InstanceDbNamesForm, *entity.DbInstance](rc)
|
||||||
instance := req.BindJsonAndCopyTo[*entity.DbInstance](rc, form, new(entity.DbInstance))
|
|
||||||
res, err := d.instanceApp.GetDatabases(rc.MetaCtx, instance, form.AuthCert)
|
res, err := d.instanceApp.GetDatabases(rc.MetaCtx, instance, form.AuthCert)
|
||||||
biz.ErrIsNil(err)
|
biz.ErrIsNil(err)
|
||||||
rc.ResData = res
|
rc.ResData = res
|
||||||
|
|||||||
@@ -30,8 +30,7 @@ func (d *DbSql) ReqConfs() *req.Confs {
|
|||||||
|
|
||||||
// @router /api/db/:dbId/sql [post]
|
// @router /api/db/:dbId/sql [post]
|
||||||
func (d *DbSql) SaveSql(rc *req.Ctx) {
|
func (d *DbSql) SaveSql(rc *req.Ctx) {
|
||||||
dbSqlForm := &form.DbSqlSaveForm{}
|
dbSqlForm := req.BindJsonAndValid[*form.DbSqlSaveForm](rc)
|
||||||
req.BindJsonAndValid(rc, dbSqlForm)
|
|
||||||
rc.ReqParam = dbSqlForm
|
rc.ReqParam = dbSqlForm
|
||||||
|
|
||||||
dbId := getDbId(rc)
|
dbId := getDbId(rc)
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ func (d *DbSqlExec) ReqConfs() *req.Confs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *DbSqlExec) DbSqlExecs(rc *req.Ctx) {
|
func (d *DbSqlExec) DbSqlExecs(rc *req.Ctx) {
|
||||||
queryCond := req.BindQuery(rc, new(entity.DbSqlExecQuery))
|
queryCond := req.BindQuery[*entity.DbSqlExecQuery](rc)
|
||||||
if statusStr := rc.Query("status"); statusStr != "" {
|
if statusStr := rc.Query("status"); statusStr != "" {
|
||||||
queryCond.Status = collx.ArrayMap[string, int8](strings.Split(statusStr, ","), func(val string) int8 {
|
queryCond.Status = collx.ArrayMap[string, int8](strings.Split(statusStr, ","), func(val string) int8 {
|
||||||
return cast.ToInt8(val)
|
return cast.ToInt8(val)
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ func (d *DbTransferTask) ReqConfs() *req.Confs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *DbTransferTask) Tasks(rc *req.Ctx) {
|
func (d *DbTransferTask) Tasks(rc *req.Ctx) {
|
||||||
queryCond := req.BindQuery(rc, new(entity.DbTransferTaskQuery))
|
queryCond := req.BindQuery[*entity.DbTransferTaskQuery](rc)
|
||||||
|
|
||||||
res, err := d.dbTransferTask.GetPageList(queryCond)
|
res, err := d.dbTransferTask.GetPageList(queryCond)
|
||||||
biz.ErrIsNil(err)
|
biz.ErrIsNil(err)
|
||||||
@@ -78,8 +78,7 @@ func (d *DbTransferTask) Tasks(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *DbTransferTask) SaveTask(rc *req.Ctx) {
|
func (d *DbTransferTask) SaveTask(rc *req.Ctx) {
|
||||||
reqForm := &form.DbTransferTaskForm{}
|
reqForm, task := req.BindJsonAndCopyTo[*form.DbTransferTaskForm, *entity.DbTransferTask](rc)
|
||||||
task := req.BindJsonAndCopyTo[*entity.DbTransferTask](rc, reqForm, new(entity.DbTransferTask))
|
|
||||||
|
|
||||||
rc.ReqParam = reqForm
|
rc.ReqParam = reqForm
|
||||||
biz.ErrIsNil(d.dbTransferTask.Save(rc.MetaCtx, task))
|
biz.ErrIsNil(d.dbTransferTask.Save(rc.MetaCtx, task))
|
||||||
@@ -98,8 +97,7 @@ func (d *DbTransferTask) DeleteTask(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *DbTransferTask) ChangeStatus(rc *req.Ctx) {
|
func (d *DbTransferTask) ChangeStatus(rc *req.Ctx) {
|
||||||
form := &form.DbTransferTaskStatusForm{}
|
form, task := req.BindJsonAndCopyTo[*form.DbTransferTaskStatusForm, *entity.DbTransferTask](rc)
|
||||||
task := req.BindJsonAndCopyTo[*entity.DbTransferTask](rc, form, new(entity.DbTransferTask))
|
|
||||||
_ = d.dbTransferTask.UpdateById(rc.MetaCtx, task)
|
_ = d.dbTransferTask.UpdateById(rc.MetaCtx, task)
|
||||||
|
|
||||||
task, err := d.dbTransferTask.GetById(task.Id)
|
task, err := d.dbTransferTask.GetById(task.Id)
|
||||||
@@ -122,7 +120,7 @@ func (d *DbTransferTask) Stop(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *DbTransferTask) Files(rc *req.Ctx) {
|
func (d *DbTransferTask) Files(rc *req.Ctx) {
|
||||||
queryCond := req.BindQuery(rc, new(entity.DbTransferFileQuery))
|
queryCond := req.BindQuery[*entity.DbTransferFileQuery](rc)
|
||||||
|
|
||||||
res, err := d.dbTransferFile.GetPageList(queryCond)
|
res, err := d.dbTransferFile.GetPageList(queryCond)
|
||||||
biz.ErrIsNil(err)
|
biz.ErrIsNil(err)
|
||||||
@@ -142,7 +140,7 @@ func (d *DbTransferTask) FileDel(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *DbTransferTask) FileRun(rc *req.Ctx) {
|
func (d *DbTransferTask) FileRun(rc *req.Ctx) {
|
||||||
fm := req.BindJsonAndValid(rc, &form.DbTransferFileRunForm{})
|
fm := req.BindJsonAndValid[*form.DbTransferFileRunForm](rc)
|
||||||
|
|
||||||
rc.ReqParam = fm
|
rc.ReqParam = fm
|
||||||
|
|
||||||
|
|||||||
@@ -277,7 +277,7 @@ func (d *dbSqlExecAppImpl) FlowBizHandle(ctx context.Context, bizHandleParam *fl
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
execSqlBizForm, err := jsonx.To(procinst.BizForm, new(FlowDbExecSqlBizForm))
|
execSqlBizForm, err := jsonx.To[*FlowDbExecSqlBizForm](procinst.BizForm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errorx.NewBiz("failed to parse the business form information: %s", err.Error())
|
return nil, errorx.NewBiz("failed to parse the business form information: %s", err.Error())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ func (d *Instance) ReqConfs() *req.Confs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *Instance) Instances(rc *req.Ctx) {
|
func (d *Instance) Instances(rc *req.Ctx) {
|
||||||
queryCond := req.BindQuery(rc, new(entity.InstanceQuery))
|
queryCond := req.BindQuery[*entity.InstanceQuery](rc)
|
||||||
|
|
||||||
// 只查询实例,兼容没有录入密码的实例
|
// 只查询实例,兼容没有录入密码的实例
|
||||||
instTags := d.tagApp.GetAccountTags(rc.GetLoginAccount().Id, &tagentity.TagTreeQuery{
|
instTags := d.tagApp.GetAccountTags(rc.GetLoginAccount().Id, &tagentity.TagTreeQuery{
|
||||||
@@ -92,8 +92,7 @@ func (d *Instance) Instances(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *Instance) TestConn(rc *req.Ctx) {
|
func (d *Instance) TestConn(rc *req.Ctx) {
|
||||||
fm := &form.InstanceForm{}
|
fm, instance := req.BindJsonAndCopyTo[*form.InstanceForm, *entity.EsInstance](rc)
|
||||||
instance := req.BindJsonAndCopyTo[*entity.EsInstance](rc, fm, new(entity.EsInstance))
|
|
||||||
|
|
||||||
var ac *tagentity.ResourceAuthCert
|
var ac *tagentity.ResourceAuthCert
|
||||||
if len(fm.AuthCerts) > 0 {
|
if len(fm.AuthCerts) > 0 {
|
||||||
@@ -105,8 +104,7 @@ func (d *Instance) TestConn(rc *req.Ctx) {
|
|||||||
rc.ResData = res
|
rc.ResData = res
|
||||||
}
|
}
|
||||||
func (d *Instance) SaveInstance(rc *req.Ctx) {
|
func (d *Instance) SaveInstance(rc *req.Ctx) {
|
||||||
fm := &form.InstanceForm{}
|
fm, instance := req.BindJsonAndCopyTo[*form.InstanceForm, *entity.EsInstance](rc)
|
||||||
instance := req.BindJsonAndCopyTo[*entity.EsInstance](rc, fm, new(entity.EsInstance))
|
|
||||||
|
|
||||||
rc.ReqParam = fm
|
rc.ReqParam = fm
|
||||||
id, err := d.inst.SaveInst(rc.MetaCtx, &dto.SaveEsInstance{
|
id, err := d.inst.SaveInst(rc.MetaCtx, &dto.SaveEsInstance{
|
||||||
|
|||||||
@@ -5,13 +5,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type InstanceForm struct {
|
type InstanceForm struct {
|
||||||
Id uint64 `json:"id"`
|
Id uint64 `json:"id"`
|
||||||
Name string `binding:"required" json:"name"`
|
Name string `binding:"required" json:"name"`
|
||||||
Host string `binding:"required" json:"host"`
|
Host string `binding:"required" json:"host"`
|
||||||
Port int `binding:"required" json:"port"`
|
Port int `binding:"required" json:"port"`
|
||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
Remark string `json:"remark"`
|
Remark *string `json:"remark"`
|
||||||
SshTunnelMachineId int `json:"sshTunnelMachineId"`
|
SshTunnelMachineId int `json:"sshTunnelMachineId"`
|
||||||
|
|
||||||
AuthCerts []*tagentity.ResourceAuthCert `json:"authCerts"` // 资产授权凭证信息列表
|
AuthCerts []*tagentity.ResourceAuthCert `json:"authCerts"` // 资产授权凭证信息列表
|
||||||
TagCodePaths []string `binding:"required" json:"tagCodePaths"`
|
TagCodePaths []string `binding:"required" json:"tagCodePaths"`
|
||||||
|
|||||||
@@ -9,16 +9,17 @@ type InstanceListVO struct {
|
|||||||
tagentity.AuthCerts // 授权凭证信息
|
tagentity.AuthCerts // 授权凭证信息
|
||||||
tagentity.ResourceTags
|
tagentity.ResourceTags
|
||||||
|
|
||||||
Id *int64 `json:"id"`
|
Id *int64 `json:"id"`
|
||||||
Code string `json:"code"`
|
Code string `json:"code"`
|
||||||
Name *string `json:"name"`
|
Name *string `json:"name"`
|
||||||
Host *string `json:"host"`
|
Host *string `json:"host"`
|
||||||
Port *int `json:"port"`
|
Port *int `json:"port"`
|
||||||
Version *string `json:"version"`
|
Version *string `json:"version"`
|
||||||
|
Remark *string `json:"remark"`
|
||||||
|
|
||||||
CreateTime *time.Time `json:"createTime"`
|
CreateTime *time.Time `json:"createTime"`
|
||||||
Creator *string `json:"creator"`
|
Creator *string `json:"creator"`
|
||||||
CreatorId *int64 `json:"creatorId"`
|
CreatorId *int64 `json:"creatorId"`
|
||||||
|
|
||||||
UpdateTime *time.Time `json:"updateTime"`
|
UpdateTime *time.Time `json:"updateTime"`
|
||||||
Modifier *string `json:"modifier"`
|
Modifier *string `json:"modifier"`
|
||||||
ModifierId *int64 `json:"modifierId"`
|
ModifierId *int64 `json:"modifierId"`
|
||||||
|
|||||||
@@ -8,14 +8,14 @@ import (
|
|||||||
type EsInstance struct {
|
type EsInstance struct {
|
||||||
model.Model
|
model.Model
|
||||||
|
|
||||||
Code string `json:"code" gorm:"size:32;not null;"`
|
Code string `json:"code" gorm:"size:32;not null;"`
|
||||||
Name string `json:"name" gorm:"size:32;not null;"`
|
Name string `json:"name" gorm:"size:32;not null;"`
|
||||||
Host string `json:"host" gorm:"size:255;not null;"`
|
Host string `json:"host" gorm:"size:255;not null;"`
|
||||||
Port int `json:"port"`
|
Port int `json:"port"`
|
||||||
Network string `json:"network" gorm:"size:20;"`
|
Network string `json:"network" gorm:"size:20;"`
|
||||||
Version string `json:"version" gorm:"size:50;"`
|
Version string `json:"version" gorm:"size:50;"`
|
||||||
AuthCertName string `json:"authCertName" gorm:"size:255;"`
|
Remark *string `json:"remark" gorm:"size:255;"`
|
||||||
SshTunnelMachineId int `json:"sshTunnelMachineId"` // ssh隧道机器id
|
SshTunnelMachineId int `json:"sshTunnelMachineId"` // ssh隧道机器id
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *EsInstance) TableName() string {
|
func (d *EsInstance) TableName() string {
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ func (p *Procdef) ReqConfs() *req.Confs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *Procdef) GetProcdefPage(rc *req.Ctx) {
|
func (p *Procdef) GetProcdefPage(rc *req.Ctx) {
|
||||||
cond, page := req.BindQueryAndPage(rc, new(entity.Procdef))
|
cond, page := req.BindQueryAndPage[*entity.Procdef](rc)
|
||||||
|
|
||||||
res, err := p.procdefApp.GetPageList(cond, page)
|
res, err := p.procdefApp.GetPageList(cond, page)
|
||||||
biz.ErrIsNil(err)
|
biz.ErrIsNil(err)
|
||||||
@@ -87,8 +87,7 @@ func (p *Procdef) GetProcdef(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *Procdef) Save(rc *req.Ctx) {
|
func (a *Procdef) Save(rc *req.Ctx) {
|
||||||
form := &form.Procdef{}
|
form, procdef := req.BindJsonAndCopyTo[*form.Procdef, *entity.Procdef](rc)
|
||||||
procdef := req.BindJsonAndCopyTo(rc, form, new(entity.Procdef))
|
|
||||||
rc.ReqParam = form
|
rc.ReqParam = form
|
||||||
biz.ErrIsNil(a.procdefApp.SaveProcdef(rc.MetaCtx, &dto.SaveProcdef{
|
biz.ErrIsNil(a.procdefApp.SaveProcdef(rc.MetaCtx, &dto.SaveProcdef{
|
||||||
Procdef: procdef,
|
Procdef: procdef,
|
||||||
@@ -98,7 +97,7 @@ func (a *Procdef) Save(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *Procdef) SaveFlowDef(rc *req.Ctx) {
|
func (a *Procdef) SaveFlowDef(rc *req.Ctx) {
|
||||||
form := req.BindJsonAndValid(rc, &form.ProcdefFlow{})
|
form := req.BindJsonAndValid[*form.ProcdefFlow](rc)
|
||||||
rc.ReqParam = form
|
rc.ReqParam = form
|
||||||
|
|
||||||
biz.ErrIsNil(a.procdefApp.SaveFlowDef(rc.MetaCtx, &dto.SaveFlowDef{
|
biz.ErrIsNil(a.procdefApp.SaveFlowDef(rc.MetaCtx, &dto.SaveFlowDef{
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ func (p *Procinst) ReqConfs() *req.Confs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *Procinst) GetProcinstPage(rc *req.Ctx) {
|
func (p *Procinst) GetProcinstPage(rc *req.Ctx) {
|
||||||
cond := req.BindQuery(rc, new(entity.ProcinstQuery))
|
cond := req.BindQuery[*entity.ProcinstQuery](rc)
|
||||||
// 非管理员只能获取自己申请的流程
|
// 非管理员只能获取自己申请的流程
|
||||||
if laId := rc.GetLoginAccount().Id; laId != consts.AdminId {
|
if laId := rc.GetLoginAccount().Id; laId != consts.AdminId {
|
||||||
cond.CreatorId = laId
|
cond.CreatorId = laId
|
||||||
@@ -47,8 +47,7 @@ func (p *Procinst) GetProcinstPage(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *Procinst) ProcinstStart(rc *req.Ctx) {
|
func (p *Procinst) ProcinstStart(rc *req.Ctx) {
|
||||||
startForm := new(form.ProcinstStart)
|
startForm := req.BindJsonAndValid[*form.ProcinstStart](rc)
|
||||||
req.BindJsonAndValid(rc, startForm)
|
|
||||||
_, err := p.procinstApp.StartProc(rc.MetaCtx, startForm.ProcdefId, &dto.StarProc{
|
_, err := p.procinstApp.StartProc(rc.MetaCtx, startForm.ProcdefId, &dto.StarProc{
|
||||||
BizType: startForm.BizType,
|
BizType: startForm.BizType,
|
||||||
BizForm: jsonx.ToStr(startForm.BizForm),
|
BizForm: jsonx.ToStr(startForm.BizForm),
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ func (p *ProcinstTask) ReqConfs() *req.Confs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *ProcinstTask) GetTasks(rc *req.Ctx) {
|
func (p *ProcinstTask) GetTasks(rc *req.Ctx) {
|
||||||
instTaskQuery := req.BindQuery(rc, new(entity.ProcinstTaskQuery))
|
instTaskQuery := req.BindQuery[*entity.ProcinstTaskQuery](rc)
|
||||||
if laId := rc.GetLoginAccount().Id; laId != consts.AdminId {
|
if laId := rc.GetLoginAccount().Id; laId != consts.AdminId {
|
||||||
// 赋值操作人为当前登录账号
|
// 赋值操作人为当前登录账号
|
||||||
instTaskQuery.Assignee = fmt.Sprintf("%d", rc.GetLoginAccount().Id)
|
instTaskQuery.Assignee = fmt.Sprintf("%d", rc.GetLoginAccount().Id)
|
||||||
@@ -74,7 +74,7 @@ func (p *ProcinstTask) GetTasks(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *ProcinstTask) PassTask(rc *req.Ctx) {
|
func (p *ProcinstTask) PassTask(rc *req.Ctx) {
|
||||||
auditForm := req.BindJsonAndValid(rc, new(form.ProcinstTaskAudit))
|
auditForm := req.BindJsonAndValid[*form.ProcinstTaskAudit](rc)
|
||||||
rc.ReqParam = auditForm
|
rc.ReqParam = auditForm
|
||||||
|
|
||||||
la := rc.GetLoginAccount()
|
la := rc.GetLoginAccount()
|
||||||
@@ -84,7 +84,7 @@ func (p *ProcinstTask) PassTask(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *ProcinstTask) RejectTask(rc *req.Ctx) {
|
func (p *ProcinstTask) RejectTask(rc *req.Ctx) {
|
||||||
auditForm := req.BindJsonAndValid(rc, new(form.ProcinstTaskAudit))
|
auditForm := req.BindJsonAndValid[*form.ProcinstTaskAudit](rc)
|
||||||
rc.ReqParam = auditForm
|
rc.ReqParam = auditForm
|
||||||
|
|
||||||
la := rc.GetLoginAccount()
|
la := rc.GetLoginAccount()
|
||||||
@@ -94,7 +94,7 @@ func (p *ProcinstTask) RejectTask(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *ProcinstTask) BackTask(rc *req.Ctx) {
|
func (p *ProcinstTask) BackTask(rc *req.Ctx) {
|
||||||
auditForm := req.BindJsonAndValid(rc, new(form.ProcinstTaskAudit))
|
auditForm := req.BindJsonAndValid[*form.ProcinstTaskAudit](rc)
|
||||||
rc.ReqParam = auditForm
|
rc.ReqParam = auditForm
|
||||||
biz.ErrIsNil(p.procinstTaskApp.BackTask(rc.MetaCtx, dto.UserTaskOp{TaskId: auditForm.Id, Remark: auditForm.Remark}))
|
biz.ErrIsNil(p.procinstTaskApp.BackTask(rc.MetaCtx, dto.UserTaskOp{TaskId: auditForm.Id, Remark: auditForm.Remark}))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,7 +104,9 @@ func (e *executionAppImpl) MoveTo(ctx *ExecutionCtx, nextNode *entity.FlowNode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 记录当前节点结束
|
// 记录当前节点结束
|
||||||
e.hisProcinstOpApp.RecordEnd(ctx, "copmpleted")
|
if err := e.hisProcinstOpApp.RecordEnd(ctx, "copmpleted"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// 下一个节点为空,说明流程已结束
|
// 下一个节点为空,说明流程已结束
|
||||||
if nextNode == nil {
|
if nextNode == nil {
|
||||||
@@ -163,7 +165,9 @@ func (e *executionAppImpl) executeNode(ctx *ExecutionCtx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 节点开始操作记录
|
// 节点开始操作记录
|
||||||
e.hisProcinstOpApp.RecordStart(ctx)
|
if err := e.hisProcinstOpApp.RecordStart(ctx); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// 执行节点逻辑
|
// 执行节点逻辑
|
||||||
return node.Execute(ctx)
|
return node.Execute(ctx)
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ func (p *Procdef) GetFlowDef() *FlowDef {
|
|||||||
if p.FlowDef == "" {
|
if p.FlowDef == "" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
flow, err := jsonx.To(p.FlowDef, new(FlowDef))
|
flow, err := jsonx.To[*FlowDef](p.FlowDef)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logx.ErrorTrace("parse flow def failed", err)
|
logx.ErrorTrace("parse flow def failed", err)
|
||||||
return flow
|
return flow
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ func (a *Procinst) SetEnd() {
|
|||||||
|
|
||||||
// GetProcdefFlow 获取流程定义信息
|
// GetProcdefFlow 获取流程定义信息
|
||||||
func (p *Procinst) GetFlowDef() *FlowDef {
|
func (p *Procinst) GetFlowDef() *FlowDef {
|
||||||
flow, err := jsonx.To(p.FlowDef, new(FlowDef))
|
flow, err := jsonx.To[*FlowDef](p.FlowDef)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logx.ErrorTrace("parse procdef flow failed", err)
|
logx.ErrorTrace("parse procdef flow failed", err)
|
||||||
return flow
|
return flow
|
||||||
|
|||||||
@@ -50,12 +50,12 @@ type MachineCronJobForm struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type MachineCmdConfForm struct {
|
type MachineCmdConfForm struct {
|
||||||
Id uint64 `json:"id"`
|
Id uint64 `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Cmds []string `json:"cmds"` // 命令配置
|
Cmds model.Slice[string] `json:"cmds"` // 命令配置
|
||||||
Status int8 `json:"execCmds"` // 状态
|
Status int8 `json:"execCmds"` // 状态
|
||||||
Stratege string `json:"stratege"` // 策略,空禁用
|
Stratege string `json:"stratege"` // 策略,空禁用
|
||||||
Remark string `json:"remark"` // 备注
|
Remark string `json:"remark"` // 备注
|
||||||
|
|
||||||
CodePaths []string `json:"codePaths"`
|
CodePaths []string `json:"codePaths"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ func (m *Machine) ReqConfs() *req.Confs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Machine) Machines(rc *req.Ctx) {
|
func (m *Machine) Machines(rc *req.Ctx) {
|
||||||
condition := req.BindQuery(rc, new(entity.MachineQuery))
|
condition := req.BindQuery[*entity.MachineQuery](rc)
|
||||||
|
|
||||||
tags := m.tagTreeApp.GetAccountTags(rc.GetLoginAccount().Id, &tagentity.TagTreeQuery{
|
tags := m.tagTreeApp.GetAccountTags(rc.GetLoginAccount().Id, &tagentity.TagTreeQuery{
|
||||||
TypePaths: collx.AsArray(tagentity.NewTypePaths(tagentity.TagTypeMachine, tagentity.TagTypeAuthCert)),
|
TypePaths: collx.AsArray(tagentity.NewTypePaths(tagentity.TagTypeMachine, tagentity.TagTypeAuthCert)),
|
||||||
@@ -143,8 +143,7 @@ func (m *Machine) MachineStats(rc *req.Ctx) {
|
|||||||
|
|
||||||
// 保存机器信息
|
// 保存机器信息
|
||||||
func (m *Machine) SaveMachine(rc *req.Ctx) {
|
func (m *Machine) SaveMachine(rc *req.Ctx) {
|
||||||
machineForm := new(form.MachineForm)
|
machineForm, me := req.BindJsonAndCopyTo[*form.MachineForm, *entity.Machine](rc)
|
||||||
me := req.BindJsonAndCopyTo(rc, machineForm, new(entity.Machine))
|
|
||||||
|
|
||||||
rc.ReqParam = machineForm
|
rc.ReqParam = machineForm
|
||||||
|
|
||||||
@@ -156,8 +155,7 @@ func (m *Machine) SaveMachine(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Machine) TestConn(rc *req.Ctx) {
|
func (m *Machine) TestConn(rc *req.Ctx) {
|
||||||
machineForm := new(form.MachineForm)
|
machineForm, me := req.BindJsonAndCopyTo[*form.MachineForm, *entity.Machine](rc)
|
||||||
me := req.BindJsonAndCopyTo(rc, machineForm, new(entity.Machine))
|
|
||||||
// 测试连接
|
// 测试连接
|
||||||
biz.ErrIsNilAppendErr(m.machineApp.TestConn(rc.MetaCtx, me, machineForm.AuthCerts[0]), "connection error: %s")
|
biz.ErrIsNilAppendErr(m.machineApp.TestConn(rc.MetaCtx, me, machineForm.AuthCerts[0]), "connection error: %s")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ func (mcc *MachineCmdConf) ReqConfs() *req.Confs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *MachineCmdConf) MachineCmdConfs(rc *req.Ctx) {
|
func (m *MachineCmdConf) MachineCmdConfs(rc *req.Ctx) {
|
||||||
cond := req.BindQuery(rc, new(entity.MachineCmdConf))
|
cond := req.BindQuery[*entity.MachineCmdConf](rc)
|
||||||
|
|
||||||
var vos []*vo.MachineCmdConfVO
|
var vos []*vo.MachineCmdConfVO
|
||||||
err := m.machineCmdConfApp.ListByCondToAny(cond, &vos)
|
err := m.machineCmdConfApp.ListByCondToAny(cond, &vos)
|
||||||
@@ -47,8 +47,7 @@ func (m *MachineCmdConf) MachineCmdConfs(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *MachineCmdConf) Save(rc *req.Ctx) {
|
func (m *MachineCmdConf) Save(rc *req.Ctx) {
|
||||||
cmdForm := new(form.MachineCmdConfForm)
|
cmdForm, mcj := req.BindJsonAndCopyTo[*form.MachineCmdConfForm, *entity.MachineCmdConf](rc)
|
||||||
mcj := req.BindJsonAndCopyTo[*entity.MachineCmdConf](rc, cmdForm, new(entity.MachineCmdConf))
|
|
||||||
rc.ReqParam = cmdForm
|
rc.ReqParam = cmdForm
|
||||||
|
|
||||||
err := m.machineCmdConfApp.SaveCmdConf(rc.MetaCtx, &dto.SaveMachineCmdConf{
|
err := m.machineCmdConfApp.SaveCmdConf(rc.MetaCtx, &dto.SaveMachineCmdConf{
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ func (mcj *MachineCronJob) ReqConfs() *req.Confs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *MachineCronJob) MachineCronJobs(rc *req.Ctx) {
|
func (m *MachineCronJob) MachineCronJobs(rc *req.Ctx) {
|
||||||
cond, pageParam := req.BindQueryAndPage(rc, new(entity.MachineCronJob))
|
cond, pageParam := req.BindQueryAndPage[*entity.MachineCronJob](rc)
|
||||||
|
|
||||||
pageRes, err := m.machineCronJobApp.GetPageList(cond, pageParam)
|
pageRes, err := m.machineCronJobApp.GetPageList(cond, pageParam)
|
||||||
biz.ErrIsNil(err)
|
biz.ErrIsNil(err)
|
||||||
@@ -62,8 +62,7 @@ func (m *MachineCronJob) MachineCronJobs(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *MachineCronJob) Save(rc *req.Ctx) {
|
func (m *MachineCronJob) Save(rc *req.Ctx) {
|
||||||
jobForm := new(form.MachineCronJobForm)
|
jobForm, mcj := req.BindJsonAndCopyTo[*form.MachineCronJobForm, *entity.MachineCronJob](rc)
|
||||||
mcj := req.BindJsonAndCopyTo[*entity.MachineCronJob](rc, jobForm, new(entity.MachineCronJob))
|
|
||||||
rc.ReqParam = jobForm
|
rc.ReqParam = jobForm
|
||||||
|
|
||||||
err := m.machineCronJobApp.SaveMachineCronJob(rc.MetaCtx, &dto.SaveMachineCronJob{
|
err := m.machineCronJobApp.SaveMachineCronJob(rc.MetaCtx, &dto.SaveMachineCronJob{
|
||||||
@@ -90,7 +89,7 @@ func (m *MachineCronJob) RunCronJob(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *MachineCronJob) CronJobExecs(rc *req.Ctx) {
|
func (m *MachineCronJob) CronJobExecs(rc *req.Ctx) {
|
||||||
cond, pageParam := req.BindQueryAndPage[*entity.MachineCronJobExec](rc, new(entity.MachineCronJobExec))
|
cond, pageParam := req.BindQueryAndPage[*entity.MachineCronJobExec](rc)
|
||||||
res, err := m.machineCronJobApp.GetExecPageList(cond, pageParam)
|
res, err := m.machineCronJobApp.GetExecPageList(cond, pageParam)
|
||||||
biz.ErrIsNil(err)
|
biz.ErrIsNil(err)
|
||||||
rc.ResData = res
|
rc.ResData = res
|
||||||
|
|||||||
@@ -93,8 +93,7 @@ func (m *MachineFile) MachineFiles(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *MachineFile) SaveMachineFiles(rc *req.Ctx) {
|
func (m *MachineFile) SaveMachineFiles(rc *req.Ctx) {
|
||||||
fileForm := new(form.MachineFileForm)
|
fileForm, entity := req.BindJsonAndCopyTo[*form.MachineFileForm, *entity.MachineFile](rc)
|
||||||
entity := req.BindJsonAndCopyTo[*entity.MachineFile](rc, fileForm, new(entity.MachineFile))
|
|
||||||
|
|
||||||
rc.ReqParam = fileForm
|
rc.ReqParam = fileForm
|
||||||
biz.ErrIsNil(m.machineFileApp.Save(rc.MetaCtx, entity))
|
biz.ErrIsNil(m.machineFileApp.Save(rc.MetaCtx, entity))
|
||||||
@@ -107,7 +106,7 @@ func (m *MachineFile) DeleteFile(rc *req.Ctx) {
|
|||||||
/*** sftp相关操作 */
|
/*** sftp相关操作 */
|
||||||
|
|
||||||
func (m *MachineFile) CreateFile(rc *req.Ctx) {
|
func (m *MachineFile) CreateFile(rc *req.Ctx) {
|
||||||
opForm := req.BindJsonAndValid(rc, new(form.CreateFileForm))
|
opForm := req.BindJsonAndValid[*form.CreateFileForm](rc)
|
||||||
path := opForm.Path
|
path := opForm.Path
|
||||||
|
|
||||||
attrs := collx.Kvs("path", path)
|
attrs := collx.Kvs("path", path)
|
||||||
@@ -126,7 +125,7 @@ func (m *MachineFile) CreateFile(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *MachineFile) ReadFileContent(rc *req.Ctx) {
|
func (m *MachineFile) ReadFileContent(rc *req.Ctx) {
|
||||||
opForm := req.BindQuery(rc, new(dto.MachineFileOp))
|
opForm := req.BindQuery[*dto.MachineFileOp](rc)
|
||||||
readPath := opForm.Path
|
readPath := opForm.Path
|
||||||
ctx := rc.MetaCtx
|
ctx := rc.MetaCtx
|
||||||
|
|
||||||
@@ -158,7 +157,7 @@ func (m *MachineFile) ReadFileContent(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *MachineFile) DownloadFile(rc *req.Ctx) {
|
func (m *MachineFile) DownloadFile(rc *req.Ctx) {
|
||||||
opForm := req.BindQuery(rc, new(dto.MachineFileOp))
|
opForm := req.BindQuery[*dto.MachineFileOp](rc)
|
||||||
|
|
||||||
readPath := opForm.Path
|
readPath := opForm.Path
|
||||||
|
|
||||||
@@ -186,7 +185,7 @@ func (m *MachineFile) DownloadFile(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *MachineFile) GetDirEntry(rc *req.Ctx) {
|
func (m *MachineFile) GetDirEntry(rc *req.Ctx) {
|
||||||
opForm := req.BindQuery(rc, new(dto.MachineFileOp))
|
opForm := req.BindQuery[*dto.MachineFileOp](rc)
|
||||||
readPath := opForm.Path
|
readPath := opForm.Path
|
||||||
rc.ReqParam = fmt.Sprintf("path: %s", readPath)
|
rc.ReqParam = fmt.Sprintf("path: %s", readPath)
|
||||||
|
|
||||||
@@ -225,7 +224,7 @@ func (m *MachineFile) GetDirEntry(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *MachineFile) GetDirSize(rc *req.Ctx) {
|
func (m *MachineFile) GetDirSize(rc *req.Ctx) {
|
||||||
opForm := req.BindQuery(rc, new(dto.MachineFileOp))
|
opForm := req.BindQuery[*dto.MachineFileOp](rc)
|
||||||
|
|
||||||
size, err := m.machineFileApp.GetDirSize(rc.MetaCtx, opForm)
|
size, err := m.machineFileApp.GetDirSize(rc.MetaCtx, opForm)
|
||||||
biz.ErrIsNil(err)
|
biz.ErrIsNil(err)
|
||||||
@@ -233,14 +232,14 @@ func (m *MachineFile) GetDirSize(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *MachineFile) GetFileStat(rc *req.Ctx) {
|
func (m *MachineFile) GetFileStat(rc *req.Ctx) {
|
||||||
opForm := req.BindQuery(rc, new(dto.MachineFileOp))
|
opForm := req.BindQuery[*dto.MachineFileOp](rc)
|
||||||
res, err := m.machineFileApp.FileStat(rc.MetaCtx, opForm)
|
res, err := m.machineFileApp.FileStat(rc.MetaCtx, opForm)
|
||||||
biz.ErrIsNil(err, res)
|
biz.ErrIsNil(err, res)
|
||||||
rc.ResData = res
|
rc.ResData = res
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MachineFile) WriteFileContent(rc *req.Ctx) {
|
func (m *MachineFile) WriteFileContent(rc *req.Ctx) {
|
||||||
opForm := req.BindJsonAndValid(rc, new(form.WriteFileContentForm))
|
opForm := req.BindJsonAndValid[*form.WriteFileContentForm](rc)
|
||||||
path := opForm.Path
|
path := opForm.Path
|
||||||
|
|
||||||
mi, err := m.machineFileApp.WriteFileContent(rc.MetaCtx, opForm.MachineFileOp, []byte(opForm.Content))
|
mi, err := m.machineFileApp.WriteFileContent(rc.MetaCtx, opForm.MachineFileOp, []byte(opForm.Content))
|
||||||
@@ -401,7 +400,7 @@ func (m *MachineFile) UploadFolder(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *MachineFile) RemoveFile(rc *req.Ctx) {
|
func (m *MachineFile) RemoveFile(rc *req.Ctx) {
|
||||||
opForm := req.BindJsonAndValid(rc, new(form.RemoveFileForm))
|
opForm := req.BindJsonAndValid[*form.RemoveFileForm](rc)
|
||||||
|
|
||||||
mi, err := m.machineFileApp.RemoveFile(rc.MetaCtx, opForm.MachineFileOp, opForm.Paths...)
|
mi, err := m.machineFileApp.RemoveFile(rc.MetaCtx, opForm.MachineFileOp, opForm.Paths...)
|
||||||
rc.ReqParam = collx.Kvs("machine", mi, "path", opForm)
|
rc.ReqParam = collx.Kvs("machine", mi, "path", opForm)
|
||||||
@@ -409,21 +408,21 @@ func (m *MachineFile) RemoveFile(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *MachineFile) CopyFile(rc *req.Ctx) {
|
func (m *MachineFile) CopyFile(rc *req.Ctx) {
|
||||||
opForm := req.BindJsonAndValid(rc, new(form.CopyFileForm))
|
opForm := req.BindJsonAndValid[*form.CopyFileForm](rc)
|
||||||
mi, err := m.machineFileApp.Copy(rc.MetaCtx, opForm.MachineFileOp, opForm.ToPath, opForm.Paths...)
|
mi, err := m.machineFileApp.Copy(rc.MetaCtx, opForm.MachineFileOp, opForm.ToPath, opForm.Paths...)
|
||||||
biz.ErrIsNilAppendErr(err, "file copy error: %s")
|
biz.ErrIsNilAppendErr(err, "file copy error: %s")
|
||||||
rc.ReqParam = collx.Kvs("machine", mi, "cp", opForm)
|
rc.ReqParam = collx.Kvs("machine", mi, "cp", opForm)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MachineFile) MvFile(rc *req.Ctx) {
|
func (m *MachineFile) MvFile(rc *req.Ctx) {
|
||||||
opForm := req.BindJsonAndValid(rc, new(form.CopyFileForm))
|
opForm := req.BindJsonAndValid[*form.CopyFileForm](rc)
|
||||||
mi, err := m.machineFileApp.Mv(rc.MetaCtx, opForm.MachineFileOp, opForm.ToPath, opForm.Paths...)
|
mi, err := m.machineFileApp.Mv(rc.MetaCtx, opForm.MachineFileOp, opForm.ToPath, opForm.Paths...)
|
||||||
rc.ReqParam = collx.Kvs("machine", mi, "mv", opForm)
|
rc.ReqParam = collx.Kvs("machine", mi, "mv", opForm)
|
||||||
biz.ErrIsNilAppendErr(err, "file move error: %s")
|
biz.ErrIsNilAppendErr(err, "file move error: %s")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MachineFile) Rename(rc *req.Ctx) {
|
func (m *MachineFile) Rename(rc *req.Ctx) {
|
||||||
renameForm := req.BindJsonAndValid(rc, new(form.RenameForm))
|
renameForm := req.BindJsonAndValid[*form.RenameForm](rc)
|
||||||
mi, err := m.machineFileApp.Rename(rc.MetaCtx, renameForm.MachineFileOp, renameForm.Newname)
|
mi, err := m.machineFileApp.Rename(rc.MetaCtx, renameForm.MachineFileOp, renameForm.Newname)
|
||||||
rc.ReqParam = collx.Kvs("machine", mi, "rename", renameForm)
|
rc.ReqParam = collx.Kvs("machine", mi, "rename", renameForm)
|
||||||
biz.ErrIsNilAppendErr(err, "file rename error: %s")
|
biz.ErrIsNilAppendErr(err, "file rename error: %s")
|
||||||
|
|||||||
@@ -46,8 +46,7 @@ func (m *MachineScript) MachineScripts(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *MachineScript) SaveMachineScript(rc *req.Ctx) {
|
func (m *MachineScript) SaveMachineScript(rc *req.Ctx) {
|
||||||
form := new(form.MachineScriptForm)
|
form, machineScript := req.BindJsonAndCopyTo[*form.MachineScriptForm, *entity.MachineScript](rc)
|
||||||
machineScript := req.BindJsonAndCopyTo(rc, form, new(entity.MachineScript))
|
|
||||||
|
|
||||||
rc.ReqParam = form
|
rc.ReqParam = form
|
||||||
biz.ErrIsNil(m.machineScriptApp.Save(rc.MetaCtx, machineScript))
|
biz.ErrIsNil(m.machineScriptApp.Save(rc.MetaCtx, machineScript))
|
||||||
|
|||||||
@@ -111,10 +111,10 @@ type MachineCmdConfVO struct {
|
|||||||
model.Model
|
model.Model
|
||||||
|
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Cmds model.Slice[string] `json:"cmds"` // 命令配置
|
Cmds model.Slice[string] `json:"cmds" gorm:"type:varchar"` // 命令配置,要加gorm标签才会正确解析model.Slice
|
||||||
Status int8 `json:"execCmds"` // 状态
|
Status int8 `json:"execCmds"` // 状态
|
||||||
Stratege string `json:"stratege"` // 策略,空禁用
|
Stratege string `json:"stratege"` // 策略,空禁用
|
||||||
Remark string `json:"remark"` // 备注
|
Remark string `json:"remark"` // 备注
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mcc *MachineCmdConfVO) GetRelateId() uint64 {
|
func (mcc *MachineCmdConfVO) GetRelateId() uint64 {
|
||||||
|
|||||||
@@ -20,5 +20,5 @@ func GetMachineStats(machineId uint64) (*mcm.Stats, error) {
|
|||||||
if cacheStr == "" {
|
if cacheStr == "" {
|
||||||
return nil, errors.New("不存在该值")
|
return nil, errors.New("不存在该值")
|
||||||
}
|
}
|
||||||
return jsonx.To(cacheStr, new(mcm.Stats))
|
return jsonx.To[*mcm.Stats](cacheStr)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ func (ma *Mongo) ReqConfs() *req.Confs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Mongo) Mongos(rc *req.Ctx) {
|
func (m *Mongo) Mongos(rc *req.Ctx) {
|
||||||
queryCond := req.BindQuery(rc, new(entity.MongoQuery))
|
queryCond := req.BindQuery[*entity.MongoQuery](rc)
|
||||||
|
|
||||||
// 不存在可访问标签id,即没有可操作数据
|
// 不存在可访问标签id,即没有可操作数据
|
||||||
tags := m.tagTreeApp.GetAccountTags(rc.GetLoginAccount().Id, &tagentity.TagTreeQuery{
|
tags := m.tagTreeApp.GetAccountTags(rc.GetLoginAccount().Id, &tagentity.TagTreeQuery{
|
||||||
@@ -95,14 +95,12 @@ func (m *Mongo) Mongos(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Mongo) TestConn(rc *req.Ctx) {
|
func (m *Mongo) TestConn(rc *req.Ctx) {
|
||||||
form := &form.Mongo{}
|
_, mongo := req.BindJsonAndCopyTo[*form.Mongo, *entity.Mongo](rc)
|
||||||
mongo := req.BindJsonAndCopyTo[*entity.Mongo](rc, form, new(entity.Mongo))
|
|
||||||
biz.ErrIsNilAppendErr(m.mongoApp.TestConn(mongo), "connection error: %s")
|
biz.ErrIsNilAppendErr(m.mongoApp.TestConn(mongo), "connection error: %s")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Mongo) Save(rc *req.Ctx) {
|
func (m *Mongo) Save(rc *req.Ctx) {
|
||||||
form := &form.Mongo{}
|
form, mongo := req.BindJsonAndCopyTo[*form.Mongo, *entity.Mongo](rc)
|
||||||
mongo := req.BindJsonAndCopyTo[*entity.Mongo](rc, form, new(entity.Mongo))
|
|
||||||
|
|
||||||
// 密码脱敏记录日志
|
// 密码脱敏记录日志
|
||||||
form.Uri = func(str string) string {
|
form.Uri = func(str string) string {
|
||||||
@@ -148,8 +146,7 @@ func (m *Mongo) Collections(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Mongo) RunCommand(rc *req.Ctx) {
|
func (m *Mongo) RunCommand(rc *req.Ctx) {
|
||||||
commandForm := new(form.MongoRunCommand)
|
commandForm := req.BindJsonAndValid[*form.MongoRunCommand](rc)
|
||||||
req.BindJsonAndValid(rc, commandForm)
|
|
||||||
|
|
||||||
conn, err := m.mongoApp.GetMongoConn(rc.MetaCtx, m.GetMongoId(rc))
|
conn, err := m.mongoApp.GetMongoConn(rc.MetaCtx, m.GetMongoId(rc))
|
||||||
biz.ErrIsNil(err)
|
biz.ErrIsNil(err)
|
||||||
@@ -179,7 +176,7 @@ func (m *Mongo) RunCommand(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Mongo) FindCommand(rc *req.Ctx) {
|
func (m *Mongo) FindCommand(rc *req.Ctx) {
|
||||||
commandForm := req.BindJsonAndValid(rc, new(form.MongoFindCommand))
|
commandForm := req.BindJsonAndValid[*form.MongoFindCommand](rc)
|
||||||
|
|
||||||
conn, err := m.mongoApp.GetMongoConn(rc.MetaCtx, m.GetMongoId(rc))
|
conn, err := m.mongoApp.GetMongoConn(rc.MetaCtx, m.GetMongoId(rc))
|
||||||
biz.ErrIsNil(err)
|
biz.ErrIsNil(err)
|
||||||
@@ -214,7 +211,7 @@ func (m *Mongo) FindCommand(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Mongo) UpdateByIdCommand(rc *req.Ctx) {
|
func (m *Mongo) UpdateByIdCommand(rc *req.Ctx) {
|
||||||
commandForm := req.BindJsonAndValid(rc, new(form.MongoUpdateByIdCommand))
|
commandForm := req.BindJsonAndValid[*form.MongoUpdateByIdCommand](rc)
|
||||||
|
|
||||||
conn, err := m.mongoApp.GetMongoConn(rc.MetaCtx, m.GetMongoId(rc))
|
conn, err := m.mongoApp.GetMongoConn(rc.MetaCtx, m.GetMongoId(rc))
|
||||||
biz.ErrIsNil(err)
|
biz.ErrIsNil(err)
|
||||||
@@ -238,7 +235,7 @@ func (m *Mongo) UpdateByIdCommand(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Mongo) DeleteByIdCommand(rc *req.Ctx) {
|
func (m *Mongo) DeleteByIdCommand(rc *req.Ctx) {
|
||||||
commandForm := req.BindJsonAndValid(rc, new(form.MongoUpdateByIdCommand))
|
commandForm := req.BindJsonAndValid[*form.MongoUpdateByIdCommand](rc)
|
||||||
|
|
||||||
conn, err := m.mongoApp.GetMongoConn(rc.MetaCtx, m.GetMongoId(rc))
|
conn, err := m.mongoApp.GetMongoConn(rc.MetaCtx, m.GetMongoId(rc))
|
||||||
biz.ErrIsNil(err)
|
biz.ErrIsNil(err)
|
||||||
@@ -261,7 +258,7 @@ func (m *Mongo) DeleteByIdCommand(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Mongo) InsertOneCommand(rc *req.Ctx) {
|
func (m *Mongo) InsertOneCommand(rc *req.Ctx) {
|
||||||
commandForm := req.BindJsonAndValid(rc, new(form.MongoInsertCommand))
|
commandForm := req.BindJsonAndValid[*form.MongoInsertCommand](rc)
|
||||||
|
|
||||||
conn, err := m.mongoApp.GetMongoConn(rc.MetaCtx, m.GetMongoId(rc))
|
conn, err := m.mongoApp.GetMongoConn(rc.MetaCtx, m.GetMongoId(rc))
|
||||||
biz.ErrIsNil(err)
|
biz.ErrIsNil(err)
|
||||||
|
|||||||
@@ -36,9 +36,8 @@ func (m *MsgChannel) GetMsgChannels(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *MsgChannel) SaveMsgChannels(rc *req.Ctx) {
|
func (m *MsgChannel) SaveMsgChannels(rc *req.Ctx) {
|
||||||
form := &form.MsgChannel{}
|
form, channel := req.BindJsonAndCopyTo[*form.MsgChannel, *entity.MsgChannel](rc)
|
||||||
rc.ReqParam = form
|
rc.ReqParam = form
|
||||||
channel := req.BindJsonAndCopyTo(rc, form, new(entity.MsgChannel))
|
|
||||||
err := m.msgChannelApp.SaveChannel(rc.MetaCtx, channel)
|
err := m.msgChannelApp.SaveChannel(rc.MetaCtx, channel)
|
||||||
biz.ErrIsNil(err)
|
biz.ErrIsNil(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,9 +57,8 @@ func (m *MsgTmpl) GetMsgTmplChannels(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *MsgTmpl) SaveMsgTmpl(rc *req.Ctx) {
|
func (m *MsgTmpl) SaveMsgTmpl(rc *req.Ctx) {
|
||||||
form := &form.MsgTmpl{}
|
form, channel := req.BindJsonAndCopyTo[*form.MsgTmpl, *dto.MsgTmplSave](rc)
|
||||||
rc.ReqParam = form
|
rc.ReqParam = form
|
||||||
channel := req.BindJsonAndCopyTo(rc, form, new(dto.MsgTmplSave))
|
|
||||||
biz.ErrIsNil(m.msgTmplApp.SaveTmpl(rc.MetaCtx, channel))
|
biz.ErrIsNil(m.msgTmplApp.SaveTmpl(rc.MetaCtx, channel))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,7 +74,7 @@ func (m *MsgTmpl) DelMsgTmpls(rc *req.Ctx) {
|
|||||||
|
|
||||||
func (m *MsgTmpl) SendMsg(rc *req.Ctx) {
|
func (m *MsgTmpl) SendMsg(rc *req.Ctx) {
|
||||||
code := rc.PathParam("code")
|
code := rc.PathParam("code")
|
||||||
form := req.BindJsonAndValid(rc, new(form.SendMsg))
|
form := req.BindJsonAndValid[*form.SendMsg](rc)
|
||||||
|
|
||||||
rc.ReqParam = form
|
rc.ReqParam = form
|
||||||
|
|
||||||
|
|||||||
@@ -11,8 +11,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (r *Redis) RunCmd(rc *req.Ctx) {
|
func (r *Redis) RunCmd(rc *req.Ctx) {
|
||||||
var cmdReq form.RunCmdForm
|
cmdReq, runCmdParam := req.BindJsonAndCopyTo[*form.RunCmdForm, *dto.RunCmd](rc)
|
||||||
runCmdParam := req.BindJsonAndCopyTo(rc, &cmdReq, new(dto.RunCmd))
|
|
||||||
biz.IsTrue(len(cmdReq.Cmd) > 0, "redis cmd cannot be empty")
|
biz.IsTrue(len(cmdReq.Cmd) > 0, "redis cmd cannot be empty")
|
||||||
|
|
||||||
redisConn := r.getRedisConn(rc)
|
redisConn := r.getRedisConn(rc)
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import (
|
|||||||
func (r *Redis) ScanKeys(rc *req.Ctx) {
|
func (r *Redis) ScanKeys(rc *req.Ctx) {
|
||||||
ri := r.getRedisConn(rc)
|
ri := r.getRedisConn(rc)
|
||||||
|
|
||||||
form := req.BindJsonAndValid(rc, new(form.RedisScanForm))
|
form := req.BindJsonAndValid[*form.RedisScanForm](rc)
|
||||||
|
|
||||||
cmd := ri.GetCmdable()
|
cmd := ri.GetCmdable()
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ func (rs *Redis) ReqConfs() *req.Confs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *Redis) RedisList(rc *req.Ctx) {
|
func (r *Redis) RedisList(rc *req.Ctx) {
|
||||||
queryCond := req.BindQuery(rc, new(entity.RedisQuery))
|
queryCond := req.BindQuery[*entity.RedisQuery](rc)
|
||||||
|
|
||||||
// 不存在可访问标签id,即没有可操作数据
|
// 不存在可访问标签id,即没有可操作数据
|
||||||
tags := r.tagApp.GetAccountTags(rc.GetLoginAccount().Id, &tagentity.TagTreeQuery{
|
tags := r.tagApp.GetAccountTags(rc.GetLoginAccount().Id, &tagentity.TagTreeQuery{
|
||||||
@@ -87,8 +87,7 @@ func (r *Redis) RedisList(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *Redis) TestConn(rc *req.Ctx) {
|
func (r *Redis) TestConn(rc *req.Ctx) {
|
||||||
form := &form.Redis{}
|
form, redis := req.BindJsonAndCopyTo[*form.Redis, *entity.Redis](rc)
|
||||||
redis := req.BindJsonAndCopyTo[*entity.Redis](rc, form, new(entity.Redis))
|
|
||||||
|
|
||||||
authCert := &tagentity.ResourceAuthCert{
|
authCert := &tagentity.ResourceAuthCert{
|
||||||
Username: form.Username,
|
Username: form.Username,
|
||||||
@@ -110,8 +109,7 @@ func (r *Redis) TestConn(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *Redis) Save(rc *req.Ctx) {
|
func (r *Redis) Save(rc *req.Ctx) {
|
||||||
form := &form.Redis{}
|
form, redis := req.BindJsonAndCopyTo[*form.Redis, *entity.Redis](rc)
|
||||||
redis := req.BindJsonAndCopyTo[*entity.Redis](rc, form, new(entity.Redis))
|
|
||||||
|
|
||||||
redisParam := &dto.SaveRedis{
|
redisParam := &dto.SaveRedis{
|
||||||
Redis: redis,
|
Redis: redis,
|
||||||
|
|||||||
@@ -253,7 +253,7 @@ func (r *redisAppImpl) FlowBizHandle(ctx context.Context, bizHandleParam *flowap
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
runCmdParam, err := jsonx.To(procinst.BizForm, new(FlowRedisRunCmdBizForm))
|
runCmdParam, err := jsonx.To[*FlowRedisRunCmdBizForm](procinst.BizForm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errorx.NewBiz("failed to parse the business form information: %s", err.Error())
|
return nil, errorx.NewBiz("failed to parse the business form information: %s", err.Error())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ func (a *Account) GetPermissions(rc *req.Ctx) {
|
|||||||
func (a *Account) ChangePassword(rc *req.Ctx) {
|
func (a *Account) ChangePassword(rc *req.Ctx) {
|
||||||
ctx := rc.MetaCtx
|
ctx := rc.MetaCtx
|
||||||
|
|
||||||
form := req.BindJsonAndValid(rc, new(form.AccountChangePasswordForm))
|
form := req.BindJsonAndValid[*form.AccountChangePasswordForm](rc)
|
||||||
|
|
||||||
originOldPwd, err := utils.DefaultRsaDecrypt(form.OldPassword, true)
|
originOldPwd, err := utils.DefaultRsaDecrypt(form.OldPassword, true)
|
||||||
biz.ErrIsNilAppendErr(err, "Wrong to decrypt old password: %s")
|
biz.ErrIsNilAppendErr(err, "Wrong to decrypt old password: %s")
|
||||||
@@ -145,9 +145,10 @@ func (a *Account) AccountInfo(rc *req.Ctx) {
|
|||||||
|
|
||||||
// 更新个人账号信息
|
// 更新个人账号信息
|
||||||
func (a *Account) UpdateAccount(rc *req.Ctx) {
|
func (a *Account) UpdateAccount(rc *req.Ctx) {
|
||||||
updateAccount := req.BindJsonAndCopyTo[*entity.Account](rc, new(form.AccountUpdateForm), new(entity.Account))
|
form, updateAccount := req.BindJsonAndCopyTo[*form.AccountUpdateForm, *entity.Account](rc)
|
||||||
// 账号id为登录者账号
|
// 账号id为登录者账号
|
||||||
updateAccount.Id = rc.GetLoginAccount().Id
|
updateAccount.Id = rc.GetLoginAccount().Id
|
||||||
|
rc.ReqParam = form
|
||||||
|
|
||||||
ctx := rc.MetaCtx
|
ctx := rc.MetaCtx
|
||||||
if updateAccount.Password != "" {
|
if updateAccount.Password != "" {
|
||||||
@@ -210,8 +211,7 @@ func (a *Account) AccountDetail(rc *req.Ctx) {
|
|||||||
|
|
||||||
// @router /accounts
|
// @router /accounts
|
||||||
func (a *Account) SaveAccount(rc *req.Ctx) {
|
func (a *Account) SaveAccount(rc *req.Ctx) {
|
||||||
form := &form.AccountCreateForm{}
|
form, account := req.BindJsonAndCopyTo[*form.AccountCreateForm, *entity.Account](rc)
|
||||||
account := req.BindJsonAndCopyTo(rc, form, new(entity.Account))
|
|
||||||
|
|
||||||
form.Password = "*****"
|
form.Password = "*****"
|
||||||
rc.ReqParam = form
|
rc.ReqParam = form
|
||||||
@@ -307,7 +307,7 @@ func (a *Account) AccountResources(rc *req.Ctx) {
|
|||||||
|
|
||||||
// 关联账号角色
|
// 关联账号角色
|
||||||
func (a *Account) RelateRole(rc *req.Ctx) {
|
func (a *Account) RelateRole(rc *req.Ctx) {
|
||||||
form := req.BindJsonAndValid(rc, new(form.AccountRoleForm))
|
form := req.BindJsonAndValid[*form.AccountRoleForm](rc)
|
||||||
rc.ReqParam = form
|
rc.ReqParam = form
|
||||||
biz.ErrIsNil(a.roleApp.RelateAccountRole(rc.MetaCtx, form.Id, form.RoleId, consts.AccountRoleRelateType(form.RelateType)))
|
biz.ErrIsNil(a.roleApp.RelateAccountRole(rc.MetaCtx, form.Id, form.RoleId, consts.AccountRoleRelateType(form.RelateType)))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,8 +55,7 @@ func (c *Config) GetConfigValueByKey(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) SaveConfig(rc *req.Ctx) {
|
func (c *Config) SaveConfig(rc *req.Ctx) {
|
||||||
form := &form.ConfigForm{}
|
form, config := req.BindJsonAndCopyTo[*form.ConfigForm, *entity.Config](rc)
|
||||||
config := req.BindJsonAndCopyTo(rc, form, new(entity.Config))
|
|
||||||
rc.ReqParam = form
|
rc.ReqParam = form
|
||||||
biz.ErrIsNil(c.configApp.Save(rc.MetaCtx, config))
|
biz.ErrIsNil(c.configApp.Save(rc.MetaCtx, config))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,8 +50,7 @@ func (r *Resource) GetById(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *Resource) SaveResource(rc *req.Ctx) {
|
func (r *Resource) SaveResource(rc *req.Ctx) {
|
||||||
form := new(form.ResourceForm)
|
form, entity := req.BindJsonAndCopyTo[*form.ResourceForm, *entity.Resource](rc)
|
||||||
entity := req.BindJsonAndCopyTo(rc, form, new(entity.Resource))
|
|
||||||
|
|
||||||
rc.ReqParam = form
|
rc.ReqParam = form
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ func (r *Role) ReqConfs() *req.Confs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *Role) Roles(rc *req.Ctx) {
|
func (r *Role) Roles(rc *req.Ctx) {
|
||||||
cond := req.BindQuery(rc, new(entity.RoleQuery))
|
cond := req.BindQuery[*entity.RoleQuery](rc)
|
||||||
|
|
||||||
notIdsStr := rc.Query("notIds")
|
notIdsStr := rc.Query("notIds")
|
||||||
if notIdsStr != "" {
|
if notIdsStr != "" {
|
||||||
@@ -61,8 +61,7 @@ func (r *Role) Roles(rc *req.Ctx) {
|
|||||||
|
|
||||||
// 保存角色信息
|
// 保存角色信息
|
||||||
func (r *Role) SaveRole(rc *req.Ctx) {
|
func (r *Role) SaveRole(rc *req.Ctx) {
|
||||||
form := &form.RoleForm{}
|
form, role := req.BindJsonAndCopyTo[*form.RoleForm, *entity.Role](rc)
|
||||||
role := req.BindJsonAndCopyTo(rc, form, new(entity.Role))
|
|
||||||
rc.ReqParam = form
|
rc.ReqParam = form
|
||||||
|
|
||||||
r.roleApp.SaveRole(rc.MetaCtx, role)
|
r.roleApp.SaveRole(rc.MetaCtx, role)
|
||||||
@@ -93,8 +92,7 @@ func (r *Role) RoleResource(rc *req.Ctx) {
|
|||||||
|
|
||||||
// 保存角色资源
|
// 保存角色资源
|
||||||
func (r *Role) SaveResource(rc *req.Ctx) {
|
func (r *Role) SaveResource(rc *req.Ctx) {
|
||||||
var form form.RoleResourceForm
|
form := req.BindJsonAndValid[*form.RoleResourceForm](rc)
|
||||||
req.BindJsonAndValid(rc, &form)
|
|
||||||
rc.ReqParam = form
|
rc.ReqParam = form
|
||||||
|
|
||||||
// 将,拼接的字符串进行切割并转换
|
// 将,拼接的字符串进行切割并转换
|
||||||
@@ -107,7 +105,7 @@ func (r *Role) SaveResource(rc *req.Ctx) {
|
|||||||
|
|
||||||
// 查看角色关联的用户
|
// 查看角色关联的用户
|
||||||
func (r *Role) RoleAccount(rc *req.Ctx) {
|
func (r *Role) RoleAccount(rc *req.Ctx) {
|
||||||
cond := req.BindQuery(rc, new(entity.RoleAccountQuery))
|
cond := req.BindQuery[*entity.RoleAccountQuery](rc)
|
||||||
cond.RoleId = uint64(rc.PathParamInt("id"))
|
cond.RoleId = uint64(rc.PathParamInt("id"))
|
||||||
res, err := r.roleApp.GetRoleAccountPage(cond)
|
res, err := r.roleApp.GetRoleAccountPage(cond)
|
||||||
biz.ErrIsNil(err)
|
biz.ErrIsNil(err)
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ func (s *Syslog) ReqConfs() *req.Confs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *Syslog) Syslogs(rc *req.Ctx) {
|
func (r *Syslog) Syslogs(rc *req.Ctx) {
|
||||||
queryCond := req.BindQuery(rc, new(entity.SysLogQuery))
|
queryCond := req.BindQuery[*entity.SysLogQuery](rc)
|
||||||
res, err := r.syslogApp.GetPageList(queryCond, "create_time DESC")
|
res, err := r.syslogApp.GetPageList(queryCond, "create_time DESC")
|
||||||
biz.ErrIsNil(err)
|
biz.ErrIsNil(err)
|
||||||
rc.ResData = res
|
rc.ResData = res
|
||||||
|
|||||||
@@ -72,8 +72,7 @@ func (r *ResourceAuthCert) GetCompleteAuthCert(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *ResourceAuthCert) SaveAuthCert(rc *req.Ctx) {
|
func (c *ResourceAuthCert) SaveAuthCert(rc *req.Ctx) {
|
||||||
acForm := &form.AuthCertForm{}
|
acForm, ac := req.BindJsonAndCopyTo[*form.AuthCertForm, *entity.ResourceAuthCert](rc)
|
||||||
ac := req.BindJsonAndCopyTo(rc, acForm, new(entity.ResourceAuthCert))
|
|
||||||
|
|
||||||
// 脱敏记录日志
|
// 脱敏记录日志
|
||||||
acForm.Ciphertext = "***"
|
acForm.Ciphertext = "***"
|
||||||
|
|||||||
@@ -119,8 +119,7 @@ func (p *TagTree) ListByQuery(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *TagTree) SaveTagTree(rc *req.Ctx) {
|
func (p *TagTree) SaveTagTree(rc *req.Ctx) {
|
||||||
tagForm := &form.TagTree{}
|
tagForm, tagTree := req.BindJsonAndCopyTo[*form.TagTree, *entity.TagTree](rc)
|
||||||
tagTree := req.BindJsonAndCopyTo(rc, tagForm, new(entity.TagTree))
|
|
||||||
|
|
||||||
rc.ReqParam = fmt.Sprintf("tagTreeId: %d, tagName: %s, code: %s", tagTree.Id, tagTree.Name, tagTree.Code)
|
rc.ReqParam = fmt.Sprintf("tagTreeId: %d, tagName: %s, code: %s", tagTree.Id, tagTree.Name, tagTree.Code)
|
||||||
|
|
||||||
@@ -132,8 +131,7 @@ func (p *TagTree) DelTagTree(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *TagTree) MovingTag(rc *req.Ctx) {
|
func (p *TagTree) MovingTag(rc *req.Ctx) {
|
||||||
movingForm := &form.MovingTag{}
|
movingForm := req.BindJsonAndValid[*form.MovingTag](rc)
|
||||||
req.BindJsonAndValid(rc, movingForm)
|
|
||||||
rc.ReqParam = movingForm
|
rc.ReqParam = movingForm
|
||||||
biz.ErrIsNil(p.tagTreeApp.MovingTag(rc.MetaCtx, movingForm.FromPath, movingForm.ToPath))
|
biz.ErrIsNil(p.tagTreeApp.MovingTag(rc.MetaCtx, movingForm.FromPath, movingForm.ToPath))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ func (t *Team) ReqConfs() *req.Confs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *Team) GetTeams(rc *req.Ctx) {
|
func (p *Team) GetTeams(rc *req.Ctx) {
|
||||||
queryCond := req.BindQuery(rc, new(entity.TeamQuery))
|
queryCond := req.BindQuery[*entity.TeamQuery](rc)
|
||||||
|
|
||||||
res, err := p.teamApp.GetPageList(queryCond)
|
res, err := p.teamApp.GetPageList(queryCond)
|
||||||
biz.ErrIsNil(err)
|
biz.ErrIsNil(err)
|
||||||
@@ -60,7 +60,7 @@ func (p *Team) GetTeams(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *Team) SaveTeam(rc *req.Ctx) {
|
func (p *Team) SaveTeam(rc *req.Ctx) {
|
||||||
team := req.BindJsonAndValid(rc, new(dto.SaveTeam))
|
team := req.BindJsonAndValid[*dto.SaveTeam](rc)
|
||||||
rc.ReqParam = team
|
rc.ReqParam = team
|
||||||
biz.ErrIsNil(p.teamApp.SaveTeam(rc.MetaCtx, team))
|
biz.ErrIsNil(p.teamApp.SaveTeam(rc.MetaCtx, team))
|
||||||
}
|
}
|
||||||
@@ -87,7 +87,7 @@ func (p *Team) GetTeamMembers(rc *req.Ctx) {
|
|||||||
|
|
||||||
// 保存团队信息
|
// 保存团队信息
|
||||||
func (p *Team) SaveTeamMember(rc *req.Ctx) {
|
func (p *Team) SaveTeamMember(rc *req.Ctx) {
|
||||||
teamMems := req.BindJsonAndValid(rc, new(form.TeamMember))
|
teamMems := req.BindJsonAndValid[*form.TeamMember](rc)
|
||||||
|
|
||||||
teamId := teamMems.TeamId
|
teamId := teamMems.TeamId
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type ResourceAuthCert struct {
|
type ResourceAuthCert struct {
|
||||||
|
model.ExtraData
|
||||||
|
|
||||||
Id uint64 `json:"id"`
|
Id uint64 `json:"id"`
|
||||||
Name string `json:"name"` // 名称
|
Name string `json:"name"` // 名称
|
||||||
ResourceCode string `json:"resourceCode"` // 资源编号
|
ResourceCode string `json:"resourceCode"` // 资源编号
|
||||||
@@ -14,7 +16,6 @@ type ResourceAuthCert struct {
|
|||||||
Username string `json:"username"` // 用户名
|
Username string `json:"username"` // 用户名
|
||||||
Ciphertext string `json:"ciphertext"` // 密文
|
Ciphertext string `json:"ciphertext"` // 密文
|
||||||
CiphertextType entity.AuthCertCiphertextType `json:"ciphertextType"` // 密文类型
|
CiphertextType entity.AuthCertCiphertextType `json:"ciphertextType"` // 密文类型
|
||||||
Extra model.Map[string, any] `json:"extra"` // 账号需要的其他额外信息(如秘钥口令等)
|
|
||||||
Type entity.AuthCertType `json:"type"` // 凭证类型
|
Type entity.AuthCertType `json:"type"` // 凭证类型
|
||||||
Remark string `json:"remark"` // 备注
|
Remark string `json:"remark"` // 备注
|
||||||
|
|
||||||
|
|||||||
4
server/pkg/cache/cache.go
vendored
4
server/pkg/cache/cache.go
vendored
@@ -1,8 +1,8 @@
|
|||||||
package cache
|
package cache
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"mayfly-go/pkg/utils/anyx"
|
"mayfly-go/pkg/utils/anyx"
|
||||||
"mayfly-go/pkg/utils/jsonx"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/may-fly/cast"
|
"github.com/may-fly/cast"
|
||||||
@@ -65,7 +65,7 @@ func (dc *defaultCache) GetInt(k string) (int, bool) {
|
|||||||
|
|
||||||
func (dc *defaultCache) GetJson(k string, valPtr any) bool {
|
func (dc *defaultCache) GetJson(k string, valPtr any) bool {
|
||||||
if val, ok := dc.GetStr(k); ok {
|
if val, ok := dc.GetStr(k); ok {
|
||||||
jsonx.To(val, valPtr)
|
json.Unmarshal([]byte(val), valPtr)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"mayfly-go/pkg/utils/collx"
|
|
||||||
"mayfly-go/pkg/utils/structx"
|
"mayfly-go/pkg/utils/structx"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -27,13 +26,8 @@ func PageResultConv[F any, T any](pageResult *PageResult[F]) *PageResult[T] {
|
|||||||
if pageResult == nil {
|
if pageResult == nil {
|
||||||
return NewEmptyPageResult[T]()
|
return NewEmptyPageResult[T]()
|
||||||
}
|
}
|
||||||
|
|
||||||
return &PageResult[T]{
|
return &PageResult[T]{
|
||||||
Total: pageResult.Total,
|
Total: pageResult.Total,
|
||||||
List: collx.ArrayMap(pageResult.List, func(item F) T {
|
List: structx.CopySliceTo[F, T](pageResult.List),
|
||||||
t := structx.NewInstance[T]()
|
|
||||||
structx.Copy(t, item)
|
|
||||||
return t
|
|
||||||
}),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// 绑定并校验请求结构体参数
|
// 绑定并校验请求结构体参数
|
||||||
func BindJsonAndValid[T any](rc *Ctx, data T) T {
|
func BindJsonAndValid[T any](rc *Ctx) T {
|
||||||
|
data := structx.NewInstance[T]()
|
||||||
if err := rc.BindJSON(data); err != nil {
|
if err := rc.BindJSON(data); err != nil {
|
||||||
panic(ConvBindValidationError(data, err))
|
panic(ConvBindValidationError(data, err))
|
||||||
} else {
|
} else {
|
||||||
@@ -18,15 +19,15 @@ func BindJsonAndValid[T any](rc *Ctx, data T) T {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 绑定请求体中的json至form结构体,并拷贝至另一结构体
|
// 绑定请求体中的json至form结构体,并拷贝至指定结构体
|
||||||
func BindJsonAndCopyTo[T any](rc *Ctx, form any, toStruct T) T {
|
func BindJsonAndCopyTo[F, T any](rc *Ctx) (F, T) {
|
||||||
BindJsonAndValid(rc, form)
|
f := BindJsonAndValid[F](rc)
|
||||||
structx.Copy(toStruct, form)
|
return f, structx.CopyTo[T](f)
|
||||||
return toStruct
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 绑定查询字符串到指定结构体
|
// 绑定查询字符串到指定结构体
|
||||||
func BindQuery[T any](rc *Ctx, data T) T {
|
func BindQuery[T any](rc *Ctx) T {
|
||||||
|
data := structx.NewInstance[T]()
|
||||||
if err := rc.BindQuery(data); err != nil {
|
if err := rc.BindQuery(data); err != nil {
|
||||||
panic(ConvBindValidationError(data, err))
|
panic(ConvBindValidationError(data, err))
|
||||||
} else {
|
} else {
|
||||||
@@ -35,7 +36,8 @@ func BindQuery[T any](rc *Ctx, data T) T {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 绑定查询字符串到指定结构体,并将分页信息也返回
|
// 绑定查询字符串到指定结构体,并将分页信息也返回
|
||||||
func BindQueryAndPage[T any](rc *Ctx, data T) (T, model.PageParam) {
|
func BindQueryAndPage[T any](rc *Ctx) (T, model.PageParam) {
|
||||||
|
data := structx.NewInstance[T]()
|
||||||
if err := rc.BindQuery(data); err != nil {
|
if err := rc.BindQuery(data); err != nil {
|
||||||
panic(ConvBindValidationError(data, err))
|
panic(ConvBindValidationError(data, err))
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"mayfly-go/pkg/logx"
|
"mayfly-go/pkg/logx"
|
||||||
"mayfly-go/pkg/utils/collx"
|
"mayfly-go/pkg/utils/collx"
|
||||||
|
"mayfly-go/pkg/utils/structx"
|
||||||
|
|
||||||
"github.com/tidwall/gjson"
|
"github.com/tidwall/gjson"
|
||||||
)
|
)
|
||||||
@@ -16,9 +17,10 @@ func ToMap(jsonStr string) (collx.M, error) {
|
|||||||
return ToMapByBytes([]byte(jsonStr))
|
return ToMapByBytes([]byte(jsonStr))
|
||||||
}
|
}
|
||||||
|
|
||||||
// json字符串转结构体
|
// json字符串转结构体, T需为指针类型
|
||||||
func To[T any](jsonStr string, res T) (T, error) {
|
func To[T any](jsonStr string) (T, error) {
|
||||||
return res, json.Unmarshal([]byte(jsonStr), &res)
|
res := structx.NewInstance[T]()
|
||||||
|
return res, json.Unmarshal([]byte(jsonStr), res)
|
||||||
}
|
}
|
||||||
|
|
||||||
// json字节数组转map
|
// json字节数组转map
|
||||||
|
|||||||
874
server/pkg/utils/structx/copier.go
Normal file
874
server/pkg/utils/structx/copier.go
Normal file
@@ -0,0 +1,874 @@
|
|||||||
|
package structx
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"database/sql/driver"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"unicode"
|
||||||
|
)
|
||||||
|
|
||||||
|
// github.com/jinzhu/copier
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrInvalidCopyDestination = errors.New("copy destination must be non-nil and addressable")
|
||||||
|
ErrInvalidCopyFrom = errors.New("copy from must be non-nil and addressable")
|
||||||
|
ErrMapKeyNotMatch = errors.New("map's key type doesn't match")
|
||||||
|
ErrNotSupported = errors.New("not supported")
|
||||||
|
ErrFieldNameTagStartNotUpperCase = errors.New("copier field name tag must be start upper case")
|
||||||
|
)
|
||||||
|
|
||||||
|
// These flags define options for tag handling
|
||||||
|
const (
|
||||||
|
// Denotes that a destination field must be copied to. If copying fails then a panic will ensue.
|
||||||
|
tagMust uint8 = 1 << iota
|
||||||
|
|
||||||
|
// Denotes that the program should not panic when the must flag is on and
|
||||||
|
// value is not copied. The program will return an error instead.
|
||||||
|
tagNoPanic
|
||||||
|
|
||||||
|
// Ignore a destination field from being copied to.
|
||||||
|
tagIgnore
|
||||||
|
|
||||||
|
// Denotes the fact that the field should be overridden, no matter if the IgnoreEmpty is set
|
||||||
|
tagOverride
|
||||||
|
|
||||||
|
// Denotes that the value as been copied
|
||||||
|
hasCopied
|
||||||
|
|
||||||
|
// Some default converter types for a nicer syntax
|
||||||
|
String string = ""
|
||||||
|
Bool bool = false
|
||||||
|
Int int = 0
|
||||||
|
Float32 float32 = 0
|
||||||
|
Float64 float64 = 0
|
||||||
|
)
|
||||||
|
|
||||||
|
// Option sets copy options
|
||||||
|
type Option struct {
|
||||||
|
// setting this value to true will ignore copying zero values of all the fields, including bools, as well as a
|
||||||
|
// struct having all it's fields set to their zero values respectively (see IsZero() in reflect/value.go)
|
||||||
|
IgnoreEmpty bool
|
||||||
|
CaseSensitive bool
|
||||||
|
DeepCopy bool
|
||||||
|
Converters []TypeConverter
|
||||||
|
// Custom field name mappings to copy values with different names in `fromValue` and `toValue` types.
|
||||||
|
// Examples can be found in `copier_field_name_mapping_test.go`.
|
||||||
|
FieldNameMapping []FieldNameMapping
|
||||||
|
}
|
||||||
|
|
||||||
|
func (opt Option) converters() map[converterPair]TypeConverter {
|
||||||
|
var converters = map[converterPair]TypeConverter{}
|
||||||
|
|
||||||
|
// save converters into map for faster lookup
|
||||||
|
for i := range opt.Converters {
|
||||||
|
pair := converterPair{
|
||||||
|
SrcType: reflect.TypeOf(opt.Converters[i].SrcType),
|
||||||
|
DstType: reflect.TypeOf(opt.Converters[i].DstType),
|
||||||
|
}
|
||||||
|
|
||||||
|
converters[pair] = opt.Converters[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
return converters
|
||||||
|
}
|
||||||
|
|
||||||
|
type TypeConverter struct {
|
||||||
|
SrcType interface{}
|
||||||
|
DstType interface{}
|
||||||
|
Fn func(src interface{}) (dst interface{}, err error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type converterPair struct {
|
||||||
|
SrcType reflect.Type
|
||||||
|
DstType reflect.Type
|
||||||
|
}
|
||||||
|
|
||||||
|
func (opt Option) fieldNameMapping() map[converterPair]FieldNameMapping {
|
||||||
|
var mapping = map[converterPair]FieldNameMapping{}
|
||||||
|
|
||||||
|
for i := range opt.FieldNameMapping {
|
||||||
|
pair := converterPair{
|
||||||
|
SrcType: reflect.TypeOf(opt.FieldNameMapping[i].SrcType),
|
||||||
|
DstType: reflect.TypeOf(opt.FieldNameMapping[i].DstType),
|
||||||
|
}
|
||||||
|
|
||||||
|
mapping[pair] = opt.FieldNameMapping[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
return mapping
|
||||||
|
}
|
||||||
|
|
||||||
|
type FieldNameMapping struct {
|
||||||
|
SrcType interface{}
|
||||||
|
DstType interface{}
|
||||||
|
Mapping map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tag Flags
|
||||||
|
type flags struct {
|
||||||
|
BitFlags map[string]uint8
|
||||||
|
SrcNames tagNameMapping
|
||||||
|
DestNames tagNameMapping
|
||||||
|
}
|
||||||
|
|
||||||
|
// Field Tag name mapping
|
||||||
|
type tagNameMapping struct {
|
||||||
|
FieldNameToTag map[string]string
|
||||||
|
TagToFieldName map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy copy things
|
||||||
|
func Copy(toValue interface{}, fromValue interface{}) (err error) {
|
||||||
|
return copier(toValue, fromValue, Option{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyWithOption copy with option
|
||||||
|
func CopyWithOption(toValue interface{}, fromValue interface{}, opt Option) (err error) {
|
||||||
|
return copier(toValue, fromValue, opt)
|
||||||
|
}
|
||||||
|
|
||||||
|
func copier(toValue interface{}, fromValue interface{}, opt Option) (err error) {
|
||||||
|
var (
|
||||||
|
isSlice bool
|
||||||
|
amount = 1
|
||||||
|
from = indirect(reflect.ValueOf(fromValue))
|
||||||
|
to = indirect(reflect.ValueOf(toValue))
|
||||||
|
converters = opt.converters()
|
||||||
|
mappings = opt.fieldNameMapping()
|
||||||
|
)
|
||||||
|
|
||||||
|
if !to.CanAddr() {
|
||||||
|
return ErrInvalidCopyDestination
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return is from value is invalid
|
||||||
|
if !from.IsValid() {
|
||||||
|
return ErrInvalidCopyFrom
|
||||||
|
}
|
||||||
|
|
||||||
|
fromType, isPtrFrom := indirectType(from.Type())
|
||||||
|
toType, _ := indirectType(to.Type())
|
||||||
|
|
||||||
|
if fromType.Kind() == reflect.Interface {
|
||||||
|
fromType = reflect.TypeOf(from.Interface())
|
||||||
|
}
|
||||||
|
|
||||||
|
if toType.Kind() == reflect.Interface {
|
||||||
|
toType, _ = indirectType(reflect.TypeOf(to.Interface()))
|
||||||
|
oldTo := to
|
||||||
|
to = reflect.New(reflect.TypeOf(to.Interface())).Elem()
|
||||||
|
defer func() {
|
||||||
|
oldTo.Set(to)
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Just set it if possible to assign for normal types
|
||||||
|
if from.Kind() != reflect.Slice && from.Kind() != reflect.Struct && from.Kind() != reflect.Map && (from.Type().AssignableTo(to.Type()) || from.Type().ConvertibleTo(to.Type())) {
|
||||||
|
if !isPtrFrom || !opt.DeepCopy {
|
||||||
|
to.Set(from.Convert(to.Type()))
|
||||||
|
} else {
|
||||||
|
fromCopy := reflect.New(from.Type())
|
||||||
|
fromCopy.Set(from.Elem())
|
||||||
|
to.Set(fromCopy.Convert(to.Type()))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if from.Kind() != reflect.Slice && fromType.Kind() == reflect.Map && toType.Kind() == reflect.Map {
|
||||||
|
if !fromType.Key().ConvertibleTo(toType.Key()) {
|
||||||
|
return ErrMapKeyNotMatch
|
||||||
|
}
|
||||||
|
|
||||||
|
if to.IsNil() {
|
||||||
|
to.Set(reflect.MakeMapWithSize(toType, from.Len()))
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, k := range from.MapKeys() {
|
||||||
|
toKey := indirect(reflect.New(toType.Key()))
|
||||||
|
isSet, err := set(toKey, k, opt.DeepCopy, converters)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !isSet {
|
||||||
|
return fmt.Errorf("%w map, old key: %v, new key: %v", ErrNotSupported, k.Type(), toType.Key())
|
||||||
|
}
|
||||||
|
|
||||||
|
elemType := toType.Elem()
|
||||||
|
if elemType.Kind() != reflect.Slice {
|
||||||
|
elemType, _ = indirectType(elemType)
|
||||||
|
}
|
||||||
|
toValue := indirect(reflect.New(elemType))
|
||||||
|
isSet, err = set(toValue, from.MapIndex(k), opt.DeepCopy, converters)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !isSet {
|
||||||
|
if err = copier(toValue.Addr().Interface(), from.MapIndex(k).Interface(), opt); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for {
|
||||||
|
if elemType == toType.Elem() {
|
||||||
|
to.SetMapIndex(toKey, toValue)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
elemType = reflect.PointerTo(elemType)
|
||||||
|
toValue = toValue.Addr()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if from.Kind() == reflect.Slice && to.Kind() == reflect.Slice {
|
||||||
|
// Return directly if both slices are nil
|
||||||
|
if from.IsNil() && to.IsNil() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if to.IsNil() {
|
||||||
|
slice := reflect.MakeSlice(reflect.SliceOf(to.Type().Elem()), from.Len(), from.Cap())
|
||||||
|
to.Set(slice)
|
||||||
|
}
|
||||||
|
if fromType.ConvertibleTo(toType) {
|
||||||
|
for i := 0; i < from.Len(); i++ {
|
||||||
|
if to.Len() < i+1 {
|
||||||
|
to.Set(reflect.Append(to, reflect.New(to.Type().Elem()).Elem()))
|
||||||
|
}
|
||||||
|
isSet, err := set(to.Index(i), from.Index(i), opt.DeepCopy, converters)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !isSet {
|
||||||
|
// ignore error while copy slice element
|
||||||
|
err = copier(to.Index(i).Addr().Interface(), from.Index(i).Interface(), opt)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if to.Len() > from.Len() {
|
||||||
|
to.SetLen(from.Len())
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if fromType.Kind() != reflect.Struct || toType.Kind() != reflect.Struct {
|
||||||
|
// skip not supported type
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(converters) > 0 {
|
||||||
|
if ok, e := set(to, from, opt.DeepCopy, converters); e == nil && ok {
|
||||||
|
// converter supported
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if from.Kind() == reflect.Slice || to.Kind() == reflect.Slice {
|
||||||
|
isSlice = true
|
||||||
|
if from.Kind() == reflect.Slice {
|
||||||
|
amount = from.Len()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < amount; i++ {
|
||||||
|
var dest, source reflect.Value
|
||||||
|
|
||||||
|
if isSlice {
|
||||||
|
// source
|
||||||
|
if from.Kind() == reflect.Slice {
|
||||||
|
source = indirect(from.Index(i))
|
||||||
|
} else {
|
||||||
|
source = indirect(from)
|
||||||
|
}
|
||||||
|
// dest
|
||||||
|
dest = indirect(reflect.New(toType).Elem())
|
||||||
|
} else {
|
||||||
|
source = indirect(from)
|
||||||
|
dest = indirect(to)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(converters) > 0 {
|
||||||
|
if ok, e := set(dest, source, opt.DeepCopy, converters); e == nil && ok {
|
||||||
|
if isSlice {
|
||||||
|
// FIXME: maybe should check the other types?
|
||||||
|
if to.Type().Elem().Kind() == reflect.Ptr {
|
||||||
|
to.Index(i).Set(dest.Addr())
|
||||||
|
} else {
|
||||||
|
if to.Len() < i+1 {
|
||||||
|
reflect.Append(to, dest)
|
||||||
|
} else {
|
||||||
|
to.Index(i).Set(dest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
to.Set(dest)
|
||||||
|
}
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
destKind := dest.Kind()
|
||||||
|
initDest := false
|
||||||
|
if destKind == reflect.Interface {
|
||||||
|
initDest = true
|
||||||
|
dest = indirect(reflect.New(toType))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get tag options
|
||||||
|
flgs, err := getFlags(dest, source, toType, fromType)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// check source
|
||||||
|
if source.IsValid() {
|
||||||
|
copyUnexportedStructFields(dest, source)
|
||||||
|
|
||||||
|
// Copy from source field to dest field or method
|
||||||
|
fromTypeFields := deepFields(fromType)
|
||||||
|
for _, field := range fromTypeFields {
|
||||||
|
name := field.Name
|
||||||
|
|
||||||
|
// Get bit flags for field
|
||||||
|
fieldFlags := flgs.BitFlags[name]
|
||||||
|
|
||||||
|
// Check if we should ignore copying
|
||||||
|
if (fieldFlags & tagIgnore) != 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldNamesMapping := getFieldNamesMapping(mappings, fromType, toType)
|
||||||
|
|
||||||
|
srcFieldName, destFieldName := getFieldName(name, flgs, fieldNamesMapping)
|
||||||
|
|
||||||
|
if fromField := fieldByNameOrZeroValue(source, srcFieldName); fromField.IsValid() && !shouldIgnore(fromField, fieldFlags, opt.IgnoreEmpty) {
|
||||||
|
// process for nested anonymous field
|
||||||
|
destFieldNotSet := false
|
||||||
|
if f, ok := dest.Type().FieldByName(destFieldName); ok {
|
||||||
|
// only initialize parent embedded struct pointer in the path
|
||||||
|
for idx := range f.Index[:len(f.Index)-1] {
|
||||||
|
destField := dest.FieldByIndex(f.Index[:idx+1])
|
||||||
|
|
||||||
|
if destField.Kind() != reflect.Ptr {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if !destField.IsNil() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !destField.CanSet() {
|
||||||
|
destFieldNotSet = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// destField is a nil pointer that can be set
|
||||||
|
newValue := reflect.New(destField.Type().Elem())
|
||||||
|
destField.Set(newValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if destFieldNotSet {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
toField := fieldByName(dest, destFieldName, opt.CaseSensitive)
|
||||||
|
if toField.IsValid() {
|
||||||
|
if toField.CanSet() {
|
||||||
|
isSet, err := set(toField, fromField, opt.DeepCopy, converters)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !isSet {
|
||||||
|
if err := copier(toField.Addr().Interface(), fromField.Interface(), opt); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if fieldFlags != 0 {
|
||||||
|
// Note that a copy was made
|
||||||
|
flgs.BitFlags[name] = fieldFlags | hasCopied
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// try to set to method
|
||||||
|
var toMethod reflect.Value
|
||||||
|
if dest.CanAddr() {
|
||||||
|
toMethod = dest.Addr().MethodByName(destFieldName)
|
||||||
|
} else {
|
||||||
|
toMethod = dest.MethodByName(destFieldName)
|
||||||
|
}
|
||||||
|
|
||||||
|
if toMethod.IsValid() && toMethod.Type().NumIn() == 1 && fromField.Type().AssignableTo(toMethod.Type().In(0)) {
|
||||||
|
toMethod.Call([]reflect.Value{fromField})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy from from method to dest field
|
||||||
|
for _, field := range deepFields(toType) {
|
||||||
|
name := field.Name
|
||||||
|
srcFieldName, destFieldName := getFieldName(name, flgs, getFieldNamesMapping(mappings, fromType, toType))
|
||||||
|
|
||||||
|
var fromMethod reflect.Value
|
||||||
|
if source.CanAddr() {
|
||||||
|
fromMethod = source.Addr().MethodByName(srcFieldName)
|
||||||
|
} else {
|
||||||
|
fromMethod = source.MethodByName(srcFieldName)
|
||||||
|
}
|
||||||
|
|
||||||
|
if fromMethod.IsValid() && fromMethod.Type().NumIn() == 0 && fromMethod.Type().NumOut() == 1 && !shouldIgnore(fromMethod, flgs.BitFlags[name], opt.IgnoreEmpty) {
|
||||||
|
if toField := fieldByName(dest, destFieldName, opt.CaseSensitive); toField.IsValid() && toField.CanSet() {
|
||||||
|
values := fromMethod.Call([]reflect.Value{})
|
||||||
|
if len(values) >= 1 {
|
||||||
|
set(toField, values[0], opt.DeepCopy, converters)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if isSlice && to.Kind() == reflect.Slice {
|
||||||
|
if dest.Addr().Type().AssignableTo(to.Type().Elem()) {
|
||||||
|
if to.Len() < i+1 {
|
||||||
|
to.Set(reflect.Append(to, dest.Addr()))
|
||||||
|
} else {
|
||||||
|
isSet, err := set(to.Index(i), dest.Addr(), opt.DeepCopy, converters)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !isSet {
|
||||||
|
// ignore error while copy slice element
|
||||||
|
err = copier(to.Index(i).Addr().Interface(), dest.Addr().Interface(), opt)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if dest.Type().AssignableTo(to.Type().Elem()) {
|
||||||
|
if to.Len() < i+1 {
|
||||||
|
to.Set(reflect.Append(to, dest))
|
||||||
|
} else {
|
||||||
|
isSet, err := set(to.Index(i), dest, opt.DeepCopy, converters)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !isSet {
|
||||||
|
// ignore error while copy slice element
|
||||||
|
err = copier(to.Index(i).Addr().Interface(), dest.Interface(), opt)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if initDest {
|
||||||
|
to.Set(dest)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = checkBitFlags(flgs.BitFlags)
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func getFieldNamesMapping(mappings map[converterPair]FieldNameMapping, fromType reflect.Type, toType reflect.Type) map[string]string {
|
||||||
|
var fieldNamesMapping map[string]string
|
||||||
|
|
||||||
|
if len(mappings) > 0 {
|
||||||
|
pair := converterPair{
|
||||||
|
SrcType: fromType,
|
||||||
|
DstType: toType,
|
||||||
|
}
|
||||||
|
if v, ok := mappings[pair]; ok {
|
||||||
|
fieldNamesMapping = v.Mapping
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fieldNamesMapping
|
||||||
|
}
|
||||||
|
|
||||||
|
func fieldByNameOrZeroValue(source reflect.Value, fieldName string) (value reflect.Value) {
|
||||||
|
defer func() {
|
||||||
|
if err := recover(); err != nil {
|
||||||
|
value = reflect.Value{}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
return source.FieldByName(fieldName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func copyUnexportedStructFields(to, from reflect.Value) {
|
||||||
|
if from.Kind() != reflect.Struct || to.Kind() != reflect.Struct || !from.Type().AssignableTo(to.Type()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a shallow copy of 'to' to get all fields
|
||||||
|
tmp := indirect(reflect.New(to.Type()))
|
||||||
|
tmp.Set(from)
|
||||||
|
|
||||||
|
// revert exported fields
|
||||||
|
for i := 0; i < to.NumField(); i++ {
|
||||||
|
if tmp.Field(i).CanSet() {
|
||||||
|
tmp.Field(i).Set(to.Field(i))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
to.Set(tmp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func shouldIgnore(v reflect.Value, bitFlags uint8, ignoreEmpty bool) bool {
|
||||||
|
return ignoreEmpty && bitFlags&tagOverride == 0 && v.IsZero()
|
||||||
|
}
|
||||||
|
|
||||||
|
var deepFieldsLock sync.RWMutex
|
||||||
|
var deepFieldsMap = make(map[reflect.Type][]reflect.StructField)
|
||||||
|
|
||||||
|
func deepFields(reflectType reflect.Type) []reflect.StructField {
|
||||||
|
deepFieldsLock.RLock()
|
||||||
|
cache, ok := deepFieldsMap[reflectType]
|
||||||
|
deepFieldsLock.RUnlock()
|
||||||
|
if ok {
|
||||||
|
return cache
|
||||||
|
}
|
||||||
|
var res []reflect.StructField
|
||||||
|
if reflectType, _ = indirectType(reflectType); reflectType.Kind() == reflect.Struct {
|
||||||
|
fields := make([]reflect.StructField, 0, reflectType.NumField())
|
||||||
|
|
||||||
|
for i := 0; i < reflectType.NumField(); i++ {
|
||||||
|
v := reflectType.Field(i)
|
||||||
|
// PkgPath is the package path that qualifies a lower case (unexported)
|
||||||
|
// field name. It is empty for upper case (exported) field names.
|
||||||
|
// See https://golang.org/ref/spec#Uniqueness_of_identifiers
|
||||||
|
if v.PkgPath == "" {
|
||||||
|
fields = append(fields, v)
|
||||||
|
if v.Anonymous {
|
||||||
|
// also consider fields of anonymous fields as fields of the root
|
||||||
|
fields = append(fields, deepFields(v.Type)...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res = fields
|
||||||
|
}
|
||||||
|
|
||||||
|
deepFieldsLock.Lock()
|
||||||
|
deepFieldsMap[reflectType] = res
|
||||||
|
deepFieldsLock.Unlock()
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func indirect(reflectValue reflect.Value) reflect.Value {
|
||||||
|
for reflectValue.Kind() == reflect.Ptr {
|
||||||
|
reflectValue = reflectValue.Elem()
|
||||||
|
}
|
||||||
|
return reflectValue
|
||||||
|
}
|
||||||
|
|
||||||
|
func indirectType(reflectType reflect.Type) (_ reflect.Type, isPtr bool) {
|
||||||
|
for reflectType.Kind() == reflect.Ptr || reflectType.Kind() == reflect.Slice {
|
||||||
|
reflectType = reflectType.Elem()
|
||||||
|
isPtr = true
|
||||||
|
}
|
||||||
|
return reflectType, isPtr
|
||||||
|
}
|
||||||
|
|
||||||
|
func set(to, from reflect.Value, deepCopy bool, converters map[converterPair]TypeConverter) (bool, error) {
|
||||||
|
if !from.IsValid() {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
if ok, err := lookupAndCopyWithConverter(to, from, converters); err != nil {
|
||||||
|
return false, err
|
||||||
|
} else if ok {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if to.Kind() == reflect.Ptr {
|
||||||
|
// set `to` to nil if from is nil
|
||||||
|
if from.Kind() == reflect.Ptr && from.IsNil() {
|
||||||
|
to.Set(reflect.Zero(to.Type()))
|
||||||
|
return true, nil
|
||||||
|
} else if to.IsNil() {
|
||||||
|
// `from` -> `to`
|
||||||
|
// sql.NullString -> *string
|
||||||
|
if fromValuer, ok := driverValuer(from); ok {
|
||||||
|
v, err := fromValuer.Value()
|
||||||
|
if err != nil {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
// if `from` is not valid do nothing with `to`
|
||||||
|
if v == nil {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// allocate new `to` variable with default value (eg. *string -> new(string))
|
||||||
|
to.Set(reflect.New(to.Type().Elem()))
|
||||||
|
} else if from.Kind() != reflect.Ptr && from.IsZero() {
|
||||||
|
to.Set(reflect.Zero(to.Type()))
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
// depointer `to`
|
||||||
|
to = to.Elem()
|
||||||
|
}
|
||||||
|
|
||||||
|
if deepCopy {
|
||||||
|
toKind := to.Kind()
|
||||||
|
if toKind == reflect.Interface && to.IsNil() {
|
||||||
|
if reflect.TypeOf(from.Interface()) != nil {
|
||||||
|
to.Set(reflect.New(reflect.TypeOf(from.Interface())).Elem())
|
||||||
|
toKind = reflect.TypeOf(to.Interface()).Kind()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if from.Kind() == reflect.Ptr && from.IsNil() {
|
||||||
|
to.Set(reflect.Zero(to.Type()))
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
if _, ok := to.Addr().Interface().(sql.Scanner); !ok && (toKind == reflect.Struct || toKind == reflect.Map || toKind == reflect.Slice) {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// try convert directly
|
||||||
|
if from.Type().ConvertibleTo(to.Type()) {
|
||||||
|
to.Set(from.Convert(to.Type()))
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// try Scanner
|
||||||
|
if toScanner, ok := to.Addr().Interface().(sql.Scanner); ok {
|
||||||
|
// `from` -> `to`
|
||||||
|
// *string -> sql.NullString
|
||||||
|
if from.Kind() == reflect.Ptr {
|
||||||
|
// if `from` is nil do nothing with `to`
|
||||||
|
if from.IsNil() {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
// depointer `from`
|
||||||
|
from = indirect(from)
|
||||||
|
}
|
||||||
|
// `from` -> `to`
|
||||||
|
// string -> sql.NullString
|
||||||
|
// set `to` by invoking method Scan(`from`)
|
||||||
|
err := toScanner.Scan(from.Interface())
|
||||||
|
if err == nil {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// try Valuer
|
||||||
|
if fromValuer, ok := driverValuer(from); ok {
|
||||||
|
// `from` -> `to`
|
||||||
|
// sql.NullString -> string
|
||||||
|
v, err := fromValuer.Value()
|
||||||
|
if err != nil {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
// if `from` is not valid do nothing with `to`
|
||||||
|
if v == nil {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
rv := reflect.ValueOf(v)
|
||||||
|
if rv.Type().AssignableTo(to.Type()) {
|
||||||
|
to.Set(rv)
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
if to.CanSet() && rv.Type().ConvertibleTo(to.Type()) {
|
||||||
|
to.Set(rv.Convert(to.Type()))
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// from is ptr
|
||||||
|
if from.Kind() == reflect.Ptr {
|
||||||
|
return set(to, from.Elem(), deepCopy, converters)
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// lookupAndCopyWithConverter looks up the type pair, on success the TypeConverter Fn func is called to copy src to dst field.
|
||||||
|
func lookupAndCopyWithConverter(to, from reflect.Value, converters map[converterPair]TypeConverter) (copied bool, err error) {
|
||||||
|
pair := converterPair{
|
||||||
|
SrcType: from.Type(),
|
||||||
|
DstType: to.Type(),
|
||||||
|
}
|
||||||
|
|
||||||
|
if cnv, ok := converters[pair]; ok {
|
||||||
|
result, err := cnv.Fn(from.Interface())
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if result != nil {
|
||||||
|
to.Set(reflect.ValueOf(result))
|
||||||
|
} else {
|
||||||
|
// in case we've got a nil value to copy
|
||||||
|
to.Set(reflect.Zero(to.Type()))
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseTags Parses struct tags and returns uint8 bit flags.
|
||||||
|
func parseTags(tag string) (flg uint8, name string, err error) {
|
||||||
|
for _, t := range strings.Split(tag, ",") {
|
||||||
|
switch t {
|
||||||
|
case "-":
|
||||||
|
flg = tagIgnore
|
||||||
|
return
|
||||||
|
case "must":
|
||||||
|
flg = flg | tagMust
|
||||||
|
case "nopanic":
|
||||||
|
flg = flg | tagNoPanic
|
||||||
|
case "override":
|
||||||
|
flg = flg | tagOverride
|
||||||
|
default:
|
||||||
|
if unicode.IsUpper([]rune(t)[0]) {
|
||||||
|
name = strings.TrimSpace(t)
|
||||||
|
} else {
|
||||||
|
err = ErrFieldNameTagStartNotUpperCase
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// getTagFlags Parses struct tags for bit flags, field name.
|
||||||
|
func getFlags(dest, src reflect.Value, toType, fromType reflect.Type) (flags, error) {
|
||||||
|
flgs := flags{
|
||||||
|
BitFlags: map[string]uint8{},
|
||||||
|
SrcNames: tagNameMapping{
|
||||||
|
FieldNameToTag: map[string]string{},
|
||||||
|
TagToFieldName: map[string]string{},
|
||||||
|
},
|
||||||
|
DestNames: tagNameMapping{
|
||||||
|
FieldNameToTag: map[string]string{},
|
||||||
|
TagToFieldName: map[string]string{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var toTypeFields, fromTypeFields []reflect.StructField
|
||||||
|
if dest.IsValid() {
|
||||||
|
toTypeFields = deepFields(toType)
|
||||||
|
}
|
||||||
|
if src.IsValid() {
|
||||||
|
fromTypeFields = deepFields(fromType)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get a list dest of tags
|
||||||
|
for _, field := range toTypeFields {
|
||||||
|
tags := field.Tag.Get("copier")
|
||||||
|
if tags != "" {
|
||||||
|
var name string
|
||||||
|
var err error
|
||||||
|
if flgs.BitFlags[field.Name], name, err = parseTags(tags); err != nil {
|
||||||
|
return flags{}, err
|
||||||
|
} else if name != "" {
|
||||||
|
flgs.DestNames.FieldNameToTag[field.Name] = name
|
||||||
|
flgs.DestNames.TagToFieldName[name] = field.Name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get a list source of tags
|
||||||
|
for _, field := range fromTypeFields {
|
||||||
|
tags := field.Tag.Get("copier")
|
||||||
|
if tags != "" {
|
||||||
|
var name string
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if _, name, err = parseTags(tags); err != nil {
|
||||||
|
return flags{}, err
|
||||||
|
} else if name != "" {
|
||||||
|
flgs.SrcNames.FieldNameToTag[field.Name] = name
|
||||||
|
flgs.SrcNames.TagToFieldName[name] = field.Name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return flgs, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// checkBitFlags Checks flags for error or panic conditions.
|
||||||
|
func checkBitFlags(flagsList map[string]uint8) (err error) {
|
||||||
|
// Check flag conditions were met
|
||||||
|
for name, flgs := range flagsList {
|
||||||
|
if flgs&hasCopied == 0 {
|
||||||
|
switch {
|
||||||
|
case flgs&tagMust != 0 && flgs&tagNoPanic != 0:
|
||||||
|
err = fmt.Errorf("field %s has must tag but was not copied", name)
|
||||||
|
return
|
||||||
|
case flgs&(tagMust) != 0:
|
||||||
|
panic(fmt.Sprintf("Field %s has must tag but was not copied", name))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func getFieldName(fieldName string, flgs flags, fieldNameMapping map[string]string) (srcFieldName string, destFieldName string) {
|
||||||
|
// get dest field name
|
||||||
|
if name, ok := fieldNameMapping[fieldName]; ok {
|
||||||
|
srcFieldName = fieldName
|
||||||
|
destFieldName = name
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if srcTagName, ok := flgs.SrcNames.FieldNameToTag[fieldName]; ok {
|
||||||
|
destFieldName = srcTagName
|
||||||
|
if destTagName, ok := flgs.DestNames.TagToFieldName[srcTagName]; ok {
|
||||||
|
destFieldName = destTagName
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if destTagName, ok := flgs.DestNames.TagToFieldName[fieldName]; ok {
|
||||||
|
destFieldName = destTagName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if destFieldName == "" {
|
||||||
|
destFieldName = fieldName
|
||||||
|
}
|
||||||
|
|
||||||
|
// get source field name
|
||||||
|
if destTagName, ok := flgs.DestNames.FieldNameToTag[fieldName]; ok {
|
||||||
|
srcFieldName = destTagName
|
||||||
|
if srcField, ok := flgs.SrcNames.TagToFieldName[destTagName]; ok {
|
||||||
|
srcFieldName = srcField
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if srcField, ok := flgs.SrcNames.TagToFieldName[fieldName]; ok {
|
||||||
|
srcFieldName = srcField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if srcFieldName == "" {
|
||||||
|
srcFieldName = fieldName
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func driverValuer(v reflect.Value) (i driver.Valuer, ok bool) {
|
||||||
|
if !v.CanAddr() {
|
||||||
|
i, ok = v.Interface().(driver.Valuer)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
i, ok = v.Addr().Interface().(driver.Valuer)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func fieldByName(v reflect.Value, name string, caseSensitive bool) reflect.Value {
|
||||||
|
if caseSensitive {
|
||||||
|
return v.FieldByName(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
return v.FieldByNameFunc(func(n string) bool { return strings.EqualFold(n, name) })
|
||||||
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
package structx
|
package structx
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -11,126 +10,18 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Copy copy things,引用至copier
|
// CopyTo 将fromValue转为T类型并返回
|
||||||
func Copy(toValue any, fromValue any) (err error) {
|
func CopyTo[T any](fromValue any) T {
|
||||||
var (
|
t := NewInstance[T]()
|
||||||
isSlice bool
|
Copy(t, fromValue)
|
||||||
amount = 1
|
return t
|
||||||
from = Indirect(reflect.ValueOf(fromValue))
|
}
|
||||||
to = Indirect(reflect.ValueOf(toValue))
|
|
||||||
)
|
|
||||||
|
|
||||||
if !to.CanAddr() {
|
// CopySliceTo 将fromValue转为[]T类型并返回
|
||||||
return errors.New("copy to value is unaddressable")
|
func CopySliceTo[F, T any](fromValue []F) []T {
|
||||||
}
|
var to []T
|
||||||
|
Copy(&to, fromValue)
|
||||||
// Return is from value is invalid
|
return to
|
||||||
if !from.IsValid() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
fromType := IndirectType(from.Type())
|
|
||||||
toType := IndirectType(to.Type())
|
|
||||||
|
|
||||||
// Just set it if possible to assign
|
|
||||||
// And need to do copy anyway if the type is struct
|
|
||||||
if fromType.Kind() != reflect.Struct && from.Type().AssignableTo(to.Type()) {
|
|
||||||
to.Set(from)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if fromType.Kind() != reflect.Struct || toType.Kind() != reflect.Struct {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if to.Kind() == reflect.Slice {
|
|
||||||
isSlice = true
|
|
||||||
if from.Kind() == reflect.Slice {
|
|
||||||
amount = from.Len()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < amount; i++ {
|
|
||||||
var dest, source reflect.Value
|
|
||||||
|
|
||||||
if isSlice {
|
|
||||||
// source
|
|
||||||
if from.Kind() == reflect.Slice {
|
|
||||||
source = Indirect(from.Index(i))
|
|
||||||
} else {
|
|
||||||
source = Indirect(from)
|
|
||||||
}
|
|
||||||
// dest
|
|
||||||
dest = Indirect(reflect.New(toType).Elem())
|
|
||||||
} else {
|
|
||||||
source = Indirect(from)
|
|
||||||
dest = Indirect(to)
|
|
||||||
}
|
|
||||||
|
|
||||||
// check source
|
|
||||||
if source.IsValid() {
|
|
||||||
fromTypeFields := deepFields(fromType)
|
|
||||||
//fmt.Printf("%#v", fromTypeFields)
|
|
||||||
// Copy from field to field or method
|
|
||||||
for _, field := range fromTypeFields {
|
|
||||||
name := field.Name
|
|
||||||
|
|
||||||
if fromField := source.FieldByName(name); fromField.IsValid() {
|
|
||||||
// has field
|
|
||||||
if toField := dest.FieldByName(name); toField.IsValid() {
|
|
||||||
if toField.CanSet() {
|
|
||||||
if !set(toField, fromField) {
|
|
||||||
if err := Copy(toField.Addr().Interface(), fromField.Interface()); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// try to set to method
|
|
||||||
var toMethod reflect.Value
|
|
||||||
if dest.CanAddr() {
|
|
||||||
toMethod = dest.Addr().MethodByName(name)
|
|
||||||
} else {
|
|
||||||
toMethod = dest.MethodByName(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
if toMethod.IsValid() && toMethod.Type().NumIn() == 1 && fromField.Type().AssignableTo(toMethod.Type().In(0)) {
|
|
||||||
toMethod.Call([]reflect.Value{fromField})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy from method to field
|
|
||||||
for _, field := range deepFields(toType) {
|
|
||||||
name := field.Name
|
|
||||||
|
|
||||||
var fromMethod reflect.Value
|
|
||||||
if source.CanAddr() {
|
|
||||||
fromMethod = source.Addr().MethodByName(name)
|
|
||||||
} else {
|
|
||||||
fromMethod = source.MethodByName(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
if fromMethod.IsValid() && fromMethod.Type().NumIn() == 0 && fromMethod.Type().NumOut() == 1 {
|
|
||||||
if toField := dest.FieldByName(name); toField.IsValid() && toField.CanSet() {
|
|
||||||
values := fromMethod.Call([]reflect.Value{})
|
|
||||||
if len(values) >= 1 {
|
|
||||||
set(toField, values[0])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if isSlice {
|
|
||||||
if dest.Addr().Type().AssignableTo(to.Type().Elem()) {
|
|
||||||
to.Set(reflect.Append(to, dest.Addr()))
|
|
||||||
} else if dest.Type().AssignableTo(to.Type().Elem()) {
|
|
||||||
to.Set(reflect.Append(to, dest))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 对结构体的每个字段以及字段值执行doWith回调函数, 包括匿名属性的字段
|
// 对结构体的每个字段以及字段值执行doWith回调函数, 包括匿名属性的字段
|
||||||
@@ -158,23 +49,6 @@ func DoWithFields(str any, doWith func(fType reflect.StructField, fValue reflect
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func deepFields(reflectType reflect.Type) []reflect.StructField {
|
|
||||||
var fields []reflect.StructField
|
|
||||||
|
|
||||||
if reflectType = IndirectType(reflectType); reflectType.Kind() == reflect.Struct {
|
|
||||||
for i := 0; i < reflectType.NumField(); i++ {
|
|
||||||
v := reflectType.Field(i)
|
|
||||||
if v.Anonymous {
|
|
||||||
fields = append(fields, deepFields(v.Type)...)
|
|
||||||
} else {
|
|
||||||
fields = append(fields, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return fields
|
|
||||||
}
|
|
||||||
|
|
||||||
func Indirect(reflectValue reflect.Value) reflect.Value {
|
func Indirect(reflectValue reflect.Value) reflect.Value {
|
||||||
for reflectValue.Kind() == reflect.Ptr {
|
for reflectValue.Kind() == reflect.Ptr {
|
||||||
reflectValue = reflectValue.Elem()
|
reflectValue = reflectValue.Elem()
|
||||||
@@ -189,35 +63,6 @@ func IndirectType(reflectType reflect.Type) reflect.Type {
|
|||||||
return reflectType
|
return reflectType
|
||||||
}
|
}
|
||||||
|
|
||||||
func set(to, from reflect.Value) bool {
|
|
||||||
if from.IsValid() {
|
|
||||||
if to.Kind() == reflect.Ptr {
|
|
||||||
//set `to` to nil if from is nil
|
|
||||||
if from.Kind() == reflect.Ptr && from.IsNil() {
|
|
||||||
to.Set(reflect.Zero(to.Type()))
|
|
||||||
return true
|
|
||||||
} else if to.IsNil() {
|
|
||||||
to.Set(reflect.New(to.Type().Elem()))
|
|
||||||
}
|
|
||||||
to = to.Elem()
|
|
||||||
}
|
|
||||||
|
|
||||||
if from.Type().ConvertibleTo(to.Type()) {
|
|
||||||
to.Set(from.Convert(to.Type()))
|
|
||||||
} else if scanner, ok := to.Addr().Interface().(sql.Scanner); ok {
|
|
||||||
err := scanner.Scan(from.Interface())
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
} else if from.Kind() == reflect.Ptr {
|
|
||||||
return set(to, from.Elem())
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func Map2Struct(m map[string]any, s any) error {
|
func Map2Struct(m map[string]any, s any) error {
|
||||||
toValue := Indirect(reflect.ValueOf(s))
|
toValue := Indirect(reflect.ValueOf(s))
|
||||||
if !toValue.CanAddr() {
|
if !toValue.CanAddr() {
|
||||||
|
|||||||
Reference in New Issue
Block a user