mirror of
				https://gitee.com/dromara/mayfly-go
				synced 2025-11-04 08:20:25 +08:00 
			
		
		
		
	feat: 机器列表新增运行状态 & refactor: 登录账号信息存储与context
This commit is contained in:
		@@ -15,7 +15,7 @@
 | 
				
			|||||||
    "countup.js": "^2.7.0",
 | 
					    "countup.js": "^2.7.0",
 | 
				
			||||||
    "cropperjs": "^1.5.11",
 | 
					    "cropperjs": "^1.5.11",
 | 
				
			||||||
    "echarts": "^5.4.3",
 | 
					    "echarts": "^5.4.3",
 | 
				
			||||||
    "element-plus": "^2.4.1",
 | 
					    "element-plus": "^2.4.2",
 | 
				
			||||||
    "jsencrypt": "^3.3.1",
 | 
					    "jsencrypt": "^3.3.1",
 | 
				
			||||||
    "lodash": "^4.17.21",
 | 
					    "lodash": "^4.17.21",
 | 
				
			||||||
    "mitt": "^3.0.1",
 | 
					    "mitt": "^3.0.1",
 | 
				
			||||||
@@ -29,7 +29,7 @@
 | 
				
			|||||||
    "sortablejs": "^1.15.0",
 | 
					    "sortablejs": "^1.15.0",
 | 
				
			||||||
    "sql-formatter": "^12.1.2",
 | 
					    "sql-formatter": "^12.1.2",
 | 
				
			||||||
    "uuid": "^9.0.1",
 | 
					    "uuid": "^9.0.1",
 | 
				
			||||||
    "vue": "^3.3.7",
 | 
					    "vue": "^3.3.8",
 | 
				
			||||||
    "vue-clipboard3": "^1.0.1",
 | 
					    "vue-clipboard3": "^1.0.1",
 | 
				
			||||||
    "vue-router": "^4.2.5",
 | 
					    "vue-router": "^4.2.5",
 | 
				
			||||||
    "xterm": "^5.3.0",
 | 
					    "xterm": "^5.3.0",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -118,10 +118,10 @@ const props = defineProps({
 | 
				
			|||||||
        required: true,
 | 
					        required: true,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    // sql脚本名,若有则去加载该sql内容
 | 
					    // sql脚本名,若有则去加载该sql内容
 | 
				
			||||||
    sqlName: {
 | 
					    // sqlName: {
 | 
				
			||||||
        type: String,
 | 
					    //     type: String,
 | 
				
			||||||
        default: '',
 | 
					    //     default: '',
 | 
				
			||||||
    },
 | 
					    // },
 | 
				
			||||||
    editorHeight: {
 | 
					    editorHeight: {
 | 
				
			||||||
        type: String,
 | 
					        type: String,
 | 
				
			||||||
        default: '600',
 | 
					        default: '600',
 | 
				
			||||||
@@ -153,7 +153,7 @@ const state = reactive({
 | 
				
			|||||||
    hasUpdatedFileds: false,
 | 
					    hasUpdatedFileds: false,
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const { tableDataHeight, ti, execRes, table, loading, hasUpdatedFileds } = toRefs(state);
 | 
					const { tableDataHeight, ti, execRes, table, sqlName, loading, hasUpdatedFileds } = toRefs(state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
watch(
 | 
					watch(
 | 
				
			||||||
    () => props.editorHeight,
 | 
					    () => props.editorHeight,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -37,6 +37,36 @@
 | 
				
			|||||||
                </el-link>
 | 
					                </el-link>
 | 
				
			||||||
            </template>
 | 
					            </template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <template #stat="{ data }">
 | 
				
			||||||
 | 
					                <span v-if="!data.stat">-</span>
 | 
				
			||||||
 | 
					                <div v-else>
 | 
				
			||||||
 | 
					                    <el-row>
 | 
				
			||||||
 | 
					                        <el-text size="small" style="font-size: 10px">
 | 
				
			||||||
 | 
					                            内存(可用/总):
 | 
				
			||||||
 | 
					                            <span :class="getStatsFontClass(data.stat.memAvailable, data.stat.memTotal)"
 | 
				
			||||||
 | 
					                                >{{ formatByteSize(data.stat.memAvailable, 1) }}/{{ formatByteSize(data.stat.memTotal, 1) }}
 | 
				
			||||||
 | 
					                            </span>
 | 
				
			||||||
 | 
					                        </el-text>
 | 
				
			||||||
 | 
					                    </el-row>
 | 
				
			||||||
 | 
					                    <el-row>
 | 
				
			||||||
 | 
					                        <el-text style="font-size: 10px" size="small">
 | 
				
			||||||
 | 
					                            CPU(空闲): <span :class="getStatsFontClass(data.stat.cpuIdle, 100)">{{ data.stat.cpuIdle.toFixed(0) }}%</span>
 | 
				
			||||||
 | 
					                        </el-text>
 | 
				
			||||||
 | 
					                    </el-row>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <template #fs="{ data }">
 | 
				
			||||||
 | 
					                <span v-if="!data.stat?.fsInfos">-</span>
 | 
				
			||||||
 | 
					                <div v-else>
 | 
				
			||||||
 | 
					                    <el-row v-for="i in data.stat.fsInfos.slice(0, 2)" :key="i.mountPoint">
 | 
				
			||||||
 | 
					                        <el-text style="font-size: 10px" size="small" :class="getStatsFontClass(i.free, i.used + i.free)">
 | 
				
			||||||
 | 
					                            {{ i.mountPoint }} => {{ formatByteSize(i.free, 0) }}/{{ formatByteSize(i.used + i.free, 0) }}
 | 
				
			||||||
 | 
					                        </el-text>
 | 
				
			||||||
 | 
					                    </el-row>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <template #status="{ data }">
 | 
					            <template #status="{ data }">
 | 
				
			||||||
                <el-switch
 | 
					                <el-switch
 | 
				
			||||||
                    v-auth:disabled="'machine:update'"
 | 
					                    v-auth:disabled="'machine:update'"
 | 
				
			||||||
@@ -168,6 +198,7 @@ import TagInfo from '../component/TagInfo.vue';
 | 
				
			|||||||
import PageTable from '@/components/pagetable/PageTable.vue';
 | 
					import PageTable from '@/components/pagetable/PageTable.vue';
 | 
				
			||||||
import { TableColumn, TableQuery } from '@/components/pagetable';
 | 
					import { TableColumn, TableQuery } from '@/components/pagetable';
 | 
				
			||||||
import { hasPerms } from '@/components/auth/auth';
 | 
					import { hasPerms } from '@/components/auth/auth';
 | 
				
			||||||
 | 
					import { formatByteSize } from '@/common/utils/format';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 组件
 | 
					// 组件
 | 
				
			||||||
const TerminalDialog = defineAsyncComponent(() => import('@/components/terminal/TerminalDialog.vue'));
 | 
					const TerminalDialog = defineAsyncComponent(() => import('@/components/terminal/TerminalDialog.vue'));
 | 
				
			||||||
@@ -196,6 +227,8 @@ const columns = ref([
 | 
				
			|||||||
    TableColumn.new('tagPath', '标签路径').isSlot().setAddWidth(20),
 | 
					    TableColumn.new('tagPath', '标签路径').isSlot().setAddWidth(20),
 | 
				
			||||||
    TableColumn.new('name', '名称'),
 | 
					    TableColumn.new('name', '名称'),
 | 
				
			||||||
    TableColumn.new('ipPort', 'ip:port').isSlot().setAddWidth(50),
 | 
					    TableColumn.new('ipPort', 'ip:port').isSlot().setAddWidth(50),
 | 
				
			||||||
 | 
					    TableColumn.new('stat', '运行状态').isSlot().setAddWidth(50),
 | 
				
			||||||
 | 
					    TableColumn.new('fs', '磁盘(挂载点=>可用/总)').isSlot().setAddWidth(20),
 | 
				
			||||||
    TableColumn.new('username', '用户名'),
 | 
					    TableColumn.new('username', '用户名'),
 | 
				
			||||||
    TableColumn.new('status', '状态').isSlot().setMinWidth(85),
 | 
					    TableColumn.new('status', '状态').isSlot().setMinWidth(85),
 | 
				
			||||||
    TableColumn.new('remark', '备注'),
 | 
					    TableColumn.new('remark', '备注'),
 | 
				
			||||||
@@ -408,6 +441,18 @@ const search = async () => {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const getStatsFontClass = (availavle: number, total: number) => {
 | 
				
			||||||
 | 
					    const p = availavle / total;
 | 
				
			||||||
 | 
					    if (p < 0.1) {
 | 
				
			||||||
 | 
					        return 'color-danger';
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (p < 0.2) {
 | 
				
			||||||
 | 
					        return 'color-warning';
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 'color-success';
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const showInfo = (info: any) => {
 | 
					const showInfo = (info: any) => {
 | 
				
			||||||
    state.infoDialog.data = info;
 | 
					    state.infoDialog.data = info;
 | 
				
			||||||
    state.infoDialog.visible = true;
 | 
					    state.infoDialog.visible = true;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,18 +8,18 @@
 | 
				
			|||||||
                            <el-link @click="onRefresh" icon="refresh" :underline="false" type="success"></el-link>
 | 
					                            <el-link @click="onRefresh" icon="refresh" :underline="false" type="success"></el-link>
 | 
				
			||||||
                        </template>
 | 
					                        </template>
 | 
				
			||||||
                        <el-descriptions-item label="主机名">
 | 
					                        <el-descriptions-item label="主机名">
 | 
				
			||||||
                            {{ stats.Hostname }}
 | 
					                            {{ stats.hostname }}
 | 
				
			||||||
                        </el-descriptions-item>
 | 
					                        </el-descriptions-item>
 | 
				
			||||||
                        <el-descriptions-item label="运行时间">
 | 
					                        <el-descriptions-item label="运行时间">
 | 
				
			||||||
                            {{ stats.Uptime }}
 | 
					                            {{ stats.uptime }}
 | 
				
			||||||
                        </el-descriptions-item>
 | 
					                        </el-descriptions-item>
 | 
				
			||||||
                        <el-descriptions-item label="总任务">
 | 
					                        <el-descriptions-item label="总任务">
 | 
				
			||||||
                            {{ stats.TotalProcs }}
 | 
					                            {{ stats.totalProcs }}
 | 
				
			||||||
                        </el-descriptions-item>
 | 
					                        </el-descriptions-item>
 | 
				
			||||||
                        <el-descriptions-item label="运行中任务">
 | 
					                        <el-descriptions-item label="运行中任务">
 | 
				
			||||||
                            {{ stats.RunningProcs }}
 | 
					                            {{ stats.runningProcs }}
 | 
				
			||||||
                        </el-descriptions-item>
 | 
					                        </el-descriptions-item>
 | 
				
			||||||
                        <el-descriptions-item label="负载"> {{ stats.Load1 }} {{ stats.Load5 }} {{ stats.Load10 }} </el-descriptions-item>
 | 
					                        <el-descriptions-item label="负载"> {{ stats.load1 }} {{ stats.load5 }} {{ stats.load10 }} </el-descriptions-item>
 | 
				
			||||||
                    </el-descriptions>
 | 
					                    </el-descriptions>
 | 
				
			||||||
                </el-col>
 | 
					                </el-col>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -35,16 +35,16 @@
 | 
				
			|||||||
            <el-row :gutter="20">
 | 
					            <el-row :gutter="20">
 | 
				
			||||||
                <el-col :lg="8" :md="8">
 | 
					                <el-col :lg="8" :md="8">
 | 
				
			||||||
                    <span style="font-size: 16px; font-weight: 700">磁盘</span>
 | 
					                    <span style="font-size: 16px; font-weight: 700">磁盘</span>
 | 
				
			||||||
                    <el-table :data="stats.FSInfos" stripe max-height="250" style="width: 100%" border>
 | 
					                    <el-table :data="stats.fSInfos" stripe max-height="250" style="width: 100%" border>
 | 
				
			||||||
                        <el-table-column prop="MountPoint" label="挂载点" min-width="100" show-overflow-tooltip> </el-table-column>
 | 
					                        <el-table-column prop="mountPoint" label="挂载点" min-width="100" show-overflow-tooltip> </el-table-column>
 | 
				
			||||||
                        <el-table-column prop="Used" label="可使用" min-width="70" show-overflow-tooltip>
 | 
					                        <el-table-column prop="used" label="可使用" min-width="70" show-overflow-tooltip>
 | 
				
			||||||
                            <template #default="scope">
 | 
					                            <template #default="scope">
 | 
				
			||||||
                                {{ formatByteSize(scope.row.Free) }}
 | 
					                                {{ formatByteSize(scope.row.free) }}
 | 
				
			||||||
                            </template>
 | 
					                            </template>
 | 
				
			||||||
                        </el-table-column>
 | 
					                        </el-table-column>
 | 
				
			||||||
                        <el-table-column prop="Used" label="已使用" min-width="70" show-overflow-tooltip>
 | 
					                        <el-table-column prop="Used" label="已使用" min-width="70" show-overflow-tooltip>
 | 
				
			||||||
                            <template #default="scope">
 | 
					                            <template #default="scope">
 | 
				
			||||||
                                {{ formatByteSize(scope.row.Used) }}
 | 
					                                {{ formatByteSize(scope.row.used) }}
 | 
				
			||||||
                            </template>
 | 
					                            </template>
 | 
				
			||||||
                        </el-table-column>
 | 
					                        </el-table-column>
 | 
				
			||||||
                    </el-table>
 | 
					                    </el-table>
 | 
				
			||||||
@@ -54,16 +54,16 @@
 | 
				
			|||||||
                    <span style="font-size: 16px; font-weight: 700">网卡</span>
 | 
					                    <span style="font-size: 16px; font-weight: 700">网卡</span>
 | 
				
			||||||
                    <el-table :data="netInter" stripe max-height="250" style="width: 100%" border>
 | 
					                    <el-table :data="netInter" stripe max-height="250" style="width: 100%" border>
 | 
				
			||||||
                        <el-table-column prop="name" label="网卡" min-width="120" show-overflow-tooltip></el-table-column>
 | 
					                        <el-table-column prop="name" label="网卡" min-width="120" show-overflow-tooltip></el-table-column>
 | 
				
			||||||
                        <el-table-column prop="IPv4" label="IPv4" min-width="130" show-overflow-tooltip> </el-table-column>
 | 
					                        <el-table-column prop="ipv4" label="IPv4" min-width="130" show-overflow-tooltip> </el-table-column>
 | 
				
			||||||
                        <el-table-column prop="IPv6" label="IPv6" min-width="130" show-overflow-tooltip> </el-table-column>
 | 
					                        <el-table-column prop="ipv6" label="IPv6" min-width="130" show-overflow-tooltip> </el-table-column>
 | 
				
			||||||
                        <el-table-column prop="Rx" label="接收(rx)" min-width="110" show-overflow-tooltip>
 | 
					                        <el-table-column prop="rx" label="接收(rx)" min-width="110" show-overflow-tooltip>
 | 
				
			||||||
                            <template #default="scope">
 | 
					                            <template #default="scope">
 | 
				
			||||||
                                {{ formatByteSize(scope.row.Rx) }}
 | 
					                                {{ formatByteSize(scope.row.rx) }}
 | 
				
			||||||
                            </template>
 | 
					                            </template>
 | 
				
			||||||
                        </el-table-column>
 | 
					                        </el-table-column>
 | 
				
			||||||
                        <el-table-column prop="Tx" label="发送(tx)" min-width="110" show-overflow-tooltip>
 | 
					                        <el-table-column prop="tx" label="发送(tx)" min-width="110" show-overflow-tooltip>
 | 
				
			||||||
                            <template #default="scope">
 | 
					                            <template #default="scope">
 | 
				
			||||||
                                {{ formatByteSize(scope.row.Tx) }}
 | 
					                                {{ formatByteSize(scope.row.tx) }}
 | 
				
			||||||
                            </template>
 | 
					                            </template>
 | 
				
			||||||
                        </el-table-column>
 | 
					                        </el-table-column>
 | 
				
			||||||
                    </el-table>
 | 
					                    </el-table>
 | 
				
			||||||
@@ -84,9 +84,6 @@ const props = defineProps({
 | 
				
			|||||||
    visible: {
 | 
					    visible: {
 | 
				
			||||||
        type: Boolean,
 | 
					        type: Boolean,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    stats: {
 | 
					 | 
				
			||||||
        type: Object,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    machineId: {
 | 
					    machineId: {
 | 
				
			||||||
        type: Number,
 | 
					        type: Number,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
@@ -134,11 +131,12 @@ const onRefresh = async () => {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const initMemStats = () => {
 | 
					const initMemStats = () => {
 | 
				
			||||||
 | 
					    const mem = state.stats.memInfo;
 | 
				
			||||||
    const data = [
 | 
					    const data = [
 | 
				
			||||||
        { name: '可用内存', value: state.stats.MemAvailable },
 | 
					        { name: '可用内存', value: mem.available },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            name: '已用内存',
 | 
					            name: '已用内存',
 | 
				
			||||||
            value: state.stats.MemTotal - state.stats.MemAvailable,
 | 
					            value: mem.total - mem.available,
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
    ];
 | 
					    ];
 | 
				
			||||||
    const option = {
 | 
					    const option = {
 | 
				
			||||||
@@ -192,20 +190,20 @@ const initMemStats = () => {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const initCpuStats = () => {
 | 
					const initCpuStats = () => {
 | 
				
			||||||
    const cpu = state.stats.CPU;
 | 
					    const cpu = state.stats.cpu;
 | 
				
			||||||
    const data = [
 | 
					    const data = [
 | 
				
			||||||
        { name: 'Idle', value: cpu.Idle },
 | 
					        { name: 'Idle', value: cpu.idle },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            name: 'Iowait',
 | 
					            name: 'Iowait',
 | 
				
			||||||
            value: cpu.Iowait,
 | 
					            value: cpu.iowait,
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            name: 'System',
 | 
					            name: 'System',
 | 
				
			||||||
            value: cpu.System,
 | 
					            value: cpu.system,
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            name: 'User',
 | 
					            name: 'User',
 | 
				
			||||||
            value: cpu.User,
 | 
					            value: cpu.user,
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
    ];
 | 
					    ];
 | 
				
			||||||
    const option = {
 | 
					    const option = {
 | 
				
			||||||
@@ -283,7 +281,7 @@ const initEchartsResize = () => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const parseNetInter = () => {
 | 
					const parseNetInter = () => {
 | 
				
			||||||
    state.netInter = [];
 | 
					    state.netInter = [];
 | 
				
			||||||
    const netInter = state.stats.NetIntf;
 | 
					    const netInter = state.stats.netIntf;
 | 
				
			||||||
    const keys = Object.keys(netInter);
 | 
					    const keys = Object.keys(netInter);
 | 
				
			||||||
    const values = Object.values(netInter);
 | 
					    const values = Object.values(netInter);
 | 
				
			||||||
    for (let i = 0; i < values.length; i++) {
 | 
					    for (let i = 0; i < values.length; i++) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -390,13 +390,13 @@
 | 
				
			|||||||
    estree-walker "^2.0.2"
 | 
					    estree-walker "^2.0.2"
 | 
				
			||||||
    source-map-js "^1.0.2"
 | 
					    source-map-js "^1.0.2"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"@vue/compiler-core@3.3.7":
 | 
					"@vue/compiler-core@3.3.8":
 | 
				
			||||||
  version "3.3.7"
 | 
					  version "3.3.8"
 | 
				
			||||||
  resolved "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.3.7.tgz#865a5734c971686d9737d85a0c5a08de045b6162"
 | 
					  resolved "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.3.8.tgz#301bb60d0245265a88ed5b30e200fbf223acb313"
 | 
				
			||||||
  integrity sha512-pACdY6YnTNVLXsB86YD8OF9ihwpolzhhtdLVHhBL6do/ykr6kKXNYABRtNMGrsQXpEXXyAdwvWWkuTbs4MFtPQ==
 | 
					  integrity sha512-hN/NNBUECw8SusQvDSqqcVv6gWq8L6iAktUR0UF3vGu2OhzRqcOiAno0FmBJWwxhYEXRlQJT5XnoKsVq1WZx4g==
 | 
				
			||||||
  dependencies:
 | 
					  dependencies:
 | 
				
			||||||
    "@babel/parser" "^7.23.0"
 | 
					    "@babel/parser" "^7.23.0"
 | 
				
			||||||
    "@vue/shared" "3.3.7"
 | 
					    "@vue/shared" "3.3.8"
 | 
				
			||||||
    estree-walker "^2.0.2"
 | 
					    estree-walker "^2.0.2"
 | 
				
			||||||
    source-map-js "^1.0.2"
 | 
					    source-map-js "^1.0.2"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -408,25 +408,25 @@
 | 
				
			|||||||
    "@vue/compiler-core" "3.3.4"
 | 
					    "@vue/compiler-core" "3.3.4"
 | 
				
			||||||
    "@vue/shared" "3.3.4"
 | 
					    "@vue/shared" "3.3.4"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"@vue/compiler-dom@3.3.7":
 | 
					"@vue/compiler-dom@3.3.8":
 | 
				
			||||||
  version "3.3.7"
 | 
					  version "3.3.8"
 | 
				
			||||||
  resolved "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.3.7.tgz#a245aa03f9bfcdb537a239bf02842072de0644c9"
 | 
					  resolved "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.3.8.tgz#09d832514b9b8d9415a3816b065d69dbefcc7e9b"
 | 
				
			||||||
  integrity sha512-0LwkyJjnUPssXv/d1vNJ0PKfBlDoQs7n81CbO6Q0zdL7H1EzqYRrTVXDqdBVqro0aJjo/FOa1qBAPVI4PGSHBw==
 | 
					  integrity sha512-+PPtv+p/nWDd0AvJu3w8HS0RIm/C6VGBIRe24b9hSyNWOAPEUosFZ5diwawwP8ip5sJ8n0Pe87TNNNHnvjs0FQ==
 | 
				
			||||||
  dependencies:
 | 
					  dependencies:
 | 
				
			||||||
    "@vue/compiler-core" "3.3.7"
 | 
					    "@vue/compiler-core" "3.3.8"
 | 
				
			||||||
    "@vue/shared" "3.3.7"
 | 
					    "@vue/shared" "3.3.8"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"@vue/compiler-sfc@3.3.7":
 | 
					"@vue/compiler-sfc@3.3.8":
 | 
				
			||||||
  version "3.3.7"
 | 
					  version "3.3.8"
 | 
				
			||||||
  resolved "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.3.7.tgz#219d04b3013c7b15fbc536e2279e07810b731cc2"
 | 
					  resolved "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.3.8.tgz#40b18e48aa00260950964d1d72157668521be0e1"
 | 
				
			||||||
  integrity sha512-7pfldWy/J75U/ZyYIXRVqvLRw3vmfxDo2YLMwVtWVNew8Sm8d6wodM+OYFq4ll/UxfqVr0XKiVwti32PCrruAw==
 | 
					  integrity sha512-WMzbUrlTjfYF8joyT84HfwwXo+8WPALuPxhy+BZ6R4Aafls+jDBnSz8PDz60uFhuqFbl3HxRfxvDzrUf3THwpA==
 | 
				
			||||||
  dependencies:
 | 
					  dependencies:
 | 
				
			||||||
    "@babel/parser" "^7.23.0"
 | 
					    "@babel/parser" "^7.23.0"
 | 
				
			||||||
    "@vue/compiler-core" "3.3.7"
 | 
					    "@vue/compiler-core" "3.3.8"
 | 
				
			||||||
    "@vue/compiler-dom" "3.3.7"
 | 
					    "@vue/compiler-dom" "3.3.8"
 | 
				
			||||||
    "@vue/compiler-ssr" "3.3.7"
 | 
					    "@vue/compiler-ssr" "3.3.8"
 | 
				
			||||||
    "@vue/reactivity-transform" "3.3.7"
 | 
					    "@vue/reactivity-transform" "3.3.8"
 | 
				
			||||||
    "@vue/shared" "3.3.7"
 | 
					    "@vue/shared" "3.3.8"
 | 
				
			||||||
    estree-walker "^2.0.2"
 | 
					    estree-walker "^2.0.2"
 | 
				
			||||||
    magic-string "^0.30.5"
 | 
					    magic-string "^0.30.5"
 | 
				
			||||||
    postcss "^8.4.31"
 | 
					    postcss "^8.4.31"
 | 
				
			||||||
@@ -456,13 +456,13 @@
 | 
				
			|||||||
    "@vue/compiler-dom" "3.3.4"
 | 
					    "@vue/compiler-dom" "3.3.4"
 | 
				
			||||||
    "@vue/shared" "3.3.4"
 | 
					    "@vue/shared" "3.3.4"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"@vue/compiler-ssr@3.3.7":
 | 
					"@vue/compiler-ssr@3.3.8":
 | 
				
			||||||
  version "3.3.7"
 | 
					  version "3.3.8"
 | 
				
			||||||
  resolved "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.3.7.tgz#eff4a70f7ceb800d60e68d208b96a030c0f1b636"
 | 
					  resolved "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.3.8.tgz#136eed54411e4694815d961048a237191063fbce"
 | 
				
			||||||
  integrity sha512-TxOfNVVeH3zgBc82kcUv+emNHo+vKnlRrkv8YvQU5+Y5LJGJwSNzcmLUoxD/dNzv0bhQ/F0s+InlgV0NrApJZg==
 | 
					  integrity sha512-hXCqQL/15kMVDBuoBYpUnSYT8doDNwsjvm3jTefnXr+ytn294ySnT8NlsFHmTgKNjwpuFy7XVV8yTeLtNl/P6w==
 | 
				
			||||||
  dependencies:
 | 
					  dependencies:
 | 
				
			||||||
    "@vue/compiler-dom" "3.3.7"
 | 
					    "@vue/compiler-dom" "3.3.8"
 | 
				
			||||||
    "@vue/shared" "3.3.7"
 | 
					    "@vue/shared" "3.3.8"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"@vue/devtools-api@^6.5.0":
 | 
					"@vue/devtools-api@^6.5.0":
 | 
				
			||||||
  version "6.5.0"
 | 
					  version "6.5.0"
 | 
				
			||||||
@@ -480,58 +480,58 @@
 | 
				
			|||||||
    estree-walker "^2.0.2"
 | 
					    estree-walker "^2.0.2"
 | 
				
			||||||
    magic-string "^0.30.0"
 | 
					    magic-string "^0.30.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"@vue/reactivity-transform@3.3.7":
 | 
					"@vue/reactivity-transform@3.3.8":
 | 
				
			||||||
  version "3.3.7"
 | 
					  version "3.3.8"
 | 
				
			||||||
  resolved "https://registry.npmmirror.com/@vue/reactivity-transform/-/reactivity-transform-3.3.7.tgz#eb9f5110af5085079b851d162205394bc790d539"
 | 
					  resolved "https://registry.npmmirror.com/@vue/reactivity-transform/-/reactivity-transform-3.3.8.tgz#6d07649013b0be5c670f0ab6cc7ddd3150ad03f2"
 | 
				
			||||||
  integrity sha512-APhRmLVbgE1VPGtoLQoWBJEaQk4V8JUsqrQihImVqKT+8U6Qi3t5ATcg4Y9wGAPb3kIhetpufyZ1RhwbZCIdDA==
 | 
					  integrity sha512-49CvBzmZNtcHua0XJ7GdGifM8GOXoUMOX4dD40Y5DxI3R8OUhMlvf2nvgUAcPxaXiV5MQQ1Nwy09ADpnLQUqRw==
 | 
				
			||||||
  dependencies:
 | 
					  dependencies:
 | 
				
			||||||
    "@babel/parser" "^7.23.0"
 | 
					    "@babel/parser" "^7.23.0"
 | 
				
			||||||
    "@vue/compiler-core" "3.3.7"
 | 
					    "@vue/compiler-core" "3.3.8"
 | 
				
			||||||
    "@vue/shared" "3.3.7"
 | 
					    "@vue/shared" "3.3.8"
 | 
				
			||||||
    estree-walker "^2.0.2"
 | 
					    estree-walker "^2.0.2"
 | 
				
			||||||
    magic-string "^0.30.5"
 | 
					    magic-string "^0.30.5"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"@vue/reactivity@3.3.7":
 | 
					"@vue/reactivity@3.3.8":
 | 
				
			||||||
  version "3.3.7"
 | 
					  version "3.3.8"
 | 
				
			||||||
  resolved "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.3.7.tgz#48b6671a45ba33039da2c0eb25ae702f924486a9"
 | 
					  resolved "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.3.8.tgz#cce8a03a3fd3539c3eeda53e277ba365d160dd4d"
 | 
				
			||||||
  integrity sha512-cZNVjWiw00708WqT0zRpyAgduG79dScKEPYJXq2xj/aMtk3SKvL3FBt2QKUlh6EHBJ1m8RhBY+ikBUzwc7/khg==
 | 
					  integrity sha512-ctLWitmFBu6mtddPyOKpHg8+5ahouoTCRtmAHZAXmolDtuZXfjL2T3OJ6DL6ezBPQB1SmMnpzjiWjCiMYmpIuw==
 | 
				
			||||||
  dependencies:
 | 
					  dependencies:
 | 
				
			||||||
    "@vue/shared" "3.3.7"
 | 
					    "@vue/shared" "3.3.8"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"@vue/runtime-core@3.3.7":
 | 
					"@vue/runtime-core@3.3.8":
 | 
				
			||||||
  version "3.3.7"
 | 
					  version "3.3.8"
 | 
				
			||||||
  resolved "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.3.7.tgz#c1eece1c98f936dc69dd0667d11b464579b128fd"
 | 
					  resolved "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.3.8.tgz#fba5a632cbf2b5d29e171489570149cb6975dcdb"
 | 
				
			||||||
  integrity sha512-LHq9du3ubLZFdK/BP0Ysy3zhHqRfBn80Uc+T5Hz3maFJBGhci1MafccnL3rpd5/3wVfRHAe6c+PnlO2PAavPTQ==
 | 
					  integrity sha512-qurzOlb6q26KWQ/8IShHkMDOuJkQnQcTIp1sdP4I9MbCf9FJeGVRXJFr2mF+6bXh/3Zjr9TDgURXrsCr9bfjUw==
 | 
				
			||||||
  dependencies:
 | 
					  dependencies:
 | 
				
			||||||
    "@vue/reactivity" "3.3.7"
 | 
					    "@vue/reactivity" "3.3.8"
 | 
				
			||||||
    "@vue/shared" "3.3.7"
 | 
					    "@vue/shared" "3.3.8"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"@vue/runtime-dom@3.3.7":
 | 
					"@vue/runtime-dom@3.3.8":
 | 
				
			||||||
  version "3.3.7"
 | 
					  version "3.3.8"
 | 
				
			||||||
  resolved "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.3.7.tgz#e7cf88cc01591fdf6e3164825554fdadc3137ffc"
 | 
					  resolved "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.3.8.tgz#e2d7aa795cf50914dda9a951887765a594b38af4"
 | 
				
			||||||
  integrity sha512-PFQU1oeJxikdDmrfoNQay5nD4tcPNYixUBruZzVX/l0eyZvFKElZUjW4KctCcs52nnpMGO6UDK+jF5oV4GT5Lw==
 | 
					  integrity sha512-Noy5yM5UIf9UeFoowBVgghyGGPIDPy1Qlqt0yVsUdAVbqI8eeMSsTqBtauaEoT2UFXUk5S64aWVNJN4MJ2vRdA==
 | 
				
			||||||
  dependencies:
 | 
					  dependencies:
 | 
				
			||||||
    "@vue/runtime-core" "3.3.7"
 | 
					    "@vue/runtime-core" "3.3.8"
 | 
				
			||||||
    "@vue/shared" "3.3.7"
 | 
					    "@vue/shared" "3.3.8"
 | 
				
			||||||
    csstype "^3.1.2"
 | 
					    csstype "^3.1.2"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"@vue/server-renderer@3.3.7":
 | 
					"@vue/server-renderer@3.3.8":
 | 
				
			||||||
  version "3.3.7"
 | 
					  version "3.3.8"
 | 
				
			||||||
  resolved "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.3.7.tgz#0cc3dc6ad39a54693e6e8f853caa3c7bb43b0364"
 | 
					  resolved "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.3.8.tgz#9b1779010e75783edeed8fcfb97d9c95fc3ac5d2"
 | 
				
			||||||
  integrity sha512-UlpKDInd1hIZiNuVVVvLgxpfnSouxKQOSE2bOfQpBuGwxRV/JqqTCyyjXUWiwtVMyeRaZhOYYqntxElk8FhBhw==
 | 
					  integrity sha512-zVCUw7RFskvPuNlPn/8xISbrf0zTWsTSdYTsUTN1ERGGZGVnRxM2QZ3x1OR32+vwkkCm0IW6HmJ49IsPm7ilLg==
 | 
				
			||||||
  dependencies:
 | 
					  dependencies:
 | 
				
			||||||
    "@vue/compiler-ssr" "3.3.7"
 | 
					    "@vue/compiler-ssr" "3.3.8"
 | 
				
			||||||
    "@vue/shared" "3.3.7"
 | 
					    "@vue/shared" "3.3.8"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"@vue/shared@3.3.4":
 | 
					"@vue/shared@3.3.4":
 | 
				
			||||||
  version "3.3.4"
 | 
					  version "3.3.4"
 | 
				
			||||||
  resolved "https://registry.npmmirror.com/@vue/shared/-/shared-3.3.4.tgz#06e83c5027f464eef861c329be81454bc8b70780"
 | 
					  resolved "https://registry.npmmirror.com/@vue/shared/-/shared-3.3.4.tgz#06e83c5027f464eef861c329be81454bc8b70780"
 | 
				
			||||||
  integrity sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==
 | 
					  integrity sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"@vue/shared@3.3.7":
 | 
					"@vue/shared@3.3.8":
 | 
				
			||||||
  version "3.3.7"
 | 
					  version "3.3.8"
 | 
				
			||||||
  resolved "https://registry.npmmirror.com/@vue/shared/-/shared-3.3.7.tgz#0091852fe5cc4237c8440fe32f3ab6bc920ae6d9"
 | 
					  resolved "https://registry.npmmirror.com/@vue/shared/-/shared-3.3.8.tgz#f044942142e1d3a395f24132e6203a784838542d"
 | 
				
			||||||
  integrity sha512-N/tbkINRUDExgcPTBvxNkvHGu504k8lzlNQRITVnm6YjOjwa4r0nnbd4Jb01sNpur5hAllyRJzSK5PvB9PPwRg==
 | 
					  integrity sha512-8PGwybFwM4x8pcfgqEQFy70NaQxASvOC5DJwLQfpArw1UDfUXrJkdxD3BhVTMS+0Lef/TU7YO0Jvr0jJY8T+mw==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"@vueuse/core@^9.1.0":
 | 
					"@vueuse/core@^9.1.0":
 | 
				
			||||||
  version "9.2.0"
 | 
					  version "9.2.0"
 | 
				
			||||||
@@ -841,10 +841,10 @@ echarts@^5.4.3:
 | 
				
			|||||||
    tslib "2.3.0"
 | 
					    tslib "2.3.0"
 | 
				
			||||||
    zrender "5.4.4"
 | 
					    zrender "5.4.4"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
element-plus@^2.4.1:
 | 
					element-plus@^2.4.2:
 | 
				
			||||||
  version "2.4.1"
 | 
					  version "2.4.2"
 | 
				
			||||||
  resolved "https://registry.npmmirror.com/element-plus/-/element-plus-2.4.1.tgz#8a5faa69e856d82494b94d77fb485d9e727c8bc1"
 | 
					  resolved "https://registry.npmmirror.com/element-plus/-/element-plus-2.4.2.tgz#2a24632e0904ccd7bbbd64c269704f6b9969833c"
 | 
				
			||||||
  integrity sha512-t7nl+vQlkBKVk1Ag6AufSDyFV8YIXxTFsaya4Nz/0tiRlcz65WPN4WMFeNURuFJleu1HLNtP4YyQKMuS7El8uA==
 | 
					  integrity sha512-E/HwXX7JF1LPvQSjs0fZ8WblIoc0quoXsRXQZiL7QDq7xJdNGSUaXtdk7xiEv7axPmLfEFtxE5du9fFspDrmJw==
 | 
				
			||||||
  dependencies:
 | 
					  dependencies:
 | 
				
			||||||
    "@ctrl/tinycolor" "^3.4.1"
 | 
					    "@ctrl/tinycolor" "^3.4.1"
 | 
				
			||||||
    "@element-plus/icons-vue" "^2.0.6"
 | 
					    "@element-plus/icons-vue" "^2.0.6"
 | 
				
			||||||
@@ -1912,16 +1912,16 @@ vue-router@^4.2.5:
 | 
				
			|||||||
  dependencies:
 | 
					  dependencies:
 | 
				
			||||||
    "@vue/devtools-api" "^6.5.0"
 | 
					    "@vue/devtools-api" "^6.5.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
vue@^3.3.7:
 | 
					vue@^3.3.8:
 | 
				
			||||||
  version "3.3.7"
 | 
					  version "3.3.8"
 | 
				
			||||||
  resolved "https://registry.npmmirror.com/vue/-/vue-3.3.7.tgz#972a218682443a3819d121261b2bff914417f4f0"
 | 
					  resolved "https://registry.npmmirror.com/vue/-/vue-3.3.8.tgz#532ff071af24f6a69e5ecc53a66858a9ee874ffc"
 | 
				
			||||||
  integrity sha512-YEMDia1ZTv1TeBbnu6VybatmSteGOS3A3YgfINOfraCbf85wdKHzscD6HSS/vB4GAtI7sa1XPX7HcQaJ1l24zA==
 | 
					  integrity sha512-5VSX/3DabBikOXMsxzlW8JyfeLKlG9mzqnWgLQLty88vdZL7ZJgrdgBOmrArwxiLtmS+lNNpPcBYqrhE6TQW5w==
 | 
				
			||||||
  dependencies:
 | 
					  dependencies:
 | 
				
			||||||
    "@vue/compiler-dom" "3.3.7"
 | 
					    "@vue/compiler-dom" "3.3.8"
 | 
				
			||||||
    "@vue/compiler-sfc" "3.3.7"
 | 
					    "@vue/compiler-sfc" "3.3.8"
 | 
				
			||||||
    "@vue/runtime-dom" "3.3.7"
 | 
					    "@vue/runtime-dom" "3.3.8"
 | 
				
			||||||
    "@vue/server-renderer" "3.3.7"
 | 
					    "@vue/server-renderer" "3.3.8"
 | 
				
			||||||
    "@vue/shared" "3.3.7"
 | 
					    "@vue/shared" "3.3.8"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
which@^2.0.1:
 | 
					which@^2.0.1:
 | 
				
			||||||
  version "2.0.2"
 | 
					  version "2.0.2"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
package api
 | 
					package api
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
	"encoding/json"
 | 
						"encoding/json"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"mayfly-go/internal/auth/api/form"
 | 
						"mayfly-go/internal/auth/api/form"
 | 
				
			||||||
@@ -107,7 +108,7 @@ func (a *AccountLogin) OtpVerify(rc *req.Ctx) {
 | 
				
			|||||||
		update := &sysentity.Account{OtpSecret: otpSecret}
 | 
							update := &sysentity.Account{OtpSecret: otpSecret}
 | 
				
			||||||
		update.Id = accountId
 | 
							update.Id = accountId
 | 
				
			||||||
		update.OtpSecretEncrypt()
 | 
							update.OtpSecretEncrypt()
 | 
				
			||||||
		biz.ErrIsNil(a.AccountApp.Update(update))
 | 
							biz.ErrIsNil(a.AccountApp.Update(context.Background(), update))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	la := &sysentity.Account{Username: otpInfo.Username}
 | 
						la := &sysentity.Account{Username: otpInfo.Username}
 | 
				
			||||||
@@ -119,6 +120,7 @@ func (a *AccountLogin) OtpVerify(rc *req.Ctx) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (a *AccountLogin) Logout(rc *req.Ctx) {
 | 
					func (a *AccountLogin) Logout(rc *req.Ctx) {
 | 
				
			||||||
	req.GetPermissionCodeRegistery().Remove(rc.LoginAccount.Id)
 | 
						la := rc.GetLoginAccount()
 | 
				
			||||||
	ws.CloseClient(ws.UserId(rc.LoginAccount.Id))
 | 
						req.GetPermissionCodeRegistery().Remove(la.Id)
 | 
				
			||||||
 | 
						ws.CloseClient(ws.UserId(la.Id))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
package api
 | 
					package api
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"mayfly-go/internal/auth/config"
 | 
						"mayfly-go/internal/auth/config"
 | 
				
			||||||
	msgapp "mayfly-go/internal/msg/application"
 | 
						msgapp "mayfly-go/internal/msg/application"
 | 
				
			||||||
@@ -108,7 +109,7 @@ func saveLogin(account *sysentity.Account, ip string) {
 | 
				
			|||||||
	updateAccount.Id = account.Id
 | 
						updateAccount.Id = account.Id
 | 
				
			||||||
	updateAccount.LastLoginIp = ip
 | 
						updateAccount.LastLoginIp = ip
 | 
				
			||||||
	// 偷懒为了方便直接获取accountApp
 | 
						// 偷懒为了方便直接获取accountApp
 | 
				
			||||||
	biz.ErrIsNil(sysapp.GetAccountApp().Update(updateAccount))
 | 
						biz.ErrIsNil(sysapp.GetAccountApp().Update(context.TODO(), updateAccount))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 创建登录消息
 | 
						// 创建登录消息
 | 
				
			||||||
	loginMsg := &msgentity.Msg{
 | 
						loginMsg := &msgentity.Msg{
 | 
				
			||||||
@@ -119,5 +120,5 @@ func saveLogin(account *sysentity.Account, ip string) {
 | 
				
			|||||||
	loginMsg.CreateTime = &now
 | 
						loginMsg.CreateTime = &now
 | 
				
			||||||
	loginMsg.Creator = account.Username
 | 
						loginMsg.Creator = account.Username
 | 
				
			||||||
	loginMsg.CreatorId = account.Id
 | 
						loginMsg.CreatorId = account.Id
 | 
				
			||||||
	msgapp.GetMsgApp().Create(loginMsg)
 | 
						msgapp.GetMsgApp().Create(context.TODO(), loginMsg)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
package api
 | 
					package api
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
	"crypto/tls"
 | 
						"crypto/tls"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"mayfly-go/internal/auth/api/form"
 | 
						"mayfly-go/internal/auth/api/form"
 | 
				
			||||||
@@ -88,10 +89,10 @@ func (a *LdapLogin) createUser(userName, displayName string) {
 | 
				
			|||||||
	account := &sysentity.Account{Username: userName}
 | 
						account := &sysentity.Account{Username: userName}
 | 
				
			||||||
	account.SetBaseInfo(nil)
 | 
						account.SetBaseInfo(nil)
 | 
				
			||||||
	account.Name = displayName
 | 
						account.Name = displayName
 | 
				
			||||||
	biz.ErrIsNil(a.AccountApp.Create(account))
 | 
						biz.ErrIsNil(a.AccountApp.Create(context.TODO(), account))
 | 
				
			||||||
	// 将 LADP 用户本地密码设置为空,不允许本地登录
 | 
						// 将 LADP 用户本地密码设置为空,不允许本地登录
 | 
				
			||||||
	account.Password = cryptox.PwdHash("")
 | 
						account.Password = cryptox.PwdHash("")
 | 
				
			||||||
	biz.ErrIsNil(a.AccountApp.Update(account))
 | 
						biz.ErrIsNil(a.AccountApp.Update(context.TODO(), account))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (a *LdapLogin) getOrCreateUserWithLdap(userName string, password string, cols ...string) (*sysentity.Account, error) {
 | 
					func (a *LdapLogin) getOrCreateUserWithLdap(userName string, password string, cols ...string) (*sysentity.Account, error) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
package api
 | 
					package api
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"io"
 | 
						"io"
 | 
				
			||||||
	"mayfly-go/internal/auth/api/vo"
 | 
						"mayfly-go/internal/auth/api/vo"
 | 
				
			||||||
@@ -42,7 +43,7 @@ func (a *Oauth2Login) OAuth2Login(rc *req.Ctx) {
 | 
				
			|||||||
func (a *Oauth2Login) OAuth2Bind(rc *req.Ctx) {
 | 
					func (a *Oauth2Login) OAuth2Bind(rc *req.Ctx) {
 | 
				
			||||||
	client, _ := a.getOAuthClient()
 | 
						client, _ := a.getOAuthClient()
 | 
				
			||||||
	state := stringx.Rand(32)
 | 
						state := stringx.Rand(32)
 | 
				
			||||||
	cache.SetStr("oauth2:state:"+state, "bind:"+strconv.FormatUint(rc.LoginAccount.Id, 10),
 | 
						cache.SetStr("oauth2:state:"+state, "bind:"+strconv.FormatUint(rc.GetLoginAccount().Id, 10),
 | 
				
			||||||
		5*time.Minute)
 | 
							5*time.Minute)
 | 
				
			||||||
	rc.GinCtx.Redirect(http.StatusFound, client.AuthCodeURL(state))
 | 
						rc.GinCtx.Redirect(http.StatusFound, client.AuthCodeURL(state))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -152,7 +153,7 @@ func (a *Oauth2Login) doLoginAction(rc *req.Ctx, userId string, oauth *config.Oa
 | 
				
			|||||||
			Name:     userId,
 | 
								Name:     userId,
 | 
				
			||||||
			Username: userId,
 | 
								Username: userId,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		biz.ErrIsNil(a.AccountApp.Create(account))
 | 
							biz.ErrIsNil(a.AccountApp.Create(context.TODO(), account))
 | 
				
			||||||
		// 绑定
 | 
							// 绑定
 | 
				
			||||||
		err := a.Oauth2App.BindOAuthAccount(&entity.Oauth2Account{
 | 
							err := a.Oauth2App.BindOAuthAccount(&entity.Oauth2Account{
 | 
				
			||||||
			AccountId:  account.Id,
 | 
								AccountId:  account.Id,
 | 
				
			||||||
@@ -207,7 +208,7 @@ func (a *Oauth2Login) Oauth2Status(ctx *req.Ctx) {
 | 
				
			|||||||
	res.Enable = oauth2LoginConfig.Enable
 | 
						res.Enable = oauth2LoginConfig.Enable
 | 
				
			||||||
	if res.Enable {
 | 
						if res.Enable {
 | 
				
			||||||
		err := a.Oauth2App.GetOAuthAccount(&entity.Oauth2Account{
 | 
							err := a.Oauth2App.GetOAuthAccount(&entity.Oauth2Account{
 | 
				
			||||||
			AccountId: ctx.LoginAccount.Id,
 | 
								AccountId: ctx.GetLoginAccount().Id,
 | 
				
			||||||
		}, "account_id", "identity")
 | 
							}, "account_id", "identity")
 | 
				
			||||||
		res.Bind = err == nil
 | 
							res.Bind = err == nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -216,7 +217,7 @@ func (a *Oauth2Login) Oauth2Status(ctx *req.Ctx) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (a *Oauth2Login) Oauth2Unbind(rc *req.Ctx) {
 | 
					func (a *Oauth2Login) Oauth2Unbind(rc *req.Ctx) {
 | 
				
			||||||
	a.Oauth2App.Unbind(rc.LoginAccount.Id)
 | 
						a.Oauth2App.Unbind(rc.GetLoginAccount().Id)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 获取oauth2登录配置信息,因为有些字段是敏感字段,故单独使用接口获取
 | 
					// 获取oauth2登录配置信息,因为有些字段是敏感字段,故单独使用接口获取
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
package application
 | 
					package application
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
	"mayfly-go/internal/auth/domain/entity"
 | 
						"mayfly-go/internal/auth/domain/entity"
 | 
				
			||||||
	"mayfly-go/internal/auth/domain/repository"
 | 
						"mayfly-go/internal/auth/domain/repository"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -29,11 +30,11 @@ func (a *oauth2AppImpl) GetOAuthAccount(condition *entity.Oauth2Account, cols ..
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func (a *oauth2AppImpl) BindOAuthAccount(e *entity.Oauth2Account) error {
 | 
					func (a *oauth2AppImpl) BindOAuthAccount(e *entity.Oauth2Account) error {
 | 
				
			||||||
	if e.Id == 0 {
 | 
						if e.Id == 0 {
 | 
				
			||||||
		return a.oauthAccountRepo.Insert(e)
 | 
							return a.oauthAccountRepo.Insert(context.Background(), e)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return a.oauthAccountRepo.UpdateById(e)
 | 
						return a.oauthAccountRepo.UpdateById(context.Background(), e)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (a *oauth2AppImpl) Unbind(accountId uint64) {
 | 
					func (a *oauth2AppImpl) Unbind(accountId uint64) {
 | 
				
			||||||
	a.oauthAccountRepo.DeleteByCond(&entity.Oauth2Account{AccountId: accountId})
 | 
						a.oauthAccountRepo.DeleteByCond(context.Background(), &entity.Oauth2Account{AccountId: accountId})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,7 +23,7 @@ type Index struct {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (i *Index) Count(rc *req.Ctx) {
 | 
					func (i *Index) Count(rc *req.Ctx) {
 | 
				
			||||||
	accountId := rc.LoginAccount.Id
 | 
						accountId := rc.GetLoginAccount().Id
 | 
				
			||||||
	tagIds := i.TagApp.ListTagIdByAccountId(accountId)
 | 
						tagIds := i.TagApp.ListTagIdByAccountId(accountId)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var mongoNum int64
 | 
						var mongoNum int64
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,7 +13,6 @@ import (
 | 
				
			|||||||
	tagapp "mayfly-go/internal/tag/application"
 | 
						tagapp "mayfly-go/internal/tag/application"
 | 
				
			||||||
	"mayfly-go/pkg/biz"
 | 
						"mayfly-go/pkg/biz"
 | 
				
			||||||
	"mayfly-go/pkg/ginx"
 | 
						"mayfly-go/pkg/ginx"
 | 
				
			||||||
	"mayfly-go/pkg/gormx"
 | 
					 | 
				
			||||||
	"mayfly-go/pkg/logx"
 | 
						"mayfly-go/pkg/logx"
 | 
				
			||||||
	"mayfly-go/pkg/model"
 | 
						"mayfly-go/pkg/model"
 | 
				
			||||||
	"mayfly-go/pkg/req"
 | 
						"mayfly-go/pkg/req"
 | 
				
			||||||
@@ -42,7 +41,7 @@ func (d *Db) Dbs(rc *req.Ctx) {
 | 
				
			|||||||
	queryCond, page := ginx.BindQueryAndPage[*entity.DbQuery](rc.GinCtx, new(entity.DbQuery))
 | 
						queryCond, page := ginx.BindQueryAndPage[*entity.DbQuery](rc.GinCtx, new(entity.DbQuery))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 不存在可访问标签id,即没有可操作数据
 | 
						// 不存在可访问标签id,即没有可操作数据
 | 
				
			||||||
	tagIds := d.TagApp.ListTagIdByAccountId(rc.LoginAccount.Id)
 | 
						tagIds := d.TagApp.ListTagIdByAccountId(rc.GetLoginAccount().Id)
 | 
				
			||||||
	if len(tagIds) == 0 {
 | 
						if len(tagIds) == 0 {
 | 
				
			||||||
		rc.ResData = model.EmptyPageResult[any]()
 | 
							rc.ResData = model.EmptyPageResult[any]()
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
@@ -55,7 +54,7 @@ func (d *Db) Dbs(rc *req.Ctx) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (d *Db) DbTags(rc *req.Ctx) {
 | 
					func (d *Db) DbTags(rc *req.Ctx) {
 | 
				
			||||||
	rc.ResData = d.TagApp.ListTagByAccountIdAndResource(rc.LoginAccount.Id, new(entity.Db))
 | 
						rc.ResData = d.TagApp.ListTagByAccountIdAndResource(rc.GetLoginAccount().Id, new(entity.Db))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (d *Db) Save(rc *req.Ctx) {
 | 
					func (d *Db) Save(rc *req.Ctx) {
 | 
				
			||||||
@@ -64,8 +63,7 @@ func (d *Db) Save(rc *req.Ctx) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	rc.ReqParam = form
 | 
						rc.ReqParam = form
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	db.SetBaseInfo(rc.LoginAccount)
 | 
						biz.ErrIsNil(d.DbApp.Save(rc.MetaCtx, db))
 | 
				
			||||||
	biz.ErrIsNil(d.DbApp.Save(db))
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (d *Db) DeleteDb(rc *req.Ctx) {
 | 
					func (d *Db) DeleteDb(rc *req.Ctx) {
 | 
				
			||||||
@@ -73,13 +71,14 @@ func (d *Db) DeleteDb(rc *req.Ctx) {
 | 
				
			|||||||
	rc.ReqParam = idsStr
 | 
						rc.ReqParam = idsStr
 | 
				
			||||||
	ids := strings.Split(idsStr, ",")
 | 
						ids := strings.Split(idsStr, ",")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctx := rc.MetaCtx
 | 
				
			||||||
	for _, v := range ids {
 | 
						for _, v := range ids {
 | 
				
			||||||
		value, err := strconv.Atoi(v)
 | 
							value, err := strconv.Atoi(v)
 | 
				
			||||||
		biz.ErrIsNilAppendErr(err, "string类型转换为int异常: %s")
 | 
							biz.ErrIsNilAppendErr(err, "string类型转换为int异常: %s")
 | 
				
			||||||
		dbId := uint64(value)
 | 
							dbId := uint64(value)
 | 
				
			||||||
		d.DbApp.Delete(dbId)
 | 
							d.DbApp.Delete(ctx, dbId)
 | 
				
			||||||
		// 删除该库的sql执行记录
 | 
							// 删除该库的sql执行记录
 | 
				
			||||||
		d.DbSqlExecApp.DeleteBy(&entity.DbSqlExec{DbId: dbId})
 | 
							d.DbSqlExecApp.DeleteBy(ctx, &entity.DbSqlExec{DbId: dbId})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -91,7 +90,7 @@ func (d *Db) ExecSql(rc *req.Ctx) {
 | 
				
			|||||||
	dbId := getDbId(g)
 | 
						dbId := getDbId(g)
 | 
				
			||||||
	dbConn, err := d.DbApp.GetDbConn(dbId, form.Db)
 | 
						dbConn, err := d.DbApp.GetDbConn(dbId, form.Db)
 | 
				
			||||||
	biz.ErrIsNil(err)
 | 
						biz.ErrIsNil(err)
 | 
				
			||||||
	biz.ErrIsNilAppendErr(d.TagApp.CanAccess(rc.LoginAccount.Id, dbConn.Info.TagPath), "%s")
 | 
						biz.ErrIsNilAppendErr(d.TagApp.CanAccess(rc.GetLoginAccount().Id, dbConn.Info.TagPath), "%s")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rc.ReqParam = fmt.Sprintf("%s\n-> %s", dbConn.Info.GetLogDesc(), form.Sql)
 | 
						rc.ReqParam = fmt.Sprintf("%s\n-> %s", dbConn.Info.GetLogDesc(), form.Sql)
 | 
				
			||||||
	biz.NotEmpty(form.Sql, "sql不能为空")
 | 
						biz.NotEmpty(form.Sql, "sql不能为空")
 | 
				
			||||||
@@ -104,7 +103,7 @@ func (d *Db) ExecSql(rc *req.Ctx) {
 | 
				
			|||||||
		Db:           form.Db,
 | 
							Db:           form.Db,
 | 
				
			||||||
		Remark:       form.Remark,
 | 
							Remark:       form.Remark,
 | 
				
			||||||
		DbConn:       dbConn,
 | 
							DbConn:       dbConn,
 | 
				
			||||||
		LoginAccount: rc.LoginAccount,
 | 
							LoginAccount: rc.GetLoginAccount(),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sqls, err := sqlparser.SplitStatementToPieces(sql, sqlparser.WithDialect(dbConn.Info.Type.Dialect()))
 | 
						sqls, err := sqlparser.SplitStatementToPieces(sql, sqlparser.WithDialect(dbConn.Info.Type.Dialect()))
 | 
				
			||||||
@@ -163,7 +162,7 @@ func (d *Db) ExecSqlFile(rc *req.Ctx) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	dbConn, err := d.DbApp.GetDbConn(dbId, dbName)
 | 
						dbConn, err := d.DbApp.GetDbConn(dbId, dbName)
 | 
				
			||||||
	biz.ErrIsNil(err)
 | 
						biz.ErrIsNil(err)
 | 
				
			||||||
	biz.ErrIsNilAppendErr(d.TagApp.CanAccess(rc.LoginAccount.Id, dbConn.Info.TagPath), "%s")
 | 
						biz.ErrIsNilAppendErr(d.TagApp.CanAccess(rc.GetLoginAccount().Id, dbConn.Info.TagPath), "%s")
 | 
				
			||||||
	rc.ReqParam = fmt.Sprintf("filename: %s -> %s", filename, dbConn.Info.GetLogDesc())
 | 
						rc.ReqParam = fmt.Sprintf("filename: %s -> %s", filename, dbConn.Info.GetLogDesc())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	defer func() {
 | 
						defer func() {
 | 
				
			||||||
@@ -172,7 +171,7 @@ func (d *Db) ExecSqlFile(rc *req.Ctx) {
 | 
				
			|||||||
			if len(errInfo) > 300 {
 | 
								if len(errInfo) > 300 {
 | 
				
			||||||
				errInfo = errInfo[:300] + "..."
 | 
									errInfo = errInfo[:300] + "..."
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			d.MsgApp.CreateAndSend(rc.LoginAccount, msgdto.ErrSysMsg("sql脚本执行失败", fmt.Sprintf("[%s][%s]执行失败: [%s]", filename, dbConn.Info.GetLogDesc(), errInfo)).WithClientId(clientId))
 | 
								d.MsgApp.CreateAndSend(rc.GetLoginAccount(), msgdto.ErrSysMsg("sql脚本执行失败", fmt.Sprintf("[%s][%s]执行失败: [%s]", filename, dbConn.Info.GetLogDesc(), errInfo)).WithClientId(clientId))
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}()
 | 
						}()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -181,7 +180,7 @@ func (d *Db) ExecSqlFile(rc *req.Ctx) {
 | 
				
			|||||||
		Db:           dbName,
 | 
							Db:           dbName,
 | 
				
			||||||
		Remark:       filename,
 | 
							Remark:       filename,
 | 
				
			||||||
		DbConn:       dbConn,
 | 
							DbConn:       dbConn,
 | 
				
			||||||
		LoginAccount: rc.LoginAccount,
 | 
							LoginAccount: rc.GetLoginAccount(),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var sql string
 | 
						var sql string
 | 
				
			||||||
@@ -191,7 +190,8 @@ func (d *Db) ExecSqlFile(rc *req.Ctx) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	executedStatements := 0
 | 
						executedStatements := 0
 | 
				
			||||||
	progressId := stringx.Rand(32)
 | 
						progressId := stringx.Rand(32)
 | 
				
			||||||
	defer ws.SendJsonMsg(ws.UserId(rc.LoginAccount.Id), clientId, msgdto.InfoSysMsg("sql脚本执行进度", &progressMsg{
 | 
						laId := rc.GetLoginAccount().Id
 | 
				
			||||||
 | 
						defer ws.SendJsonMsg(ws.UserId(laId), clientId, msgdto.InfoSysMsg("sql脚本执行进度", &progressMsg{
 | 
				
			||||||
		Id:                 progressId,
 | 
							Id:                 progressId,
 | 
				
			||||||
		Title:              filename,
 | 
							Title:              filename,
 | 
				
			||||||
		ExecutedStatements: executedStatements,
 | 
							ExecutedStatements: executedStatements,
 | 
				
			||||||
@@ -202,7 +202,7 @@ func (d *Db) ExecSqlFile(rc *req.Ctx) {
 | 
				
			|||||||
	for {
 | 
						for {
 | 
				
			||||||
		select {
 | 
							select {
 | 
				
			||||||
		case <-ticker.C:
 | 
							case <-ticker.C:
 | 
				
			||||||
			ws.SendJsonMsg(ws.UserId(rc.LoginAccount.Id), clientId, msgdto.InfoSysMsg("sql脚本执行进度", &progressMsg{
 | 
								ws.SendJsonMsg(ws.UserId(laId), clientId, msgdto.InfoSysMsg("sql脚本执行进度", &progressMsg{
 | 
				
			||||||
				Id:                 progressId,
 | 
									Id:                 progressId,
 | 
				
			||||||
				Title:              filename,
 | 
									Title:              filename,
 | 
				
			||||||
				ExecutedStatements: executedStatements,
 | 
									ExecutedStatements: executedStatements,
 | 
				
			||||||
@@ -231,7 +231,7 @@ func (d *Db) ExecSqlFile(rc *req.Ctx) {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
			dbConn, err = d.DbApp.GetDbConn(dbId, stmtUse.DBName.String())
 | 
								dbConn, err = d.DbApp.GetDbConn(dbId, stmtUse.DBName.String())
 | 
				
			||||||
			biz.ErrIsNil(err)
 | 
								biz.ErrIsNil(err)
 | 
				
			||||||
			biz.ErrIsNilAppendErr(d.TagApp.CanAccess(rc.LoginAccount.Id, dbConn.Info.TagPath), "%s")
 | 
								biz.ErrIsNilAppendErr(d.TagApp.CanAccess(laId, dbConn.Info.TagPath), "%s")
 | 
				
			||||||
			execReq.DbConn = dbConn
 | 
								execReq.DbConn = dbConn
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		// 需要记录执行记录
 | 
							// 需要记录执行记录
 | 
				
			||||||
@@ -245,7 +245,7 @@ func (d *Db) ExecSqlFile(rc *req.Ctx) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		biz.ErrIsNilAppendErr(err, "%s")
 | 
							biz.ErrIsNilAppendErr(err, "%s")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	d.MsgApp.CreateAndSend(rc.LoginAccount, msgdto.SuccessSysMsg("sql脚本执行成功", fmt.Sprintf("sql脚本执行完成:%s", rc.ReqParam)).WithClientId(clientId))
 | 
						d.MsgApp.CreateAndSend(rc.GetLoginAccount(), msgdto.SuccessSysMsg("sql脚本执行成功", fmt.Sprintf("sql脚本执行完成:%s", rc.ReqParam)).WithClientId(clientId))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 数据库dump
 | 
					// 数据库dump
 | 
				
			||||||
@@ -268,9 +268,10 @@ func (d *Db) DumpSql(rc *req.Ctx) {
 | 
				
			|||||||
	// 是否需要导出数据
 | 
						// 是否需要导出数据
 | 
				
			||||||
	needData := dumpType == "2" || dumpType == "3"
 | 
						needData := dumpType == "2" || dumpType == "3"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						la := rc.GetLoginAccount()
 | 
				
			||||||
	db, err := d.DbApp.GetById(new(entity.Db), dbId)
 | 
						db, err := d.DbApp.GetById(new(entity.Db), dbId)
 | 
				
			||||||
	biz.ErrIsNil(err, "该数据库不存在")
 | 
						biz.ErrIsNil(err, "该数据库不存在")
 | 
				
			||||||
	biz.ErrIsNilAppendErr(d.TagApp.CanAccess(rc.LoginAccount.Id, db.TagPath), "%s")
 | 
						biz.ErrIsNilAppendErr(d.TagApp.CanAccess(la.Id, db.TagPath), "%s")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	now := time.Now()
 | 
						now := time.Now()
 | 
				
			||||||
	filename := fmt.Sprintf("%s.%s.sql%s", db.Name, now.Format("20060102150405"), extName)
 | 
						filename := fmt.Sprintf("%s.%s.sql%s", db.Name, now.Format("20060102150405"), extName)
 | 
				
			||||||
@@ -294,7 +295,7 @@ func (d *Db) DumpSql(rc *req.Ctx) {
 | 
				
			|||||||
		if len(msg) > 0 {
 | 
							if len(msg) > 0 {
 | 
				
			||||||
			msg = "数据库导出失败: " + msg
 | 
								msg = "数据库导出失败: " + msg
 | 
				
			||||||
			writer.WriteString(msg)
 | 
								writer.WriteString(msg)
 | 
				
			||||||
			d.MsgApp.CreateAndSend(rc.LoginAccount, msgdto.ErrSysMsg("数据库导出失败", msg))
 | 
								d.MsgApp.CreateAndSend(la, msgdto.ErrSysMsg("数据库导出失败", msg))
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		writer.Close()
 | 
							writer.Close()
 | 
				
			||||||
	}()
 | 
						}()
 | 
				
			||||||
@@ -444,73 +445,6 @@ func (d *Db) GetCreateTableDdl(rc *req.Ctx) {
 | 
				
			|||||||
	rc.ResData = res
 | 
						rc.ResData = res
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// @router /api/db/:dbId/sql [post]
 | 
					 | 
				
			||||||
func (d *Db) SaveSql(rc *req.Ctx) {
 | 
					 | 
				
			||||||
	g := rc.GinCtx
 | 
					 | 
				
			||||||
	account := rc.LoginAccount
 | 
					 | 
				
			||||||
	dbSqlForm := &form.DbSqlSaveForm{}
 | 
					 | 
				
			||||||
	ginx.BindJsonAndValid(g, dbSqlForm)
 | 
					 | 
				
			||||||
	rc.ReqParam = dbSqlForm
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	dbId := getDbId(g)
 | 
					 | 
				
			||||||
	// 判断dbId是否存在
 | 
					 | 
				
			||||||
	err := gormx.GetById(new(entity.Db), dbId)
 | 
					 | 
				
			||||||
	biz.ErrIsNil(err, "该数据库信息不存在")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// 获取用于是否有该dbsql的保存记录,有则更改,否则新增
 | 
					 | 
				
			||||||
	dbSql := &entity.DbSql{Type: dbSqlForm.Type, DbId: dbId, Name: dbSqlForm.Name, Db: dbSqlForm.Db}
 | 
					 | 
				
			||||||
	dbSql.CreatorId = account.Id
 | 
					 | 
				
			||||||
	e := gormx.GetBy(dbSql)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	dbSql.SetBaseInfo(account)
 | 
					 | 
				
			||||||
	// 更新sql信息
 | 
					 | 
				
			||||||
	dbSql.Sql = dbSqlForm.Sql
 | 
					 | 
				
			||||||
	if e == nil {
 | 
					 | 
				
			||||||
		gormx.UpdateById(dbSql)
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		gormx.Insert(dbSql)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 获取所有保存的sql names
 | 
					 | 
				
			||||||
func (d *Db) GetSqlNames(rc *req.Ctx) {
 | 
					 | 
				
			||||||
	dbId := getDbId(rc.GinCtx)
 | 
					 | 
				
			||||||
	dbName := getDbName(rc.GinCtx)
 | 
					 | 
				
			||||||
	// 获取用于是否有该dbsql的保存记录,有则更改,否则新增
 | 
					 | 
				
			||||||
	dbSql := &entity.DbSql{Type: 1, DbId: dbId, Db: dbName}
 | 
					 | 
				
			||||||
	dbSql.CreatorId = rc.LoginAccount.Id
 | 
					 | 
				
			||||||
	var sqls []entity.DbSql
 | 
					 | 
				
			||||||
	gormx.ListBy(dbSql, &sqls, "id", "name")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	rc.ResData = sqls
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 删除保存的sql
 | 
					 | 
				
			||||||
func (d *Db) DeleteSql(rc *req.Ctx) {
 | 
					 | 
				
			||||||
	dbSql := &entity.DbSql{Type: 1, DbId: getDbId(rc.GinCtx)}
 | 
					 | 
				
			||||||
	dbSql.CreatorId = rc.LoginAccount.Id
 | 
					 | 
				
			||||||
	dbSql.Name = rc.GinCtx.Query("name")
 | 
					 | 
				
			||||||
	dbSql.Db = rc.GinCtx.Query("db")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	biz.ErrIsNil(gormx.DeleteBy(dbSql))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// @router /api/db/:dbId/sql [get]
 | 
					 | 
				
			||||||
func (d *Db) GetSql(rc *req.Ctx) {
 | 
					 | 
				
			||||||
	dbId := getDbId(rc.GinCtx)
 | 
					 | 
				
			||||||
	dbName := getDbName(rc.GinCtx)
 | 
					 | 
				
			||||||
	// 根据创建者id, 数据库id,以及sql模板名称查询保存的sql信息
 | 
					 | 
				
			||||||
	dbSql := &entity.DbSql{Type: 1, DbId: dbId, Db: dbName}
 | 
					 | 
				
			||||||
	dbSql.CreatorId = rc.LoginAccount.Id
 | 
					 | 
				
			||||||
	dbSql.Name = rc.GinCtx.Query("name")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	e := gormx.GetBy(dbSql)
 | 
					 | 
				
			||||||
	if e != nil {
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	rc.ResData = dbSql
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func getDbId(g *gin.Context) uint64 {
 | 
					func getDbId(g *gin.Context) uint64 {
 | 
				
			||||||
	dbId, _ := strconv.Atoi(g.Param("dbId"))
 | 
						dbId, _ := strconv.Atoi(g.Param("dbId"))
 | 
				
			||||||
	biz.IsTrue(dbId > 0, "dbId错误")
 | 
						biz.IsTrue(dbId > 0, "dbId错误")
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										77
									
								
								server/internal/db/api/db_sql.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								server/internal/db/api/db_sql.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,77 @@
 | 
				
			|||||||
 | 
					package api
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"mayfly-go/internal/db/api/form"
 | 
				
			||||||
 | 
						"mayfly-go/internal/db/application"
 | 
				
			||||||
 | 
						"mayfly-go/internal/db/domain/entity"
 | 
				
			||||||
 | 
						"mayfly-go/pkg/biz"
 | 
				
			||||||
 | 
						"mayfly-go/pkg/ginx"
 | 
				
			||||||
 | 
						"mayfly-go/pkg/req"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type DbSql struct {
 | 
				
			||||||
 | 
						DbSqlApp application.DbSql
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// @router /api/db/:dbId/sql [post]
 | 
				
			||||||
 | 
					func (d *DbSql) SaveSql(rc *req.Ctx) {
 | 
				
			||||||
 | 
						g := rc.GinCtx
 | 
				
			||||||
 | 
						dbSqlForm := &form.DbSqlSaveForm{}
 | 
				
			||||||
 | 
						ginx.BindJsonAndValid(g, dbSqlForm)
 | 
				
			||||||
 | 
						rc.ReqParam = dbSqlForm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dbId := getDbId(g)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						account := rc.GetLoginAccount()
 | 
				
			||||||
 | 
						// 获取用于是否有该dbsql的保存记录,有则更改,否则新增
 | 
				
			||||||
 | 
						dbSql := &entity.DbSql{Type: dbSqlForm.Type, DbId: dbId, Name: dbSqlForm.Name, Db: dbSqlForm.Db}
 | 
				
			||||||
 | 
						dbSql.CreatorId = account.Id
 | 
				
			||||||
 | 
						e := d.DbSqlApp.GetBy(dbSql)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 更新sql信息
 | 
				
			||||||
 | 
						dbSql.Sql = dbSqlForm.Sql
 | 
				
			||||||
 | 
						if e == nil {
 | 
				
			||||||
 | 
							d.DbSqlApp.UpdateById(rc.MetaCtx, dbSql)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							d.DbSqlApp.Insert(rc.MetaCtx, dbSql)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 获取所有保存的sql names
 | 
				
			||||||
 | 
					func (d *DbSql) GetSqlNames(rc *req.Ctx) {
 | 
				
			||||||
 | 
						dbId := getDbId(rc.GinCtx)
 | 
				
			||||||
 | 
						dbName := getDbName(rc.GinCtx)
 | 
				
			||||||
 | 
						// 获取用于是否有该dbsql的保存记录,有则更改,否则新增
 | 
				
			||||||
 | 
						dbSql := &entity.DbSql{Type: 1, DbId: dbId, Db: dbName}
 | 
				
			||||||
 | 
						dbSql.CreatorId = rc.GetLoginAccount().Id
 | 
				
			||||||
 | 
						var sqls []entity.DbSql
 | 
				
			||||||
 | 
						d.DbSqlApp.ListByCond(dbSql, &sqls, "id", "name")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rc.ResData = sqls
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 删除保存的sql
 | 
				
			||||||
 | 
					func (d *DbSql) DeleteSql(rc *req.Ctx) {
 | 
				
			||||||
 | 
						dbSql := &entity.DbSql{Type: 1, DbId: getDbId(rc.GinCtx)}
 | 
				
			||||||
 | 
						dbSql.CreatorId = rc.GetLoginAccount().Id
 | 
				
			||||||
 | 
						dbSql.Name = rc.GinCtx.Query("name")
 | 
				
			||||||
 | 
						dbSql.Db = rc.GinCtx.Query("db")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						biz.ErrIsNil(d.DbSqlApp.DeleteByCond(rc.MetaCtx, dbSql))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// @router /api/db/:dbId/sql [get]
 | 
				
			||||||
 | 
					func (d *DbSql) GetSql(rc *req.Ctx) {
 | 
				
			||||||
 | 
						dbId := getDbId(rc.GinCtx)
 | 
				
			||||||
 | 
						dbName := getDbName(rc.GinCtx)
 | 
				
			||||||
 | 
						// 根据创建者id, 数据库id,以及sql模板名称查询保存的sql信息
 | 
				
			||||||
 | 
						dbSql := &entity.DbSql{Type: 1, DbId: dbId, Db: dbName}
 | 
				
			||||||
 | 
						dbSql.CreatorId = rc.GetLoginAccount().Id
 | 
				
			||||||
 | 
						dbSql.Name = rc.GinCtx.Query("name")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						e := d.DbSqlApp.GetBy(dbSql)
 | 
				
			||||||
 | 
						if e != nil {
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						rc.ResData = dbSql
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -14,7 +14,7 @@ type DbSqlExec struct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func (d *DbSqlExec) DbSqlExecs(rc *req.Ctx) {
 | 
					func (d *DbSqlExec) DbSqlExecs(rc *req.Ctx) {
 | 
				
			||||||
	queryCond, page := ginx.BindQueryAndPage(rc.GinCtx, new(entity.DbSqlExecQuery))
 | 
						queryCond, page := ginx.BindQueryAndPage(rc.GinCtx, new(entity.DbSqlExecQuery))
 | 
				
			||||||
	queryCond.CreatorId = rc.LoginAccount.Id
 | 
						queryCond.CreatorId = rc.GetLoginAccount().Id
 | 
				
			||||||
	res, err := d.DbSqlExecApp.GetPageList(queryCond, page, new([]entity.DbSqlExec))
 | 
						res, err := d.DbSqlExecApp.GetPageList(queryCond, page, new([]entity.DbSqlExec))
 | 
				
			||||||
	biz.ErrIsNil(err)
 | 
						biz.ErrIsNil(err)
 | 
				
			||||||
	rc.ResData = res
 | 
						rc.ResData = res
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -43,9 +43,7 @@ func (d *Instance) SaveInstance(rc *req.Ctx) {
 | 
				
			|||||||
	// 密码脱敏记录日志
 | 
						// 密码脱敏记录日志
 | 
				
			||||||
	form.Password = "****"
 | 
						form.Password = "****"
 | 
				
			||||||
	rc.ReqParam = form
 | 
						rc.ReqParam = form
 | 
				
			||||||
 | 
						biz.ErrIsNil(d.InstanceApp.Save(rc.MetaCtx, instance))
 | 
				
			||||||
	instance.SetBaseInfo(rc.LoginAccount)
 | 
					 | 
				
			||||||
	biz.ErrIsNil(d.InstanceApp.Save(instance))
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetInstance 获取数据库实例密码,由于数据库是加密存储,故提供该接口展示原文密码
 | 
					// GetInstance 获取数据库实例密码,由于数据库是加密存储,故提供该接口展示原文密码
 | 
				
			||||||
@@ -84,7 +82,7 @@ func (d *Instance) DeleteInstance(rc *req.Ctx) {
 | 
				
			|||||||
			biz.ErrIsNil(err, "获取数据库实例错误,数据库实例ID为: %d", instance.Id)
 | 
								biz.ErrIsNil(err, "获取数据库实例错误,数据库实例ID为: %d", instance.Id)
 | 
				
			||||||
			biz.IsTrue(false, "不能删除数据库实例【%s】,请先删除其关联的数据库资源。", instance.Name)
 | 
								biz.IsTrue(false, "不能删除数据库实例【%s】,请先删除其关联的数据库资源。", instance.Name)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		d.InstanceApp.Delete(instanceId)
 | 
							d.InstanceApp.Delete(rc.MetaCtx, instanceId)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,6 +8,7 @@ var (
 | 
				
			|||||||
	instanceApp  Instance  = newInstanceApp(persistence.GetInstanceRepo())
 | 
						instanceApp  Instance  = newInstanceApp(persistence.GetInstanceRepo())
 | 
				
			||||||
	dbApp        Db        = newDbApp(persistence.GetDbRepo(), persistence.GetDbSqlRepo(), instanceApp)
 | 
						dbApp        Db        = newDbApp(persistence.GetDbRepo(), persistence.GetDbSqlRepo(), instanceApp)
 | 
				
			||||||
	dbSqlExecApp DbSqlExec = newDbSqlExecApp(persistence.GetDbSqlExecRepo())
 | 
						dbSqlExecApp DbSqlExec = newDbSqlExecApp(persistence.GetDbSqlExecRepo())
 | 
				
			||||||
 | 
						dbSqlApp     DbSql     = newDbSqlApp(persistence.GetDbSqlRepo())
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func GetInstanceApp() Instance {
 | 
					func GetInstanceApp() Instance {
 | 
				
			||||||
@@ -18,6 +19,10 @@ func GetDbApp() Db {
 | 
				
			|||||||
	return dbApp
 | 
						return dbApp
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func GetDbSqlApp() DbSql {
 | 
				
			||||||
 | 
						return dbSqlApp
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func GetDbSqlExecApp() DbSqlExec {
 | 
					func GetDbSqlExecApp() DbSqlExec {
 | 
				
			||||||
	return dbSqlExecApp
 | 
						return dbSqlExecApp
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
package application
 | 
					package application
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
	"mayfly-go/internal/db/dbm"
 | 
						"mayfly-go/internal/db/dbm"
 | 
				
			||||||
	"mayfly-go/internal/db/domain/entity"
 | 
						"mayfly-go/internal/db/domain/entity"
 | 
				
			||||||
	"mayfly-go/internal/db/domain/repository"
 | 
						"mayfly-go/internal/db/domain/repository"
 | 
				
			||||||
@@ -20,10 +21,10 @@ type Db interface {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	Count(condition *entity.DbQuery) int64
 | 
						Count(condition *entity.DbQuery) int64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Save(entity *entity.Db) error
 | 
						Save(ctx context.Context, entity *entity.Db) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 删除数据库信息
 | 
						// 删除数据库信息
 | 
				
			||||||
	Delete(id uint64) error
 | 
						Delete(ctx context.Context, id uint64) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 获取数据库连接实例
 | 
						// 获取数据库连接实例
 | 
				
			||||||
	// @param id 数据库id
 | 
						// @param id 数据库id
 | 
				
			||||||
@@ -56,7 +57,7 @@ func (d *dbAppImpl) Count(condition *entity.DbQuery) int64 {
 | 
				
			|||||||
	return d.GetRepo().Count(condition)
 | 
						return d.GetRepo().Count(condition)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (d *dbAppImpl) Save(dbEntity *entity.Db) error {
 | 
					func (d *dbAppImpl) Save(ctx context.Context, dbEntity *entity.Db) error {
 | 
				
			||||||
	// 查找是否存在
 | 
						// 查找是否存在
 | 
				
			||||||
	oldDb := &entity.Db{Name: dbEntity.Name, InstanceId: dbEntity.InstanceId}
 | 
						oldDb := &entity.Db{Name: dbEntity.Name, InstanceId: dbEntity.InstanceId}
 | 
				
			||||||
	err := d.GetBy(oldDb)
 | 
						err := d.GetBy(oldDb)
 | 
				
			||||||
@@ -65,7 +66,7 @@ func (d *dbAppImpl) Save(dbEntity *entity.Db) error {
 | 
				
			|||||||
		if err == nil {
 | 
							if err == nil {
 | 
				
			||||||
			return errorx.NewBiz("该实例下数据库名已存在")
 | 
								return errorx.NewBiz("该实例下数据库名已存在")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return d.Insert(dbEntity)
 | 
							return d.Insert(ctx, dbEntity)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 如果存在该库,则校验修改的库是否为该库
 | 
						// 如果存在该库,则校验修改的库是否为该库
 | 
				
			||||||
@@ -90,13 +91,13 @@ func (d *dbAppImpl) Save(dbEntity *entity.Db) error {
 | 
				
			|||||||
		// 关闭数据库连接
 | 
							// 关闭数据库连接
 | 
				
			||||||
		dbm.CloseDb(dbEntity.Id, v)
 | 
							dbm.CloseDb(dbEntity.Id, v)
 | 
				
			||||||
		// 删除该库关联的所有sql记录
 | 
							// 删除该库关联的所有sql记录
 | 
				
			||||||
		d.dbSqlRepo.DeleteByCond(&entity.DbSql{DbId: dbId, Db: v})
 | 
							d.dbSqlRepo.DeleteByCond(ctx, &entity.DbSql{DbId: dbId, Db: v})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return d.UpdateById(dbEntity)
 | 
						return d.UpdateById(ctx, dbEntity)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (d *dbAppImpl) Delete(id uint64) error {
 | 
					func (d *dbAppImpl) Delete(ctx context.Context, id uint64) error {
 | 
				
			||||||
	db, err := d.GetById(new(entity.Db), id)
 | 
						db, err := d.GetById(new(entity.Db), id)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return errorx.NewBiz("该数据库不存在")
 | 
							return errorx.NewBiz("该数据库不存在")
 | 
				
			||||||
@@ -107,8 +108,8 @@ func (d *dbAppImpl) Delete(id uint64) error {
 | 
				
			|||||||
		dbm.CloseDb(id, v)
 | 
							dbm.CloseDb(id, v)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// 删除该库下用户保存的所有sql信息
 | 
						// 删除该库下用户保存的所有sql信息
 | 
				
			||||||
	d.dbSqlRepo.DeleteByCond(&entity.DbSql{DbId: id})
 | 
						d.dbSqlRepo.DeleteByCond(ctx, &entity.DbSql{DbId: id})
 | 
				
			||||||
	return d.DeleteById(id)
 | 
						return d.DeleteById(ctx, id)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (d *dbAppImpl) GetDbConn(dbId uint64, dbName string) (*dbm.DbConn, error) {
 | 
					func (d *dbAppImpl) GetDbConn(dbId uint64, dbName string) (*dbm.DbConn, error) {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										21
									
								
								server/internal/db/application/db_sql.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								server/internal/db/application/db_sql.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
				
			|||||||
 | 
					package application
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"mayfly-go/internal/db/domain/entity"
 | 
				
			||||||
 | 
						"mayfly-go/internal/db/domain/repository"
 | 
				
			||||||
 | 
						"mayfly-go/pkg/base"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type DbSql interface {
 | 
				
			||||||
 | 
						base.App[*entity.DbSql]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type dbSqlAppImpl struct {
 | 
				
			||||||
 | 
						base.AppImpl[*entity.DbSql, repository.DbSql]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func newDbSqlApp(dbSqlRepo repository.DbSql) DbSql {
 | 
				
			||||||
 | 
						app := new(dbSqlAppImpl)
 | 
				
			||||||
 | 
						app.Repo = dbSqlRepo
 | 
				
			||||||
 | 
						return app
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
package application
 | 
					package application
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
	"encoding/json"
 | 
						"encoding/json"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"mayfly-go/internal/db/config"
 | 
						"mayfly-go/internal/db/config"
 | 
				
			||||||
@@ -49,7 +50,7 @@ type DbSqlExec interface {
 | 
				
			|||||||
	Exec(execSqlReq *DbSqlExecReq) (*DbSqlExecRes, error)
 | 
						Exec(execSqlReq *DbSqlExecReq) (*DbSqlExecRes, error)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 根据条件删除sql执行记录
 | 
						// 根据条件删除sql执行记录
 | 
				
			||||||
	DeleteBy(condition *entity.DbSqlExec)
 | 
						DeleteBy(ctx context.Context, condition *entity.DbSqlExec)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 分页获取
 | 
						// 分页获取
 | 
				
			||||||
	GetPageList(condition *entity.DbSqlExecQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error)
 | 
						GetPageList(condition *entity.DbSqlExecQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error)
 | 
				
			||||||
@@ -139,19 +140,19 @@ func (d *dbSqlExecAppImpl) Exec(execSqlReq *DbSqlExecReq) (*DbSqlExecRes, error)
 | 
				
			|||||||
// 保存sql执行记录,如果是查询类则根据系统配置判断是否保存
 | 
					// 保存sql执行记录,如果是查询类则根据系统配置判断是否保存
 | 
				
			||||||
func (d *dbSqlExecAppImpl) saveSqlExecLog(isQuery bool, dbSqlExecRecord *entity.DbSqlExec) {
 | 
					func (d *dbSqlExecAppImpl) saveSqlExecLog(isQuery bool, dbSqlExecRecord *entity.DbSqlExec) {
 | 
				
			||||||
	if !isQuery {
 | 
						if !isQuery {
 | 
				
			||||||
		d.dbSqlExecRepo.Insert(dbSqlExecRecord)
 | 
							d.dbSqlExecRepo.Insert(context.TODO(), dbSqlExecRecord)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if config.GetDbSaveQuerySql() {
 | 
						if config.GetDbSaveQuerySql() {
 | 
				
			||||||
		dbSqlExecRecord.Table = "-"
 | 
							dbSqlExecRecord.Table = "-"
 | 
				
			||||||
		dbSqlExecRecord.OldValue = "-"
 | 
							dbSqlExecRecord.OldValue = "-"
 | 
				
			||||||
		dbSqlExecRecord.Type = entity.DbSqlExecTypeQuery
 | 
							dbSqlExecRecord.Type = entity.DbSqlExecTypeQuery
 | 
				
			||||||
		d.dbSqlExecRepo.Insert(dbSqlExecRecord)
 | 
							d.dbSqlExecRepo.Insert(context.TODO(), dbSqlExecRecord)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (d *dbSqlExecAppImpl) DeleteBy(condition *entity.DbSqlExec) {
 | 
					func (d *dbSqlExecAppImpl) DeleteBy(ctx context.Context, condition *entity.DbSqlExec) {
 | 
				
			||||||
	d.dbSqlExecRepo.DeleteByCond(condition)
 | 
						d.dbSqlExecRepo.DeleteByCond(ctx, condition)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (d *dbSqlExecAppImpl) GetPageList(condition *entity.DbSqlExecQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
 | 
					func (d *dbSqlExecAppImpl) GetPageList(condition *entity.DbSqlExecQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
package application
 | 
					package application
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
	"mayfly-go/internal/db/domain/entity"
 | 
						"mayfly-go/internal/db/domain/entity"
 | 
				
			||||||
	"mayfly-go/internal/db/domain/repository"
 | 
						"mayfly-go/internal/db/domain/repository"
 | 
				
			||||||
	"mayfly-go/pkg/base"
 | 
						"mayfly-go/pkg/base"
 | 
				
			||||||
@@ -16,10 +17,10 @@ type Instance interface {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	Count(condition *entity.InstanceQuery) int64
 | 
						Count(condition *entity.InstanceQuery) int64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Save(instanceEntity *entity.DbInstance) error
 | 
						Save(ctx context.Context, instanceEntity *entity.DbInstance) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Delete 删除数据库信息
 | 
						// Delete 删除数据库信息
 | 
				
			||||||
	Delete(id uint64) error
 | 
						Delete(ctx context.Context, id uint64) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// GetDatabases 获取数据库实例的所有数据库列表
 | 
						// GetDatabases 获取数据库实例的所有数据库列表
 | 
				
			||||||
	GetDatabases(entity *entity.DbInstance) ([]string, error)
 | 
						GetDatabases(entity *entity.DbInstance) ([]string, error)
 | 
				
			||||||
@@ -44,7 +45,7 @@ func (app *instanceAppImpl) Count(condition *entity.InstanceQuery) int64 {
 | 
				
			|||||||
	return app.CountByCond(condition)
 | 
						return app.CountByCond(condition)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (app *instanceAppImpl) Save(instanceEntity *entity.DbInstance) error {
 | 
					func (app *instanceAppImpl) Save(ctx context.Context, instanceEntity *entity.DbInstance) error {
 | 
				
			||||||
	// 默认tcp连接
 | 
						// 默认tcp连接
 | 
				
			||||||
	instanceEntity.Network = instanceEntity.GetNetwork()
 | 
						instanceEntity.Network = instanceEntity.GetNetwork()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -72,7 +73,7 @@ func (app *instanceAppImpl) Save(instanceEntity *entity.DbInstance) error {
 | 
				
			|||||||
			return errorx.NewBiz("该数据库实例已存在")
 | 
								return errorx.NewBiz("该数据库实例已存在")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		instanceEntity.PwdEncrypt()
 | 
							instanceEntity.PwdEncrypt()
 | 
				
			||||||
		return app.Insert(instanceEntity)
 | 
							return app.Insert(ctx, instanceEntity)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 如果存在该库,则校验修改的库是否为该库
 | 
						// 如果存在该库,则校验修改的库是否为该库
 | 
				
			||||||
@@ -80,11 +81,11 @@ func (app *instanceAppImpl) Save(instanceEntity *entity.DbInstance) error {
 | 
				
			|||||||
		return errorx.NewBiz("该数据库实例已存在")
 | 
							return errorx.NewBiz("该数据库实例已存在")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	instanceEntity.PwdEncrypt()
 | 
						instanceEntity.PwdEncrypt()
 | 
				
			||||||
	return app.UpdateById(instanceEntity)
 | 
						return app.UpdateById(ctx, instanceEntity)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (app *instanceAppImpl) Delete(id uint64) error {
 | 
					func (app *instanceAppImpl) Delete(ctx context.Context, id uint64) error {
 | 
				
			||||||
	return app.DeleteById(id)
 | 
						return app.DeleteById(ctx, id)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (app *instanceAppImpl) GetDatabases(ed *entity.DbInstance) ([]string, error) {
 | 
					func (app *instanceAppImpl) GetDatabases(ed *entity.DbInstance) ([]string, error) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -46,15 +46,6 @@ func InitDbRouter(router *gin.RouterGroup) {
 | 
				
			|||||||
		req.NewGet(":dbId/c-metadata", d.ColumnMA),
 | 
							req.NewGet(":dbId/c-metadata", d.ColumnMA),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		req.NewGet(":dbId/hint-tables", d.HintTables),
 | 
							req.NewGet(":dbId/hint-tables", d.HintTables),
 | 
				
			||||||
 | 
					 | 
				
			||||||
		// 用户sql相关
 | 
					 | 
				
			||||||
		req.NewPost(":dbId/sql", d.SaveSql),
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		req.NewGet(":dbId/sql", d.GetSql),
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		req.NewDelete(":dbId/sql", d.DeleteSql),
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		req.NewGet(":dbId/sql-names", d.GetSqlNames),
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	req.BatchSetGroup(db, reqs[:])
 | 
						req.BatchSetGroup(db, reqs[:])
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										32
									
								
								server/internal/db/router/db_sql.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								server/internal/db/router/db_sql.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
				
			|||||||
 | 
					package router
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"mayfly-go/internal/db/api"
 | 
				
			||||||
 | 
						"mayfly-go/internal/db/application"
 | 
				
			||||||
 | 
						"mayfly-go/pkg/req"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/gin-gonic/gin"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func InitDbSqlRouter(router *gin.RouterGroup) {
 | 
				
			||||||
 | 
						db := router.Group("dbs")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dbSql := &api.DbSql{
 | 
				
			||||||
 | 
							DbSqlApp: application.GetDbSqlApp(),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						reqs := [...]*req.Conf{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// 用户sql相关
 | 
				
			||||||
 | 
							req.NewPost(":dbId/sql", dbSql.SaveSql),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							req.NewGet(":dbId/sql", dbSql.GetSql),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							req.NewDelete(":dbId/sql", dbSql.DeleteSql),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							req.NewGet(":dbId/sql-names", dbSql.GetSqlNames),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						req.BatchSetGroup(db, reqs[:])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -5,5 +5,6 @@ import "github.com/gin-gonic/gin"
 | 
				
			|||||||
func Init(router *gin.RouterGroup) {
 | 
					func Init(router *gin.RouterGroup) {
 | 
				
			||||||
	InitInstanceRouter(router)
 | 
						InitInstanceRouter(router)
 | 
				
			||||||
	InitDbRouter(router)
 | 
						InitDbRouter(router)
 | 
				
			||||||
 | 
						InitDbSqlRouter(router)
 | 
				
			||||||
	InitDbSqlExecRouter(router)
 | 
						InitDbSqlExecRouter(router)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -44,8 +44,7 @@ func (c *AuthCert) SaveAuthCert(rc *req.Ctx) {
 | 
				
			|||||||
	acForm.Password = "***"
 | 
						acForm.Password = "***"
 | 
				
			||||||
	rc.ReqParam = acForm
 | 
						rc.ReqParam = acForm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ac.SetBaseInfo(rc.LoginAccount)
 | 
						biz.ErrIsNil(c.AuthCertApp.Save(rc.MetaCtx, ac))
 | 
				
			||||||
	biz.ErrIsNil(c.AuthCertApp.Save(ac))
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *AuthCert) Delete(rc *req.Ctx) {
 | 
					func (c *AuthCert) Delete(rc *req.Ctx) {
 | 
				
			||||||
@@ -56,6 +55,6 @@ func (c *AuthCert) Delete(rc *req.Ctx) {
 | 
				
			|||||||
	for _, v := range ids {
 | 
						for _, v := range ids {
 | 
				
			||||||
		value, err := strconv.Atoi(v)
 | 
							value, err := strconv.Atoi(v)
 | 
				
			||||||
		biz.ErrIsNilAppendErr(err, "string类型转换为int异常: %s")
 | 
							biz.ErrIsNilAppendErr(err, "string类型转换为int异常: %s")
 | 
				
			||||||
		c.AuthCertApp.DeleteById(uint64(value))
 | 
							c.AuthCertApp.DeleteById(rc.MetaCtx, uint64(value))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,7 +39,7 @@ func (m *Machine) Machines(rc *req.Ctx) {
 | 
				
			|||||||
	condition, pageParam := ginx.BindQueryAndPage(rc.GinCtx, new(entity.MachineQuery))
 | 
						condition, pageParam := ginx.BindQueryAndPage(rc.GinCtx, new(entity.MachineQuery))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 不存在可访问标签id,即没有可操作数据
 | 
						// 不存在可访问标签id,即没有可操作数据
 | 
				
			||||||
	tagIds := m.TagApp.ListTagIdByAccountId(rc.LoginAccount.Id)
 | 
						tagIds := m.TagApp.ListTagIdByAccountId(rc.GetLoginAccount().Id)
 | 
				
			||||||
	if len(tagIds) == 0 {
 | 
						if len(tagIds) == 0 {
 | 
				
			||||||
		rc.ResData = model.EmptyPageResult[any]()
 | 
							rc.ResData = model.EmptyPageResult[any]()
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
@@ -55,12 +55,20 @@ func (m *Machine) Machines(rc *req.Ctx) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	for _, mv := range *res.List {
 | 
						for _, mv := range *res.List {
 | 
				
			||||||
		mv.HasCli = mcm.HasCli(mv.Id)
 | 
							mv.HasCli = mcm.HasCli(mv.Id)
 | 
				
			||||||
 | 
							if machineStats, err := m.MachineApp.GetMachineStats(mv.Id); err == nil {
 | 
				
			||||||
 | 
								mv.Stat = collx.M{
 | 
				
			||||||
 | 
									"cpuIdle":      machineStats.CPU.Idle,
 | 
				
			||||||
 | 
									"memAvailable": machineStats.MemInfo.Available,
 | 
				
			||||||
 | 
									"memTotal":     machineStats.MemInfo.Total,
 | 
				
			||||||
 | 
									"fsInfos":      machineStats.FSInfos,
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	rc.ResData = res
 | 
						rc.ResData = res
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *Machine) MachineTags(rc *req.Ctx) {
 | 
					func (m *Machine) MachineTags(rc *req.Ctx) {
 | 
				
			||||||
	rc.ResData = m.TagApp.ListTagByAccountIdAndResource(rc.LoginAccount.Id, new(entity.Machine))
 | 
						rc.ResData = m.TagApp.ListTagByAccountIdAndResource(rc.GetLoginAccount().Id, new(entity.Machine))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *Machine) MachineStats(rc *req.Ctx) {
 | 
					func (m *Machine) MachineStats(rc *req.Ctx) {
 | 
				
			||||||
@@ -77,8 +85,7 @@ func (m *Machine) SaveMachine(rc *req.Ctx) {
 | 
				
			|||||||
	machineForm.Password = "******"
 | 
						machineForm.Password = "******"
 | 
				
			||||||
	rc.ReqParam = machineForm
 | 
						rc.ReqParam = machineForm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	me.SetBaseInfo(rc.LoginAccount)
 | 
						biz.ErrIsNil(m.MachineApp.Save(rc.MetaCtx, me))
 | 
				
			||||||
	biz.ErrIsNil(m.MachineApp.Save(me))
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *Machine) TestConn(rc *req.Ctx) {
 | 
					func (m *Machine) TestConn(rc *req.Ctx) {
 | 
				
			||||||
@@ -92,7 +99,7 @@ func (m *Machine) ChangeStatus(rc *req.Ctx) {
 | 
				
			|||||||
	id := uint64(ginx.PathParamInt(g, "machineId"))
 | 
						id := uint64(ginx.PathParamInt(g, "machineId"))
 | 
				
			||||||
	status := int8(ginx.PathParamInt(g, "status"))
 | 
						status := int8(ginx.PathParamInt(g, "status"))
 | 
				
			||||||
	rc.ReqParam = collx.Kvs("id", id, "status", status)
 | 
						rc.ReqParam = collx.Kvs("id", id, "status", status)
 | 
				
			||||||
	biz.ErrIsNil(m.MachineApp.ChangeStatus(id, status))
 | 
						biz.ErrIsNil(m.MachineApp.ChangeStatus(rc.MetaCtx, id, status))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *Machine) DeleteMachine(rc *req.Ctx) {
 | 
					func (m *Machine) DeleteMachine(rc *req.Ctx) {
 | 
				
			||||||
@@ -103,7 +110,7 @@ func (m *Machine) DeleteMachine(rc *req.Ctx) {
 | 
				
			|||||||
	for _, v := range ids {
 | 
						for _, v := range ids {
 | 
				
			||||||
		value, err := strconv.Atoi(v)
 | 
							value, err := strconv.Atoi(v)
 | 
				
			||||||
		biz.ErrIsNilAppendErr(err, "string类型转换为int异常: %s")
 | 
							biz.ErrIsNilAppendErr(err, "string类型转换为int异常: %s")
 | 
				
			||||||
		m.MachineApp.Delete(uint64(value))
 | 
							m.MachineApp.Delete(rc.MetaCtx, uint64(value))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -133,7 +140,7 @@ func (m *Machine) GetProcess(rc *req.Ctx) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	cli, err := m.MachineApp.GetCli(GetMachineId(rc.GinCtx))
 | 
						cli, err := m.MachineApp.GetCli(GetMachineId(rc.GinCtx))
 | 
				
			||||||
	biz.ErrIsNilAppendErr(err, "获取客户端连接失败: %s")
 | 
						biz.ErrIsNilAppendErr(err, "获取客户端连接失败: %s")
 | 
				
			||||||
	biz.ErrIsNilAppendErr(m.TagApp.CanAccess(rc.LoginAccount.Id, cli.Info.TagPath), "%s")
 | 
						biz.ErrIsNilAppendErr(m.TagApp.CanAccess(rc.GetLoginAccount().Id, cli.Info.TagPath), "%s")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	res, err := cli.Run(cmd)
 | 
						res, err := cli.Run(cmd)
 | 
				
			||||||
	biz.ErrIsNilAppendErr(err, "获取进程信息失败: %s")
 | 
						biz.ErrIsNilAppendErr(err, "获取进程信息失败: %s")
 | 
				
			||||||
@@ -147,7 +154,7 @@ func (m *Machine) KillProcess(rc *req.Ctx) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	cli, err := m.MachineApp.GetCli(GetMachineId(rc.GinCtx))
 | 
						cli, err := m.MachineApp.GetCli(GetMachineId(rc.GinCtx))
 | 
				
			||||||
	biz.ErrIsNilAppendErr(err, "获取客户端连接失败: %s")
 | 
						biz.ErrIsNilAppendErr(err, "获取客户端连接失败: %s")
 | 
				
			||||||
	biz.ErrIsNilAppendErr(m.TagApp.CanAccess(rc.LoginAccount.Id, cli.Info.TagPath), "%s")
 | 
						biz.ErrIsNilAppendErr(m.TagApp.CanAccess(rc.GetLoginAccount().Id, cli.Info.TagPath), "%s")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	res, err := cli.Run("sudo kill -9 " + pid)
 | 
						res, err := cli.Run("sudo kill -9 " + pid)
 | 
				
			||||||
	biz.ErrIsNil(err, "终止进程失败: %s", res)
 | 
						biz.ErrIsNil(err, "终止进程失败: %s", res)
 | 
				
			||||||
@@ -173,7 +180,7 @@ func (m *Machine) WsSSH(g *gin.Context) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	cli, err := m.MachineApp.GetCli(GetMachineId(g))
 | 
						cli, err := m.MachineApp.GetCli(GetMachineId(g))
 | 
				
			||||||
	biz.ErrIsNilAppendErr(err, "获取客户端连接失败: %s")
 | 
						biz.ErrIsNilAppendErr(err, "获取客户端连接失败: %s")
 | 
				
			||||||
	biz.ErrIsNilAppendErr(m.TagApp.CanAccess(rc.LoginAccount.Id, cli.Info.TagPath), "%s")
 | 
						biz.ErrIsNilAppendErr(m.TagApp.CanAccess(rc.GetLoginAccount().Id, cli.Info.TagPath), "%s")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cols := ginx.QueryInt(g, "cols", 80)
 | 
						cols := ginx.QueryInt(g, "cols", 80)
 | 
				
			||||||
	rows := ginx.QueryInt(g, "rows", 40)
 | 
						rows := ginx.QueryInt(g, "rows", 40)
 | 
				
			||||||
@@ -182,7 +189,7 @@ func (m *Machine) WsSSH(g *gin.Context) {
 | 
				
			|||||||
	if cli.Info.EnableRecorder == 1 {
 | 
						if cli.Info.EnableRecorder == 1 {
 | 
				
			||||||
		now := time.Now()
 | 
							now := time.Now()
 | 
				
			||||||
		// 回放文件路径为: 基础配置路径/机器id/操作日期/操作者账号/操作时间.cast
 | 
							// 回放文件路径为: 基础配置路径/机器id/操作日期/操作者账号/操作时间.cast
 | 
				
			||||||
		recPath := fmt.Sprintf("%s/%d/%s/%s", config.Conf.Server.GetMachineRecPath(), cli.Info.Id, now.Format("20060102"), rc.LoginAccount.Username)
 | 
							recPath := fmt.Sprintf("%s/%d/%s/%s", config.Conf.Server.GetMachineRecPath(), cli.Info.Id, now.Format("20060102"), rc.GetLoginAccount().Username)
 | 
				
			||||||
		os.MkdirAll(recPath, 0766)
 | 
							os.MkdirAll(recPath, 0766)
 | 
				
			||||||
		fileName := path.Join(recPath, fmt.Sprintf("%s.cast", now.Format("20060102_150405")))
 | 
							fileName := path.Join(recPath, fmt.Sprintf("%s.cast", now.Format("20060102_150405")))
 | 
				
			||||||
		f, err := os.OpenFile(fileName, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0766)
 | 
							f, err := os.OpenFile(fileName, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0766)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,12 +35,12 @@ func (m *MachineCronJob) Save(rc *req.Ctx) {
 | 
				
			|||||||
	jobForm := new(form.MachineCronJobForm)
 | 
						jobForm := new(form.MachineCronJobForm)
 | 
				
			||||||
	mcj := ginx.BindJsonAndCopyTo[*entity.MachineCronJob](rc.GinCtx, jobForm, new(entity.MachineCronJob))
 | 
						mcj := ginx.BindJsonAndCopyTo[*entity.MachineCronJob](rc.GinCtx, jobForm, new(entity.MachineCronJob))
 | 
				
			||||||
	rc.ReqParam = jobForm
 | 
						rc.ReqParam = jobForm
 | 
				
			||||||
	mcj.SetBaseInfo(rc.LoginAccount)
 | 
					
 | 
				
			||||||
	cronJobId, err := m.MachineCronJobApp.Save(mcj)
 | 
						cronJobId, err := m.MachineCronJobApp.Save(rc.MetaCtx, mcj)
 | 
				
			||||||
	biz.ErrIsNil(err)
 | 
						biz.ErrIsNil(err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 关联机器
 | 
						// 关联机器
 | 
				
			||||||
	m.MachineCronJobApp.CronJobRelateMachines(cronJobId, jobForm.MachineIds, rc.LoginAccount)
 | 
						m.MachineCronJobApp.CronJobRelateMachines(rc.MetaCtx, cronJobId, jobForm.MachineIds)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *MachineCronJob) Delete(rc *req.Ctx) {
 | 
					func (m *MachineCronJob) Delete(rc *req.Ctx) {
 | 
				
			||||||
@@ -51,7 +51,7 @@ func (m *MachineCronJob) Delete(rc *req.Ctx) {
 | 
				
			|||||||
	for _, v := range ids {
 | 
						for _, v := range ids {
 | 
				
			||||||
		value, err := strconv.Atoi(v)
 | 
							value, err := strconv.Atoi(v)
 | 
				
			||||||
		biz.ErrIsNilAppendErr(err, "string类型转换为int异常: %s")
 | 
							biz.ErrIsNilAppendErr(err, "string类型转换为int异常: %s")
 | 
				
			||||||
		m.MachineCronJobApp.Delete(uint64(value))
 | 
							m.MachineCronJobApp.Delete(rc.MetaCtx, uint64(value))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -52,14 +52,13 @@ 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 := new(form.MachineFileForm)
 | 
				
			||||||
	entity := ginx.BindJsonAndCopyTo[*entity.MachineFile](rc.GinCtx, fileForm, new(entity.MachineFile))
 | 
						entity := ginx.BindJsonAndCopyTo[*entity.MachineFile](rc.GinCtx, fileForm, new(entity.MachineFile))
 | 
				
			||||||
	entity.SetBaseInfo(rc.LoginAccount)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rc.ReqParam = fileForm
 | 
						rc.ReqParam = fileForm
 | 
				
			||||||
	biz.ErrIsNil(m.MachineFileApp.Save(entity))
 | 
						biz.ErrIsNil(m.MachineFileApp.Save(rc.MetaCtx, entity))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *MachineFile) DeleteFile(rc *req.Ctx) {
 | 
					func (m *MachineFile) DeleteFile(rc *req.Ctx) {
 | 
				
			||||||
	biz.ErrIsNil(m.MachineFileApp.Delete(GetMachineFileId(rc.GinCtx)))
 | 
						biz.ErrIsNil(m.MachineFileApp.Delete(rc.MetaCtx, GetMachineFileId(rc.GinCtx)))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/***      sftp相关操作      */
 | 
					/***      sftp相关操作      */
 | 
				
			||||||
@@ -190,7 +189,7 @@ func (m *MachineFile) UploadFile(rc *req.Ctx) {
 | 
				
			|||||||
	file, _ := fileheader.Open()
 | 
						file, _ := fileheader.Open()
 | 
				
			||||||
	defer file.Close()
 | 
						defer file.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	la := rc.LoginAccount
 | 
						la := rc.GetLoginAccount()
 | 
				
			||||||
	defer func() {
 | 
						defer func() {
 | 
				
			||||||
		if anyx.ToString(recover()) != "" {
 | 
							if anyx.ToString(recover()) != "" {
 | 
				
			||||||
			logx.Errorf("文件上传失败: %s", err)
 | 
								logx.Errorf("文件上传失败: %s", err)
 | 
				
			||||||
@@ -262,7 +261,7 @@ func (m *MachineFile) UploadFolder(rc *req.Ctx) {
 | 
				
			|||||||
	wg.Add(len(chunks))
 | 
						wg.Add(len(chunks))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	isSuccess := true
 | 
						isSuccess := true
 | 
				
			||||||
	la := rc.LoginAccount
 | 
						la := rc.GetLoginAccount()
 | 
				
			||||||
	for _, chunk := range chunks {
 | 
						for _, chunk := range chunks {
 | 
				
			||||||
		go func(files []FolderFile, wg *sync.WaitGroup) {
 | 
							go func(files []FolderFile, wg *sync.WaitGroup) {
 | 
				
			||||||
			defer func() {
 | 
								defer func() {
 | 
				
			||||||
@@ -298,7 +297,7 @@ func (m *MachineFile) UploadFolder(rc *req.Ctx) {
 | 
				
			|||||||
	wg.Wait()
 | 
						wg.Wait()
 | 
				
			||||||
	if isSuccess {
 | 
						if isSuccess {
 | 
				
			||||||
		// 保存消息并发送文件上传成功通知
 | 
							// 保存消息并发送文件上传成功通知
 | 
				
			||||||
		m.MsgApp.CreateAndSend(rc.LoginAccount, msgdto.SuccessSysMsg("文件上传成功", fmt.Sprintf("[%s]文件夹已成功上传至 %s[%s:%s]", folderName, mi.Name, mi.Ip, basePath)))
 | 
							m.MsgApp.CreateAndSend(la, msgdto.SuccessSysMsg("文件上传成功", fmt.Sprintf("[%s]文件夹已成功上传至 %s[%s:%s]", folderName, mi.Name, mi.Ip, basePath)))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -37,9 +37,7 @@ func (m *MachineScript) SaveMachineScript(rc *req.Ctx) {
 | 
				
			|||||||
	machineScript := ginx.BindJsonAndCopyTo(rc.GinCtx, form, new(entity.MachineScript))
 | 
						machineScript := ginx.BindJsonAndCopyTo(rc.GinCtx, form, new(entity.MachineScript))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rc.ReqParam = form
 | 
						rc.ReqParam = form
 | 
				
			||||||
	machineScript.SetBaseInfo(rc.LoginAccount)
 | 
						biz.ErrIsNil(m.MachineScriptApp.Save(rc.MetaCtx, machineScript))
 | 
				
			||||||
 | 
					 | 
				
			||||||
	biz.ErrIsNil(m.MachineScriptApp.Save(machineScript))
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *MachineScript) DeleteMachineScript(rc *req.Ctx) {
 | 
					func (m *MachineScript) DeleteMachineScript(rc *req.Ctx) {
 | 
				
			||||||
@@ -50,7 +48,7 @@ func (m *MachineScript) DeleteMachineScript(rc *req.Ctx) {
 | 
				
			|||||||
	for _, v := range ids {
 | 
						for _, v := range ids {
 | 
				
			||||||
		value, err := strconv.Atoi(v)
 | 
							value, err := strconv.Atoi(v)
 | 
				
			||||||
		biz.ErrIsNilAppendErr(err, "string类型转换为int异常: %s")
 | 
							biz.ErrIsNilAppendErr(err, "string类型转换为int异常: %s")
 | 
				
			||||||
		m.MachineScriptApp.Delete(uint64(value))
 | 
							m.MachineScriptApp.Delete(rc.MetaCtx, uint64(value))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -71,7 +69,7 @@ func (m *MachineScript) RunMachineScript(rc *req.Ctx) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	cli, err := m.MachineApp.GetCli(machineId)
 | 
						cli, err := m.MachineApp.GetCli(machineId)
 | 
				
			||||||
	biz.ErrIsNilAppendErr(err, "获取客户端连接失败: %s")
 | 
						biz.ErrIsNilAppendErr(err, "获取客户端连接失败: %s")
 | 
				
			||||||
	biz.ErrIsNilAppendErr(m.TagApp.CanAccess(rc.LoginAccount.Id, cli.Info.TagPath), "%s")
 | 
						biz.ErrIsNilAppendErr(m.TagApp.CanAccess(rc.GetLoginAccount().Id, cli.Info.TagPath), "%s")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	res, err := cli.Run(script)
 | 
						res, err := cli.Run(script)
 | 
				
			||||||
	// 记录请求参数
 | 
						// 记录请求参数
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,11 +26,13 @@ type MachineVO struct {
 | 
				
			|||||||
	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"`
 | 
				
			||||||
	HasCli             bool       `json:"hasCli" gorm:"-"`
 | 
					 | 
				
			||||||
	Remark             *string    `json:"remark"`
 | 
						Remark             *string    `json:"remark"`
 | 
				
			||||||
	EnableRecorder     int8       `json:"enableRecorder"`
 | 
						EnableRecorder     int8       `json:"enableRecorder"`
 | 
				
			||||||
	TagId              uint64     `json:"tagId"`
 | 
						TagId              uint64     `json:"tagId"`
 | 
				
			||||||
	TagPath            string     `json:"tagPath"`
 | 
						TagPath            string     `json:"tagPath"`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						HasCli bool           `json:"hasCli" gorm:"-"`
 | 
				
			||||||
 | 
						Stat   map[string]any `json:"stat" gorm:"-"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type MachineScriptVO struct {
 | 
					type MachineScriptVO struct {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
package application
 | 
					package application
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
	"mayfly-go/internal/machine/domain/entity"
 | 
						"mayfly-go/internal/machine/domain/entity"
 | 
				
			||||||
	"mayfly-go/internal/machine/domain/repository"
 | 
						"mayfly-go/internal/machine/domain/repository"
 | 
				
			||||||
	"mayfly-go/pkg/base"
 | 
						"mayfly-go/pkg/base"
 | 
				
			||||||
@@ -13,7 +14,7 @@ type AuthCert interface {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	GetPageList(condition *entity.AuthCertQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error)
 | 
						GetPageList(condition *entity.AuthCertQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Save(ac *entity.AuthCert) error
 | 
						Save(ctx context.Context, ac *entity.AuthCert) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	GetByIds(ids ...uint64) []*entity.AuthCert
 | 
						GetByIds(ids ...uint64) []*entity.AuthCert
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -32,7 +33,7 @@ func (a *authCertAppImpl) GetPageList(condition *entity.AuthCertQuery, pageParam
 | 
				
			|||||||
	return a.GetRepo().GetPageList(condition, pageParam, toEntity)
 | 
						return a.GetRepo().GetPageList(condition, pageParam, toEntity)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (a *authCertAppImpl) Save(ac *entity.AuthCert) error {
 | 
					func (a *authCertAppImpl) Save(ctx context.Context, ac *entity.AuthCert) error {
 | 
				
			||||||
	oldAc := &entity.AuthCert{Name: ac.Name}
 | 
						oldAc := &entity.AuthCert{Name: ac.Name}
 | 
				
			||||||
	err := a.GetBy(oldAc, "Id", "Name")
 | 
						err := a.GetBy(oldAc, "Id", "Name")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -41,14 +42,14 @@ func (a *authCertAppImpl) Save(ac *entity.AuthCert) error {
 | 
				
			|||||||
		if err == nil {
 | 
							if err == nil {
 | 
				
			||||||
			return errorx.NewBiz("该凭证名已存在")
 | 
								return errorx.NewBiz("该凭证名已存在")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return a.Insert(ac)
 | 
							return a.Insert(ctx, ac)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 如果存在该库,则校验修改的库是否为该库
 | 
						// 如果存在该库,则校验修改的库是否为该库
 | 
				
			||||||
	if err == nil && oldAc.Id != ac.Id {
 | 
						if err == nil && oldAc.Id != ac.Id {
 | 
				
			||||||
		return errorx.NewBiz("该凭证名已存在")
 | 
							return errorx.NewBiz("该凭证名已存在")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return a.UpdateById(ac)
 | 
						return a.UpdateById(ctx, ac)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (a *authCertAppImpl) GetByIds(ids ...uint64) []*entity.AuthCert {
 | 
					func (a *authCertAppImpl) GetByIds(ids ...uint64) []*entity.AuthCert {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,14 +1,20 @@
 | 
				
			|||||||
package application
 | 
					package application
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
	"mayfly-go/internal/machine/api/vo"
 | 
						"mayfly-go/internal/machine/api/vo"
 | 
				
			||||||
	"mayfly-go/internal/machine/domain/entity"
 | 
						"mayfly-go/internal/machine/domain/entity"
 | 
				
			||||||
	"mayfly-go/internal/machine/domain/repository"
 | 
						"mayfly-go/internal/machine/domain/repository"
 | 
				
			||||||
 | 
						"mayfly-go/internal/machine/infrastructure/cache"
 | 
				
			||||||
	"mayfly-go/internal/machine/mcm"
 | 
						"mayfly-go/internal/machine/mcm"
 | 
				
			||||||
	"mayfly-go/pkg/base"
 | 
						"mayfly-go/pkg/base"
 | 
				
			||||||
	"mayfly-go/pkg/errorx"
 | 
						"mayfly-go/pkg/errorx"
 | 
				
			||||||
	"mayfly-go/pkg/gormx"
 | 
						"mayfly-go/pkg/gormx"
 | 
				
			||||||
 | 
						"mayfly-go/pkg/logx"
 | 
				
			||||||
	"mayfly-go/pkg/model"
 | 
						"mayfly-go/pkg/model"
 | 
				
			||||||
 | 
						"mayfly-go/pkg/scheduler"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"gorm.io/gorm"
 | 
						"gorm.io/gorm"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -16,17 +22,17 @@ import (
 | 
				
			|||||||
type Machine interface {
 | 
					type Machine interface {
 | 
				
			||||||
	base.App[*entity.Machine]
 | 
						base.App[*entity.Machine]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Save(*entity.Machine) error
 | 
						Save(ctx context.Context, m *entity.Machine) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 测试机器连接
 | 
						// 测试机器连接
 | 
				
			||||||
	TestConn(me *entity.Machine) error
 | 
						TestConn(me *entity.Machine) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 调整机器状态
 | 
						// 调整机器状态
 | 
				
			||||||
	ChangeStatus(id uint64, status int8) error
 | 
						ChangeStatus(ctx context.Context, id uint64, status int8) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Count(condition *entity.MachineQuery) int64
 | 
						Count(condition *entity.MachineQuery) int64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Delete(id uint64) error
 | 
						Delete(ctx context.Context, id uint64) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 分页获取机器信息列表
 | 
						// 分页获取机器信息列表
 | 
				
			||||||
	GetMachineList(condition *entity.MachineQuery, pageParam *model.PageParam, toEntity *[]*vo.MachineVO, orderBy ...string) (*model.PageResult[*[]*vo.MachineVO], error)
 | 
						GetMachineList(condition *entity.MachineQuery, pageParam *model.PageParam, toEntity *[]*vo.MachineVO, orderBy ...string) (*model.PageResult[*[]*vo.MachineVO], error)
 | 
				
			||||||
@@ -36,6 +42,12 @@ type Machine interface {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// 获取ssh隧道机器连接
 | 
						// 获取ssh隧道机器连接
 | 
				
			||||||
	GetSshTunnelMachine(id int) (*mcm.SshTunnelMachine, error)
 | 
						GetSshTunnelMachine(id int) (*mcm.SshTunnelMachine, error)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 定时更新机器状态信息
 | 
				
			||||||
 | 
						TimerUpdateStats()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 获取机器运行时状态信息
 | 
				
			||||||
 | 
						GetMachineStats(machineId uint64) (*mcm.Stats, error)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func newMachineApp(machineRepo repository.Machine, authCertApp AuthCert) Machine {
 | 
					func newMachineApp(machineRepo repository.Machine, authCertApp AuthCert) Machine {
 | 
				
			||||||
@@ -61,7 +73,7 @@ func (m *machineAppImpl) Count(condition *entity.MachineQuery) int64 {
 | 
				
			|||||||
	return m.GetRepo().Count(condition)
 | 
						return m.GetRepo().Count(condition)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *machineAppImpl) Save(me *entity.Machine) error {
 | 
					func (m *machineAppImpl) Save(ctx context.Context, me *entity.Machine) error {
 | 
				
			||||||
	oldMachine := &entity.Machine{Ip: me.Ip, Port: me.Port, Username: me.Username}
 | 
						oldMachine := &entity.Machine{Ip: me.Ip, Port: me.Port, Username: me.Username}
 | 
				
			||||||
	if me.SshTunnelMachineId > 0 {
 | 
						if me.SshTunnelMachineId > 0 {
 | 
				
			||||||
		oldMachine.SshTunnelMachineId = me.SshTunnelMachineId
 | 
							oldMachine.SshTunnelMachineId = me.SshTunnelMachineId
 | 
				
			||||||
@@ -75,7 +87,7 @@ func (m *machineAppImpl) Save(me *entity.Machine) error {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		// 新增机器,默认启用状态
 | 
							// 新增机器,默认启用状态
 | 
				
			||||||
		me.Status = entity.MachineStatusEnable
 | 
							me.Status = entity.MachineStatusEnable
 | 
				
			||||||
		return m.Insert(me)
 | 
							return m.Insert(ctx, me)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 如果存在该库,则校验修改的库是否为该库
 | 
						// 如果存在该库,则校验修改的库是否为该库
 | 
				
			||||||
@@ -85,7 +97,7 @@ func (m *machineAppImpl) Save(me *entity.Machine) error {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// 关闭连接
 | 
						// 关闭连接
 | 
				
			||||||
	mcm.DeleteCli(me.Id)
 | 
						mcm.DeleteCli(me.Id)
 | 
				
			||||||
	return m.UpdateById(me)
 | 
						return m.UpdateById(ctx, me)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *machineAppImpl) TestConn(me *entity.Machine) error {
 | 
					func (m *machineAppImpl) TestConn(me *entity.Machine) error {
 | 
				
			||||||
@@ -102,7 +114,7 @@ func (m *machineAppImpl) TestConn(me *entity.Machine) error {
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *machineAppImpl) ChangeStatus(id uint64, status int8) error {
 | 
					func (m *machineAppImpl) ChangeStatus(ctx context.Context, id uint64, status int8) error {
 | 
				
			||||||
	if status == entity.MachineStatusDisable {
 | 
						if status == entity.MachineStatusDisable {
 | 
				
			||||||
		// 关闭连接
 | 
							// 关闭连接
 | 
				
			||||||
		mcm.DeleteCli(id)
 | 
							mcm.DeleteCli(id)
 | 
				
			||||||
@@ -110,11 +122,11 @@ func (m *machineAppImpl) ChangeStatus(id uint64, status int8) error {
 | 
				
			|||||||
	machine := new(entity.Machine)
 | 
						machine := new(entity.Machine)
 | 
				
			||||||
	machine.Id = id
 | 
						machine.Id = id
 | 
				
			||||||
	machine.Status = status
 | 
						machine.Status = status
 | 
				
			||||||
	return m.UpdateById(machine)
 | 
						return m.UpdateById(ctx, machine)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 根据条件获取机器信息
 | 
					// 根据条件获取机器信息
 | 
				
			||||||
func (m *machineAppImpl) Delete(id uint64) error {
 | 
					func (m *machineAppImpl) Delete(ctx context.Context, id uint64) error {
 | 
				
			||||||
	// 关闭连接
 | 
						// 关闭连接
 | 
				
			||||||
	mcm.DeleteCli(id)
 | 
						mcm.DeleteCli(id)
 | 
				
			||||||
	return gormx.Tx(
 | 
						return gormx.Tx(
 | 
				
			||||||
@@ -145,6 +157,39 @@ func (m *machineAppImpl) GetSshTunnelMachine(machineId int) (*mcm.SshTunnelMachi
 | 
				
			|||||||
	})
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *machineAppImpl) TimerUpdateStats() {
 | 
				
			||||||
 | 
						logx.Debug("开始定时收集并缓存服务器状态信息...")
 | 
				
			||||||
 | 
						scheduler.AddFun("@every 2m", func() {
 | 
				
			||||||
 | 
							machineIds := new([]entity.Machine)
 | 
				
			||||||
 | 
							m.GetRepo().ListByCond(&entity.Machine{Status: entity.MachineStatusEnable}, machineIds, "id")
 | 
				
			||||||
 | 
							for _, ma := range *machineIds {
 | 
				
			||||||
 | 
								go func(mid uint64) {
 | 
				
			||||||
 | 
									defer func() {
 | 
				
			||||||
 | 
										if err := recover(); err != nil {
 | 
				
			||||||
 | 
											logx.ErrorTrace(fmt.Sprintf("定时获取机器[id=%d]状态信息失败", mid), err.(error))
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}()
 | 
				
			||||||
 | 
									logx.Debugf("定时获取机器[id=%d]状态信息开始", mid)
 | 
				
			||||||
 | 
									cli, err := m.GetCli(mid)
 | 
				
			||||||
 | 
									// ssh获取客户端失败,则更新机器状态为禁用
 | 
				
			||||||
 | 
									if err != nil {
 | 
				
			||||||
 | 
										updateMachine := &entity.Machine{Status: entity.MachineStatusDisable}
 | 
				
			||||||
 | 
										updateMachine.Id = mid
 | 
				
			||||||
 | 
										now := time.Now()
 | 
				
			||||||
 | 
										updateMachine.UpdateTime = &now
 | 
				
			||||||
 | 
										m.UpdateById(context.TODO(), updateMachine)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									cache.SaveMachineStats(mid, cli.GetAllStats())
 | 
				
			||||||
 | 
									logx.Debugf("定时获取机器[id=%d]状态信息结束", mid)
 | 
				
			||||||
 | 
								}(ma.Id)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *machineAppImpl) GetMachineStats(machineId uint64) (*mcm.Stats, error) {
 | 
				
			||||||
 | 
						return cache.GetMachineStats(machineId)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 生成机器信息,根据授权凭证id填充用户密码等
 | 
					// 生成机器信息,根据授权凭证id填充用户密码等
 | 
				
			||||||
func (m *machineAppImpl) toMachineInfoById(machineId uint64) (*mcm.MachineInfo, error) {
 | 
					func (m *machineAppImpl) toMachineInfoById(machineId uint64) (*mcm.MachineInfo, error) {
 | 
				
			||||||
	me, err := m.GetById(new(entity.Machine), machineId)
 | 
						me, err := m.GetById(new(entity.Machine), machineId)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
package application
 | 
					package application
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
	"mayfly-go/internal/machine/domain/entity"
 | 
						"mayfly-go/internal/machine/domain/entity"
 | 
				
			||||||
	"mayfly-go/internal/machine/domain/repository"
 | 
						"mayfly-go/internal/machine/domain/repository"
 | 
				
			||||||
	"mayfly-go/pkg/base"
 | 
						"mayfly-go/pkg/base"
 | 
				
			||||||
@@ -25,9 +26,9 @@ type MachineCronJob interface {
 | 
				
			|||||||
	// 获取分页执行结果列表
 | 
						// 获取分页执行结果列表
 | 
				
			||||||
	GetExecPageList(condition *entity.MachineCronJobExec, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error)
 | 
						GetExecPageList(condition *entity.MachineCronJobExec, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Save(entity *entity.MachineCronJob) (uint64, error)
 | 
						Save(ctx context.Context, entity *entity.MachineCronJob) (uint64, error)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Delete(id uint64)
 | 
						Delete(ctx context.Context, id uint64)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 获取计划任务关联的机器列表id
 | 
						// 获取计划任务关联的机器列表id
 | 
				
			||||||
	GetRelateMachineIds(cronJobId uint64) []uint64
 | 
						GetRelateMachineIds(cronJobId uint64) []uint64
 | 
				
			||||||
@@ -36,10 +37,10 @@ type MachineCronJob interface {
 | 
				
			|||||||
	GetRelateCronJobIds(machineId uint64) []uint64
 | 
						GetRelateCronJobIds(machineId uint64) []uint64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 计划任务关联机器
 | 
						// 计划任务关联机器
 | 
				
			||||||
	CronJobRelateMachines(cronJobId uint64, machineIds []uint64, la *model.LoginAccount)
 | 
						CronJobRelateMachines(ctx context.Context, cronJobId uint64, machineIds []uint64)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 机器关联计划任务
 | 
						// 机器关联计划任务
 | 
				
			||||||
	MachineRelateCronJobs(machineId uint64, cronJobs []uint64, la *model.LoginAccount)
 | 
						MachineRelateCronJobs(ctx context.Context, machineId uint64, cronJobs []uint64)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 初始化计划任务
 | 
						// 初始化计划任务
 | 
				
			||||||
	InitCronJob()
 | 
						InitCronJob()
 | 
				
			||||||
@@ -79,10 +80,10 @@ func (m *machineCropJobAppImpl) GetExecPageList(condition *entity.MachineCronJob
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 保存机器任务信息
 | 
					// 保存机器任务信息
 | 
				
			||||||
func (m *machineCropJobAppImpl) Save(mcj *entity.MachineCronJob) (uint64, error) {
 | 
					func (m *machineCropJobAppImpl) Save(ctx context.Context, mcj *entity.MachineCronJob) (uint64, error) {
 | 
				
			||||||
	// 更新操作
 | 
						// 更新操作
 | 
				
			||||||
	if mcj.Id != 0 {
 | 
						if mcj.Id != 0 {
 | 
				
			||||||
		m.UpdateById(mcj)
 | 
							m.UpdateById(ctx, mcj)
 | 
				
			||||||
		cj, err := m.GetById(new(entity.MachineCronJob), mcj.Id)
 | 
							cj, err := m.GetById(new(entity.MachineCronJob), mcj.Id)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return 0, errorx.NewBiz("该任务不存在")
 | 
								return 0, errorx.NewBiz("该任务不存在")
 | 
				
			||||||
@@ -93,16 +94,16 @@ func (m *machineCropJobAppImpl) Save(mcj *entity.MachineCronJob) (uint64, error)
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	m.addCronJob(mcj)
 | 
						m.addCronJob(mcj)
 | 
				
			||||||
	if err := m.Insert(mcj); err != nil {
 | 
						if err := m.Insert(ctx, mcj); err != nil {
 | 
				
			||||||
		return 0, err
 | 
							return 0, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return mcj.Id, nil
 | 
						return mcj.Id, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *machineCropJobAppImpl) Delete(id uint64) {
 | 
					func (m *machineCropJobAppImpl) Delete(ctx context.Context, id uint64) {
 | 
				
			||||||
	m.DeleteById(id)
 | 
						m.DeleteById(ctx, id)
 | 
				
			||||||
	m.machineCropJobExecRepo.DeleteByCond(&entity.MachineCronJobExec{CronJobId: id})
 | 
						m.machineCropJobExecRepo.DeleteByCond(ctx, &entity.MachineCronJobExec{CronJobId: id})
 | 
				
			||||||
	m.machineCropJobRelateRepo.DeleteByCond(&entity.MachineCronJobRelate{CronJobId: id})
 | 
						m.machineCropJobRelateRepo.DeleteByCond(ctx, &entity.MachineCronJobRelate{CronJobId: id})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *machineCropJobAppImpl) GetRelateMachineIds(cronJobId uint64) []uint64 {
 | 
					func (m *machineCropJobAppImpl) GetRelateMachineIds(cronJobId uint64) []uint64 {
 | 
				
			||||||
@@ -113,47 +114,39 @@ func (m *machineCropJobAppImpl) GetRelateCronJobIds(machineId uint64) []uint64 {
 | 
				
			|||||||
	return m.machineCropJobRelateRepo.GetCronJobIds(machineId)
 | 
						return m.machineCropJobRelateRepo.GetCronJobIds(machineId)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *machineCropJobAppImpl) CronJobRelateMachines(cronJobId uint64, machineIds []uint64, la *model.LoginAccount) {
 | 
					func (m *machineCropJobAppImpl) CronJobRelateMachines(ctx context.Context, cronJobId uint64, machineIds []uint64) {
 | 
				
			||||||
	oldMachineIds := m.machineCropJobRelateRepo.GetMachineIds(cronJobId)
 | 
						oldMachineIds := m.machineCropJobRelateRepo.GetMachineIds(cronJobId)
 | 
				
			||||||
	addIds, delIds, _ := collx.ArrayCompare[uint64](machineIds, oldMachineIds, func(u1, u2 uint64) bool { return u1 == u2 })
 | 
						addIds, delIds, _ := collx.ArrayCompare[uint64](machineIds, oldMachineIds, func(u1, u2 uint64) bool { return u1 == u2 })
 | 
				
			||||||
	addVals := make([]*entity.MachineCronJobRelate, 0)
 | 
						addVals := make([]*entity.MachineCronJobRelate, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	now := time.Now()
 | 
					 | 
				
			||||||
	for _, addId := range addIds {
 | 
						for _, addId := range addIds {
 | 
				
			||||||
		addVals = append(addVals, &entity.MachineCronJobRelate{
 | 
							addVals = append(addVals, &entity.MachineCronJobRelate{
 | 
				
			||||||
			MachineId:  addId,
 | 
								MachineId: addId,
 | 
				
			||||||
			CronJobId:  cronJobId,
 | 
								CronJobId: cronJobId,
 | 
				
			||||||
			Creator:    la.Username,
 | 
					 | 
				
			||||||
			CreatorId:  la.Id,
 | 
					 | 
				
			||||||
			CreateTime: &now,
 | 
					 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	m.machineCropJobRelateRepo.BatchInsert(addVals)
 | 
						m.machineCropJobRelateRepo.BatchInsert(ctx, addVals)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, delId := range delIds {
 | 
						for _, delId := range delIds {
 | 
				
			||||||
		m.machineCropJobRelateRepo.DeleteByCond(&entity.MachineCronJobRelate{CronJobId: cronJobId, MachineId: delId})
 | 
							m.machineCropJobRelateRepo.DeleteByCond(ctx, &entity.MachineCronJobRelate{CronJobId: cronJobId, MachineId: delId})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *machineCropJobAppImpl) MachineRelateCronJobs(machineId uint64, cronJobs []uint64, la *model.LoginAccount) {
 | 
					func (m *machineCropJobAppImpl) MachineRelateCronJobs(ctx context.Context, machineId uint64, cronJobs []uint64) {
 | 
				
			||||||
	oldCronIds := m.machineCropJobRelateRepo.GetCronJobIds(machineId)
 | 
						oldCronIds := m.machineCropJobRelateRepo.GetCronJobIds(machineId)
 | 
				
			||||||
	addIds, delIds, _ := collx.ArrayCompare[uint64](cronJobs, oldCronIds, func(u1, u2 uint64) bool { return u1 == u2 })
 | 
						addIds, delIds, _ := collx.ArrayCompare[uint64](cronJobs, oldCronIds, func(u1, u2 uint64) bool { return u1 == u2 })
 | 
				
			||||||
	addVals := make([]*entity.MachineCronJobRelate, 0)
 | 
						addVals := make([]*entity.MachineCronJobRelate, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	now := time.Now()
 | 
					 | 
				
			||||||
	for _, addId := range addIds {
 | 
						for _, addId := range addIds {
 | 
				
			||||||
		addVals = append(addVals, &entity.MachineCronJobRelate{
 | 
							addVals = append(addVals, &entity.MachineCronJobRelate{
 | 
				
			||||||
			MachineId:  machineId,
 | 
								MachineId: machineId,
 | 
				
			||||||
			CronJobId:  addId,
 | 
								CronJobId: addId,
 | 
				
			||||||
			Creator:    la.Username,
 | 
					 | 
				
			||||||
			CreatorId:  la.Id,
 | 
					 | 
				
			||||||
			CreateTime: &now,
 | 
					 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	m.machineCropJobRelateRepo.BatchInsert(addVals)
 | 
						m.machineCropJobRelateRepo.BatchInsert(ctx, addVals)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, delId := range delIds {
 | 
						for _, delId := range delIds {
 | 
				
			||||||
		m.machineCropJobRelateRepo.DeleteByCond(&entity.MachineCronJobRelate{CronJobId: delId, MachineId: machineId})
 | 
							m.machineCropJobRelateRepo.DeleteByCond(ctx, &entity.MachineCronJobRelate{CronJobId: delId, MachineId: machineId})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -240,7 +233,7 @@ func (m *machineCropJobAppImpl) runCronJob0(mid uint64, cronJob *entity.MachineC
 | 
				
			|||||||
	defer func() {
 | 
						defer func() {
 | 
				
			||||||
		if err := recover(); err != nil {
 | 
							if err := recover(); err != nil {
 | 
				
			||||||
			res := anyx.ToString(err)
 | 
								res := anyx.ToString(err)
 | 
				
			||||||
			m.machineCropJobExecRepo.Insert(&entity.MachineCronJobExec{
 | 
								m.machineCropJobExecRepo.Insert(context.TODO(), &entity.MachineCronJobExec{
 | 
				
			||||||
				MachineId: mid,
 | 
									MachineId: mid,
 | 
				
			||||||
				CronJobId: cronJob.Id,
 | 
									CronJobId: cronJob.Id,
 | 
				
			||||||
				ExecTime:  time.Now(),
 | 
									ExecTime:  time.Now(),
 | 
				
			||||||
@@ -280,5 +273,5 @@ func (m *machineCropJobAppImpl) runCronJob0(mid uint64, cronJob *entity.MachineC
 | 
				
			|||||||
		execRes.Status = entity.MachineCronJobExecStatusError
 | 
							execRes.Status = entity.MachineCronJobExecStatusError
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// 保存执行记录
 | 
						// 保存执行记录
 | 
				
			||||||
	m.machineCropJobExecRepo.Insert(execRes)
 | 
						m.machineCropJobExecRepo.Insert(context.TODO(), execRes)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
package application
 | 
					package application
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"io"
 | 
						"io"
 | 
				
			||||||
@@ -27,9 +28,9 @@ type MachineFile interface {
 | 
				
			|||||||
	// 根据id获取
 | 
						// 根据id获取
 | 
				
			||||||
	GetById(id uint64, cols ...string) *entity.MachineFile
 | 
						GetById(id uint64, cols ...string) *entity.MachineFile
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Save(entity *entity.MachineFile) error
 | 
						Save(ctx context.Context, entity *entity.MachineFile) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Delete(id uint64) error
 | 
						Delete(ctx context.Context, id uint64) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 获取文件关联的机器信息,主要用于记录日志使用
 | 
						// 获取文件关联的机器信息,主要用于记录日志使用
 | 
				
			||||||
	// GetMachine(fileId uint64) *mcm.Info
 | 
						// GetMachine(fileId uint64) *mcm.Info
 | 
				
			||||||
@@ -91,31 +92,34 @@ func (m *machineFileAppImpl) GetPageList(condition *entity.MachineFile, pagePara
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// 根据条件获取
 | 
					// 根据条件获取
 | 
				
			||||||
func (m *machineFileAppImpl) GetMachineFile(condition *entity.MachineFile, cols ...string) error {
 | 
					func (m *machineFileAppImpl) GetMachineFile(condition *entity.MachineFile, cols ...string) error {
 | 
				
			||||||
	return m.machineFileRepo.GetMachineFile(condition, cols...)
 | 
						return m.machineFileRepo.GetBy(condition, cols...)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 根据id获取
 | 
					// 根据id获取
 | 
				
			||||||
func (m *machineFileAppImpl) GetById(id uint64, cols ...string) *entity.MachineFile {
 | 
					func (m *machineFileAppImpl) GetById(id uint64, cols ...string) *entity.MachineFile {
 | 
				
			||||||
	return m.machineFileRepo.GetById(id, cols...)
 | 
						mf := new(entity.MachineFile)
 | 
				
			||||||
 | 
						if err := m.machineFileRepo.GetById(mf, id, cols...); err == nil {
 | 
				
			||||||
 | 
							return mf
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 保存机器文件配置
 | 
					// 保存机器文件配置
 | 
				
			||||||
func (m *machineFileAppImpl) Save(mf *entity.MachineFile) error {
 | 
					func (m *machineFileAppImpl) Save(ctx context.Context, mf *entity.MachineFile) error {
 | 
				
			||||||
	_, err := m.machineApp.GetById(new(entity.Machine), mf.MachineId, "Name")
 | 
						_, err := m.machineApp.GetById(new(entity.Machine), mf.MachineId, "Name")
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return errorx.NewBiz("该机器不存在")
 | 
							return errorx.NewBiz("该机器不存在")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if mf.Id != 0 {
 | 
						if mf.Id != 0 {
 | 
				
			||||||
		return m.machineFileRepo.UpdateById(mf)
 | 
							return m.machineFileRepo.UpdateById(ctx, mf)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return m.machineFileRepo.Create(mf)
 | 
						return m.machineFileRepo.Insert(ctx, mf)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 根据id删除
 | 
					func (m *machineFileAppImpl) Delete(ctx context.Context, id uint64) error {
 | 
				
			||||||
func (m *machineFileAppImpl) Delete(id uint64) error {
 | 
						return m.machineFileRepo.DeleteById(ctx, id)
 | 
				
			||||||
	return m.machineFileRepo.Delete(id)
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *machineFileAppImpl) ReadDir(fid uint64, path string) ([]fs.FileInfo, error) {
 | 
					func (m *machineFileAppImpl) ReadDir(fid uint64, path string) ([]fs.FileInfo, error) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
package application
 | 
					package application
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
	"mayfly-go/internal/machine/domain/entity"
 | 
						"mayfly-go/internal/machine/domain/entity"
 | 
				
			||||||
	"mayfly-go/internal/machine/domain/repository"
 | 
						"mayfly-go/internal/machine/domain/repository"
 | 
				
			||||||
	"mayfly-go/pkg/base"
 | 
						"mayfly-go/pkg/base"
 | 
				
			||||||
@@ -14,9 +15,9 @@ type MachineScript interface {
 | 
				
			|||||||
	// 分页获取机器脚本信息列表
 | 
						// 分页获取机器脚本信息列表
 | 
				
			||||||
	GetPageList(condition *entity.MachineScript, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error)
 | 
						GetPageList(condition *entity.MachineScript, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Save(entity *entity.MachineScript) error
 | 
						Save(ctx context.Context, entity *entity.MachineScript) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Delete(id uint64)
 | 
						Delete(ctx context.Context, id uint64)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func newMachineScriptApp(machineScriptRepo repository.MachineScript, machineApp Machine) MachineScript {
 | 
					func newMachineScriptApp(machineScriptRepo repository.MachineScript, machineApp Machine) MachineScript {
 | 
				
			||||||
@@ -39,7 +40,7 @@ func (m *machineScriptAppImpl) GetPageList(condition *entity.MachineScript, page
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 保存机器脚本
 | 
					// 保存机器脚本
 | 
				
			||||||
func (m *machineScriptAppImpl) Save(ms *entity.MachineScript) error {
 | 
					func (m *machineScriptAppImpl) Save(ctx context.Context, ms *entity.MachineScript) error {
 | 
				
			||||||
	// 如果机器id不为公共脚本id,则校验机器是否存在
 | 
						// 如果机器id不为公共脚本id,则校验机器是否存在
 | 
				
			||||||
	if machineId := ms.MachineId; machineId != Common_Script_Machine_Id {
 | 
						if machineId := ms.MachineId; machineId != Common_Script_Machine_Id {
 | 
				
			||||||
		_, err := m.machineApp.GetById(new(entity.Machine), machineId, "Name")
 | 
							_, err := m.machineApp.GetById(new(entity.Machine), machineId, "Name")
 | 
				
			||||||
@@ -49,12 +50,12 @@ func (m *machineScriptAppImpl) Save(ms *entity.MachineScript) error {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ms.Id != 0 {
 | 
						if ms.Id != 0 {
 | 
				
			||||||
		return m.UpdateById(ms)
 | 
							return m.UpdateById(ctx, ms)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return m.Insert(ms)
 | 
						return m.Insert(ctx, ms)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 根据id删除
 | 
					// 根据id删除
 | 
				
			||||||
func (m *machineScriptAppImpl) Delete(id uint64) {
 | 
					func (m *machineScriptAppImpl) Delete(ctx context.Context, id uint64) {
 | 
				
			||||||
	m.DeleteById(id)
 | 
						m.DeleteById(ctx, id)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,6 +30,13 @@ type MachineCronJobRelate struct {
 | 
				
			|||||||
	CreateTime *time.Time
 | 
						CreateTime *time.Time
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *MachineCronJobRelate) SetBaseInfo(la *model.LoginAccount) {
 | 
				
			||||||
 | 
						now := time.Now()
 | 
				
			||||||
 | 
						m.CreateTime = &now
 | 
				
			||||||
 | 
						m.Creator = la.Username
 | 
				
			||||||
 | 
						m.CreatorId = la.Id
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 机器任务执行记录
 | 
					// 机器任务执行记录
 | 
				
			||||||
type MachineCronJobExec struct {
 | 
					type MachineCronJobExec struct {
 | 
				
			||||||
	model.DeletedModel
 | 
						model.DeletedModel
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,6 +3,7 @@ package entity
 | 
				
			|||||||
type MachineQuery struct {
 | 
					type MachineQuery struct {
 | 
				
			||||||
	Ids     string `json:"ids" form:"ids"`
 | 
						Ids     string `json:"ids" form:"ids"`
 | 
				
			||||||
	Name    string `json:"name" form:"name"`
 | 
						Name    string `json:"name" form:"name"`
 | 
				
			||||||
 | 
						Status  int8   `json:"status" form:"status"`
 | 
				
			||||||
	Ip      string `json:"ip" form:"ip"` // IP地址
 | 
						Ip      string `json:"ip" form:"ip"` // IP地址
 | 
				
			||||||
	TagPath string `json:"tagPath" form:"tagPath"`
 | 
						TagPath string `json:"tagPath" form:"tagPath"`
 | 
				
			||||||
	TagIds  []uint64
 | 
						TagIds  []uint64
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,22 +2,13 @@ package repository
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"mayfly-go/internal/machine/domain/entity"
 | 
						"mayfly-go/internal/machine/domain/entity"
 | 
				
			||||||
 | 
						"mayfly-go/pkg/base"
 | 
				
			||||||
	"mayfly-go/pkg/model"
 | 
						"mayfly-go/pkg/model"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type MachineFile interface {
 | 
					type MachineFile interface {
 | 
				
			||||||
 | 
						base.Repo[*entity.MachineFile]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 分页获取机器脚本信息列表
 | 
						// 分页获取机器脚本信息列表
 | 
				
			||||||
	GetPageList(condition *entity.MachineFile, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error)
 | 
						GetPageList(condition *entity.MachineFile, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error)
 | 
				
			||||||
 | 
					 | 
				
			||||||
	// 根据条件获取
 | 
					 | 
				
			||||||
	GetMachineFile(condition *entity.MachineFile, cols ...string) error
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// 根据id获取
 | 
					 | 
				
			||||||
	GetById(id uint64, cols ...string) *entity.MachineFile
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Delete(id uint64) error
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Create(entity *entity.MachineFile) error
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	UpdateById(entity *entity.MachineFile) error
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										24
									
								
								server/internal/machine/infrastructure/cache/machine_stats.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								server/internal/machine/infrastructure/cache/machine_stats.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
				
			|||||||
 | 
					package cache
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"mayfly-go/internal/machine/mcm"
 | 
				
			||||||
 | 
						global_cache "mayfly-go/pkg/cache"
 | 
				
			||||||
 | 
						"mayfly-go/pkg/utils/jsonx"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const MachineStatCackeKey = "mayfly:machine:%d:stat"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func SaveMachineStats(machineId uint64, stat *mcm.Stats) error {
 | 
				
			||||||
 | 
						return global_cache.SetStr(fmt.Sprintf(MachineStatCackeKey, machineId), jsonx.ToStr(stat), 10*time.Minute)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func GetMachineStats(machineId uint64) (*mcm.Stats, error) {
 | 
				
			||||||
 | 
						cacheStr := global_cache.GetStr(fmt.Sprintf(MachineStatCackeKey, machineId))
 | 
				
			||||||
 | 
						if cacheStr == "" {
 | 
				
			||||||
 | 
							return nil, errors.New("不存在该值")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return jsonx.To(cacheStr, new(mcm.Stats))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -23,6 +23,7 @@ func newMachineRepo() repository.Machine {
 | 
				
			|||||||
// 分页获取机器信息列表
 | 
					// 分页获取机器信息列表
 | 
				
			||||||
func (m *machineRepoImpl) GetMachineList(condition *entity.MachineQuery, pageParam *model.PageParam, toEntity *[]*vo.MachineVO, orderBy ...string) (*model.PageResult[*[]*vo.MachineVO], error) {
 | 
					func (m *machineRepoImpl) GetMachineList(condition *entity.MachineQuery, pageParam *model.PageParam, toEntity *[]*vo.MachineVO, orderBy ...string) (*model.PageResult[*[]*vo.MachineVO], error) {
 | 
				
			||||||
	qd := gormx.NewQuery(new(entity.Machine)).
 | 
						qd := gormx.NewQuery(new(entity.Machine)).
 | 
				
			||||||
 | 
							Eq("status", condition.Status).
 | 
				
			||||||
		Like("ip", condition.Ip).
 | 
							Like("ip", condition.Ip).
 | 
				
			||||||
		Like("name", condition.Name).
 | 
							Like("name", condition.Name).
 | 
				
			||||||
		In("tag_id", condition.TagIds).
 | 
							In("tag_id", condition.TagIds).
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,14 +3,17 @@ package persistence
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"mayfly-go/internal/machine/domain/entity"
 | 
						"mayfly-go/internal/machine/domain/entity"
 | 
				
			||||||
	"mayfly-go/internal/machine/domain/repository"
 | 
						"mayfly-go/internal/machine/domain/repository"
 | 
				
			||||||
 | 
						"mayfly-go/pkg/base"
 | 
				
			||||||
	"mayfly-go/pkg/gormx"
 | 
						"mayfly-go/pkg/gormx"
 | 
				
			||||||
	"mayfly-go/pkg/model"
 | 
						"mayfly-go/pkg/model"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type machineFileRepoImpl struct{}
 | 
					type machineFileRepoImpl struct {
 | 
				
			||||||
 | 
						base.RepoImpl[*entity.MachineFile]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func newMachineFileRepo() repository.MachineFile {
 | 
					func newMachineFileRepo() repository.MachineFile {
 | 
				
			||||||
	return new(machineFileRepoImpl)
 | 
						return &machineFileRepoImpl{base.RepoImpl[*entity.MachineFile]{M: new(entity.MachineFile)}}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 分页获取机器文件信息列表
 | 
					// 分页获取机器文件信息列表
 | 
				
			||||||
@@ -18,30 +21,3 @@ func (m *machineFileRepoImpl) GetPageList(condition *entity.MachineFile, pagePar
 | 
				
			|||||||
	qd := gormx.NewQuery(condition).WithCondModel(condition).WithOrderBy(orderBy...)
 | 
						qd := gormx.NewQuery(condition).WithCondModel(condition).WithOrderBy(orderBy...)
 | 
				
			||||||
	return gormx.PageQuery(qd, pageParam, toEntity)
 | 
						return gormx.PageQuery(qd, pageParam, toEntity)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
// 根据条件获取账号信息
 | 
					 | 
				
			||||||
func (m *machineFileRepoImpl) GetMachineFile(condition *entity.MachineFile, cols ...string) error {
 | 
					 | 
				
			||||||
	return gormx.GetBy(condition, cols...)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 根据id获取
 | 
					 | 
				
			||||||
func (m *machineFileRepoImpl) GetById(id uint64, cols ...string) *entity.MachineFile {
 | 
					 | 
				
			||||||
	ms := new(entity.MachineFile)
 | 
					 | 
				
			||||||
	if err := gormx.GetById(ms, id, cols...); err != nil {
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return ms
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 根据id获取
 | 
					 | 
				
			||||||
func (m *machineFileRepoImpl) Delete(id uint64) error {
 | 
					 | 
				
			||||||
	return gormx.DeleteById(new(entity.MachineFile), id)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (m *machineFileRepoImpl) Create(entity *entity.MachineFile) error {
 | 
					 | 
				
			||||||
	return gormx.Insert(entity)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (m *machineFileRepoImpl) UpdateById(entity *entity.MachineFile) error {
 | 
					 | 
				
			||||||
	return gormx.UpdateById(entity)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,4 +4,5 @@ import "mayfly-go/internal/machine/application"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func Init() {
 | 
					func Init() {
 | 
				
			||||||
	application.GetMachineCronJobApp().InitCronJob()
 | 
						application.GetMachineCronJobApp().InitCronJob()
 | 
				
			||||||
 | 
						application.GetMachineApp().TimerUpdateStats()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -42,7 +42,13 @@ func (c *Cli) GetSession() (*ssh.Session, error) {
 | 
				
			|||||||
	if c.sshClient == nil {
 | 
						if c.sshClient == nil {
 | 
				
			||||||
		return nil, errorx.NewBiz("请先进行机器客户端连接")
 | 
							return nil, errorx.NewBiz("请先进行机器客户端连接")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return c.sshClient.NewSession()
 | 
						session, err := c.sshClient.NewSession()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							// 获取session失败,则关闭cli,重试
 | 
				
			||||||
 | 
							DeleteCli(c.Info.Id)
 | 
				
			||||||
 | 
							return nil, errorx.NewBiz("请重试...")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return session, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 执行shell
 | 
					// 执行shell
 | 
				
			||||||
@@ -51,7 +57,6 @@ func (c *Cli) GetSession() (*ssh.Session, error) {
 | 
				
			|||||||
func (c *Cli) Run(shell string) (string, error) {
 | 
					func (c *Cli) Run(shell string) (string, error) {
 | 
				
			||||||
	session, err := c.GetSession()
 | 
						session, err := c.GetSession()
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		c.Close()
 | 
					 | 
				
			||||||
		return "", err
 | 
							return "", err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer session.Close()
 | 
						defer session.Close()
 | 
				
			||||||
@@ -67,6 +72,10 @@ func (c *Cli) GetAllStats() *Stats {
 | 
				
			|||||||
	res, _ := c.Run(StatsShell)
 | 
						res, _ := c.Run(StatsShell)
 | 
				
			||||||
	infos := strings.Split(res, "-----")
 | 
						infos := strings.Split(res, "-----")
 | 
				
			||||||
	stats := new(Stats)
 | 
						stats := new(Stats)
 | 
				
			||||||
 | 
						if len(infos) < 8 {
 | 
				
			||||||
 | 
							logx.Warnf("获取机器[id=%d, name=%s]的状态信息失败", c.Info.Id, c.Info.Name)
 | 
				
			||||||
 | 
							return stats
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	getUptime(infos[0], stats)
 | 
						getUptime(infos[0], stats)
 | 
				
			||||||
	getHostname(infos[1], stats)
 | 
						getHostname(infos[1], stats)
 | 
				
			||||||
	getLoad(infos[2], stats)
 | 
						getLoad(infos[2], stats)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,48 +9,52 @@ import (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type FSInfo struct {
 | 
					type FSInfo struct {
 | 
				
			||||||
	MountPoint string
 | 
						MountPoint string `json:"mountPoint"`
 | 
				
			||||||
	Used       uint64
 | 
						Used       uint64 `json:"used"`
 | 
				
			||||||
	Free       uint64
 | 
						Free       uint64 `json:"free"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type NetIntfInfo struct {
 | 
					type NetIntfInfo struct {
 | 
				
			||||||
	IPv4 string
 | 
						IPv4 string `json:"ipv4"`
 | 
				
			||||||
	IPv6 string
 | 
						IPv6 string `json:"ipv6"`
 | 
				
			||||||
	Rx   uint64
 | 
						Rx   uint64 `json:"rx"`
 | 
				
			||||||
	Tx   uint64
 | 
						Tx   uint64 `json:"tx"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type MemInfo struct {
 | 
				
			||||||
 | 
						Total     uint64 `json:"total"`
 | 
				
			||||||
 | 
						Free      uint64 `json:"free"`
 | 
				
			||||||
 | 
						Buffers   uint64 `json:"buffers"`
 | 
				
			||||||
 | 
						Available uint64 `json:"available"`
 | 
				
			||||||
 | 
						Cached    uint64 `json:"cached"`
 | 
				
			||||||
 | 
						SwapTotal uint64 `json:"swapTotal"`
 | 
				
			||||||
 | 
						SwapFree  uint64 `json:"swapFree"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type CPUInfo struct {
 | 
					type CPUInfo struct {
 | 
				
			||||||
	User    float32
 | 
						User    float32 `json:"user"`
 | 
				
			||||||
	Nice    float32
 | 
						Nice    float32 `json:"nice"`
 | 
				
			||||||
	System  float32
 | 
						System  float32 `json:"system"`
 | 
				
			||||||
	Idle    float32
 | 
						Idle    float32 `json:"idle"`
 | 
				
			||||||
	Iowait  float32
 | 
						Iowait  float32 `json:"iowait"`
 | 
				
			||||||
	Irq     float32
 | 
						Irq     float32 `json:"irq"`
 | 
				
			||||||
	SoftIrq float32
 | 
						SoftIrq float32 `json:"softIrq"`
 | 
				
			||||||
	Steal   float32
 | 
						Steal   float32 `json:"steal"`
 | 
				
			||||||
	Guest   float32
 | 
						Guest   float32 `json:"guest"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Stats struct {
 | 
					type Stats struct {
 | 
				
			||||||
	Uptime       string
 | 
						Uptime       string                 `json:"uptime"`
 | 
				
			||||||
	Hostname     string
 | 
						Hostname     string                 `json:"hostname"`
 | 
				
			||||||
	Load1        string
 | 
						Load1        string                 `json:"load1"`
 | 
				
			||||||
	Load5        string
 | 
						Load5        string                 `json:"load5"`
 | 
				
			||||||
	Load10       string
 | 
						Load10       string                 `json:"load10"`
 | 
				
			||||||
	RunningProcs string
 | 
						RunningProcs string                 `json:"runningProcs"`
 | 
				
			||||||
	TotalProcs   string
 | 
						TotalProcs   string                 `json:"totalProcs"`
 | 
				
			||||||
	MemTotal     uint64
 | 
						MemInfo      MemInfo                `json:"memInfo"`
 | 
				
			||||||
	MemFree      uint64
 | 
						FSInfos      []FSInfo               `json:"fSInfos"`
 | 
				
			||||||
	MemBuffers   uint64
 | 
						NetIntf      map[string]NetIntfInfo `json:"netIntf"`
 | 
				
			||||||
	MemAvailable uint64
 | 
						CPU          CPUInfo                `json:"cpu"` // or []CPUInfo to get all the cpu-core's stats?
 | 
				
			||||||
	MemCached    uint64
 | 
					 | 
				
			||||||
	SwapTotal    uint64
 | 
					 | 
				
			||||||
	SwapFree     uint64
 | 
					 | 
				
			||||||
	FSInfos      []FSInfo
 | 
					 | 
				
			||||||
	NetIntf      map[string]NetIntfInfo
 | 
					 | 
				
			||||||
	CPU          CPUInfo // or []CPUInfo to get all the cpu-core's stats?
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const StatsShell = `
 | 
					const StatsShell = `
 | 
				
			||||||
@@ -141,19 +145,19 @@ func getMemInfo(memInfo string, stats *Stats) (err error) {
 | 
				
			|||||||
			val *= 1024
 | 
								val *= 1024
 | 
				
			||||||
			switch parts[0] {
 | 
								switch parts[0] {
 | 
				
			||||||
			case "MemTotal:":
 | 
								case "MemTotal:":
 | 
				
			||||||
				stats.MemTotal = val
 | 
									stats.MemInfo.Total = val
 | 
				
			||||||
			case "MemFree:":
 | 
								case "MemFree:":
 | 
				
			||||||
				stats.MemFree = val
 | 
									stats.MemInfo.Free = val
 | 
				
			||||||
			case "Buffers:":
 | 
								case "Buffers:":
 | 
				
			||||||
				stats.MemBuffers = val
 | 
									stats.MemInfo.Buffers = val
 | 
				
			||||||
			case "Cached:":
 | 
								case "Cached:":
 | 
				
			||||||
				stats.MemCached = val
 | 
									stats.MemInfo.Cached = val
 | 
				
			||||||
			case "SwapTotal:":
 | 
								case "SwapTotal:":
 | 
				
			||||||
				stats.SwapTotal = val
 | 
									stats.MemInfo.SwapTotal = val
 | 
				
			||||||
			case "SwapFree:":
 | 
								case "SwapFree:":
 | 
				
			||||||
				stats.SwapFree = val
 | 
									stats.MemInfo.SwapFree = val
 | 
				
			||||||
			case "MemAvailable:":
 | 
								case "MemAvailable:":
 | 
				
			||||||
				stats.MemAvailable = val
 | 
									stats.MemInfo.Available = val
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,7 +30,7 @@ func (m *Mongo) Mongos(rc *req.Ctx) {
 | 
				
			|||||||
	queryCond, page := ginx.BindQueryAndPage[*entity.MongoQuery](rc.GinCtx, new(entity.MongoQuery))
 | 
						queryCond, page := ginx.BindQueryAndPage[*entity.MongoQuery](rc.GinCtx, new(entity.MongoQuery))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 不存在可访问标签id,即没有可操作数据
 | 
						// 不存在可访问标签id,即没有可操作数据
 | 
				
			||||||
	tagIds := m.TagApp.ListTagIdByAccountId(rc.LoginAccount.Id)
 | 
						tagIds := m.TagApp.ListTagIdByAccountId(rc.GetLoginAccount().Id)
 | 
				
			||||||
	if len(tagIds) == 0 {
 | 
						if len(tagIds) == 0 {
 | 
				
			||||||
		rc.ResData = model.EmptyPageResult[any]()
 | 
							rc.ResData = model.EmptyPageResult[any]()
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
@@ -43,7 +43,7 @@ func (m *Mongo) Mongos(rc *req.Ctx) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *Mongo) MongoTags(rc *req.Ctx) {
 | 
					func (m *Mongo) MongoTags(rc *req.Ctx) {
 | 
				
			||||||
	rc.ResData = m.TagApp.ListTagByAccountIdAndResource(rc.LoginAccount.Id, new(entity.Mongo))
 | 
						rc.ResData = m.TagApp.ListTagByAccountIdAndResource(rc.GetLoginAccount().Id, new(entity.Mongo))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *Mongo) Save(rc *req.Ctx) {
 | 
					func (m *Mongo) Save(rc *req.Ctx) {
 | 
				
			||||||
@@ -57,8 +57,7 @@ func (m *Mongo) Save(rc *req.Ctx) {
 | 
				
			|||||||
	}(form.Uri)
 | 
						}(form.Uri)
 | 
				
			||||||
	rc.ReqParam = form
 | 
						rc.ReqParam = form
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mongo.SetBaseInfo(rc.LoginAccount)
 | 
						biz.ErrIsNil(m.MongoApp.Save(rc.MetaCtx, mongo))
 | 
				
			||||||
	biz.ErrIsNil(m.MongoApp.Save(mongo))
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *Mongo) DeleteMongo(rc *req.Ctx) {
 | 
					func (m *Mongo) DeleteMongo(rc *req.Ctx) {
 | 
				
			||||||
@@ -69,7 +68,7 @@ func (m *Mongo) DeleteMongo(rc *req.Ctx) {
 | 
				
			|||||||
	for _, v := range ids {
 | 
						for _, v := range ids {
 | 
				
			||||||
		value, err := strconv.Atoi(v)
 | 
							value, err := strconv.Atoi(v)
 | 
				
			||||||
		biz.ErrIsNilAppendErr(err, "string类型转换为int异常: %s")
 | 
							biz.ErrIsNilAppendErr(err, "string类型转换为int异常: %s")
 | 
				
			||||||
		m.MongoApp.Delete(uint64(value))
 | 
							m.MongoApp.Delete(rc.MetaCtx, uint64(value))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
package application
 | 
					package application
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
	"mayfly-go/internal/mongo/domain/entity"
 | 
						"mayfly-go/internal/mongo/domain/entity"
 | 
				
			||||||
	"mayfly-go/internal/mongo/domain/repository"
 | 
						"mayfly-go/internal/mongo/domain/repository"
 | 
				
			||||||
	"mayfly-go/internal/mongo/mgm"
 | 
						"mayfly-go/internal/mongo/mgm"
 | 
				
			||||||
@@ -17,10 +18,10 @@ type Mongo interface {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	Count(condition *entity.MongoQuery) int64
 | 
						Count(condition *entity.MongoQuery) int64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Save(entity *entity.Mongo) error
 | 
						Save(ctx context.Context, entity *entity.Mongo) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 删除数据库信息
 | 
						// 删除数据库信息
 | 
				
			||||||
	Delete(id uint64) error
 | 
						Delete(ctx context.Context, id uint64) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 获取mongo连接实例
 | 
						// 获取mongo连接实例
 | 
				
			||||||
	// @param id mongo id
 | 
						// @param id mongo id
 | 
				
			||||||
@@ -46,19 +47,19 @@ func (d *mongoAppImpl) Count(condition *entity.MongoQuery) int64 {
 | 
				
			|||||||
	return d.GetRepo().Count(condition)
 | 
						return d.GetRepo().Count(condition)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (d *mongoAppImpl) Delete(id uint64) error {
 | 
					func (d *mongoAppImpl) Delete(ctx context.Context, id uint64) error {
 | 
				
			||||||
	mgm.CloseConn(id)
 | 
						mgm.CloseConn(id)
 | 
				
			||||||
	return d.GetRepo().DeleteById(id)
 | 
						return d.GetRepo().DeleteById(ctx, id)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (d *mongoAppImpl) Save(m *entity.Mongo) error {
 | 
					func (d *mongoAppImpl) Save(ctx context.Context, m *entity.Mongo) error {
 | 
				
			||||||
	if m.Id == 0 {
 | 
						if m.Id == 0 {
 | 
				
			||||||
		return d.GetRepo().Insert(m)
 | 
							return d.GetRepo().Insert(ctx, m)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 先关闭连接
 | 
						// 先关闭连接
 | 
				
			||||||
	mgm.CloseConn(m.Id)
 | 
						mgm.CloseConn(m.Id)
 | 
				
			||||||
	return d.GetRepo().UpdateById(m)
 | 
						return d.GetRepo().UpdateById(ctx, m)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (d *mongoAppImpl) GetMongoConn(id uint64) (*mgm.MongoConn, error) {
 | 
					func (d *mongoAppImpl) GetMongoConn(id uint64) (*mgm.MongoConn, error) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,7 @@ type Msg struct {
 | 
				
			|||||||
// 获取账号接收的消息列表
 | 
					// 获取账号接收的消息列表
 | 
				
			||||||
func (m *Msg) GetMsgs(rc *req.Ctx) {
 | 
					func (m *Msg) GetMsgs(rc *req.Ctx) {
 | 
				
			||||||
	condition := &entity.Msg{
 | 
						condition := &entity.Msg{
 | 
				
			||||||
		RecipientId: int64(rc.LoginAccount.Id),
 | 
							RecipientId: int64(rc.GetLoginAccount().Id),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	res, err := m.MsgApp.GetPageList(condition, ginx.GetPageParam(rc.GinCtx), new([]entity.Msg))
 | 
						res, err := m.MsgApp.GetPageList(condition, ginx.GetPageParam(rc.GinCtx), new([]entity.Msg))
 | 
				
			||||||
	biz.ErrIsNil(err)
 | 
						biz.ErrIsNil(err)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
package application
 | 
					package application
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
	"mayfly-go/internal/msg/application/dto"
 | 
						"mayfly-go/internal/msg/application/dto"
 | 
				
			||||||
	"mayfly-go/internal/msg/domain/entity"
 | 
						"mayfly-go/internal/msg/domain/entity"
 | 
				
			||||||
	"mayfly-go/internal/msg/domain/repository"
 | 
						"mayfly-go/internal/msg/domain/repository"
 | 
				
			||||||
@@ -12,7 +13,7 @@ import (
 | 
				
			|||||||
type Msg interface {
 | 
					type Msg interface {
 | 
				
			||||||
	GetPageList(condition *entity.Msg, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error)
 | 
						GetPageList(condition *entity.Msg, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Create(msg *entity.Msg)
 | 
						Create(ctx context.Context, msg *entity.Msg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 创建消息,并通过ws发送
 | 
						// 创建消息,并通过ws发送
 | 
				
			||||||
	CreateAndSend(la *model.LoginAccount, msg *dto.SysMsg)
 | 
						CreateAndSend(la *model.LoginAccount, msg *dto.SysMsg)
 | 
				
			||||||
@@ -32,13 +33,13 @@ func (a *msgAppImpl) GetPageList(condition *entity.Msg, pageParam *model.PagePar
 | 
				
			|||||||
	return a.msgRepo.GetPageList(condition, pageParam, toEntity)
 | 
						return a.msgRepo.GetPageList(condition, pageParam, toEntity)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (a *msgAppImpl) Create(msg *entity.Msg) {
 | 
					func (a *msgAppImpl) Create(ctx context.Context, msg *entity.Msg) {
 | 
				
			||||||
	a.msgRepo.Insert(msg)
 | 
						a.msgRepo.Insert(ctx, msg)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (a *msgAppImpl) CreateAndSend(la *model.LoginAccount, wmsg *dto.SysMsg) {
 | 
					func (a *msgAppImpl) CreateAndSend(la *model.LoginAccount, wmsg *dto.SysMsg) {
 | 
				
			||||||
	now := time.Now()
 | 
						now := time.Now()
 | 
				
			||||||
	msg := &entity.Msg{Type: 2, Msg: wmsg.Msg, RecipientId: int64(la.Id), CreateTime: &now, CreatorId: la.Id, Creator: la.Username}
 | 
						msg := &entity.Msg{Type: 2, Msg: wmsg.Msg, RecipientId: int64(la.Id), CreateTime: &now, CreatorId: la.Id, Creator: la.Username}
 | 
				
			||||||
	a.msgRepo.Insert(msg)
 | 
						a.msgRepo.Insert(context.TODO(), msg)
 | 
				
			||||||
	ws.SendJsonMsg(ws.UserId(la.Id), wmsg.ClientId, wmsg)
 | 
						ws.SendJsonMsg(ws.UserId(la.Id), wmsg.ClientId, wmsg)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,7 +31,7 @@ func (r *Redis) RedisList(rc *req.Ctx) {
 | 
				
			|||||||
	queryCond, page := ginx.BindQueryAndPage[*entity.RedisQuery](rc.GinCtx, new(entity.RedisQuery))
 | 
						queryCond, page := ginx.BindQueryAndPage[*entity.RedisQuery](rc.GinCtx, new(entity.RedisQuery))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 不存在可访问标签id,即没有可操作数据
 | 
						// 不存在可访问标签id,即没有可操作数据
 | 
				
			||||||
	tagIds := r.TagApp.ListTagIdByAccountId(rc.LoginAccount.Id)
 | 
						tagIds := r.TagApp.ListTagIdByAccountId(rc.GetLoginAccount().Id)
 | 
				
			||||||
	if len(tagIds) == 0 {
 | 
						if len(tagIds) == 0 {
 | 
				
			||||||
		rc.ResData = model.EmptyPageResult[any]()
 | 
							rc.ResData = model.EmptyPageResult[any]()
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
@@ -44,7 +44,7 @@ func (r *Redis) RedisList(rc *req.Ctx) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r *Redis) RedisTags(rc *req.Ctx) {
 | 
					func (r *Redis) RedisTags(rc *req.Ctx) {
 | 
				
			||||||
	rc.ResData = r.TagApp.ListTagByAccountIdAndResource(rc.LoginAccount.Id, new(entity.Redis))
 | 
						rc.ResData = r.TagApp.ListTagByAccountIdAndResource(rc.GetLoginAccount().Id, new(entity.Redis))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r *Redis) Save(rc *req.Ctx) {
 | 
					func (r *Redis) Save(rc *req.Ctx) {
 | 
				
			||||||
@@ -60,8 +60,7 @@ func (r *Redis) Save(rc *req.Ctx) {
 | 
				
			|||||||
	form.Password = "****"
 | 
						form.Password = "****"
 | 
				
			||||||
	rc.ReqParam = form
 | 
						rc.ReqParam = form
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	redis.SetBaseInfo(rc.LoginAccount)
 | 
						biz.ErrIsNil(r.RedisApp.Save(rc.MetaCtx, redis))
 | 
				
			||||||
	biz.ErrIsNil(r.RedisApp.Save(redis))
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 获取redis实例密码,由于数据库是加密存储,故提供该接口展示原文密码
 | 
					// 获取redis实例密码,由于数据库是加密存储,故提供该接口展示原文密码
 | 
				
			||||||
@@ -81,7 +80,7 @@ func (r *Redis) DeleteRedis(rc *req.Ctx) {
 | 
				
			|||||||
	for _, v := range ids {
 | 
						for _, v := range ids {
 | 
				
			||||||
		value, err := strconv.Atoi(v)
 | 
							value, err := strconv.Atoi(v)
 | 
				
			||||||
		biz.ErrIsNilAppendErr(err, "string类型转换为int异常: %s")
 | 
							biz.ErrIsNilAppendErr(err, "string类型转换为int异常: %s")
 | 
				
			||||||
		r.RedisApp.Delete(uint64(value))
 | 
							r.RedisApp.Delete(rc.MetaCtx, uint64(value))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -218,7 +217,7 @@ func (r *Redis) checkKeyAndGetRedisConn(rc *req.Ctx) (*rdm.RedisConn, string) {
 | 
				
			|||||||
func (r *Redis) getRedisConn(rc *req.Ctx) *rdm.RedisConn {
 | 
					func (r *Redis) getRedisConn(rc *req.Ctx) *rdm.RedisConn {
 | 
				
			||||||
	ri, err := r.RedisApp.GetRedisConn(getIdAndDbNum(rc.GinCtx))
 | 
						ri, err := r.RedisApp.GetRedisConn(getIdAndDbNum(rc.GinCtx))
 | 
				
			||||||
	biz.ErrIsNil(err)
 | 
						biz.ErrIsNil(err)
 | 
				
			||||||
	biz.ErrIsNilAppendErr(r.TagApp.CanAccess(rc.LoginAccount.Id, ri.Info.TagPath), "%s")
 | 
						biz.ErrIsNilAppendErr(r.TagApp.CanAccess(rc.GetLoginAccount().Id, ri.Info.TagPath), "%s")
 | 
				
			||||||
	return ri
 | 
						return ri
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
package application
 | 
					package application
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
	"mayfly-go/internal/redis/domain/entity"
 | 
						"mayfly-go/internal/redis/domain/entity"
 | 
				
			||||||
	"mayfly-go/internal/redis/domain/repository"
 | 
						"mayfly-go/internal/redis/domain/repository"
 | 
				
			||||||
	"mayfly-go/internal/redis/rdm"
 | 
						"mayfly-go/internal/redis/rdm"
 | 
				
			||||||
@@ -19,10 +20,10 @@ type Redis interface {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	Count(condition *entity.RedisQuery) int64
 | 
						Count(condition *entity.RedisQuery) int64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Save(re *entity.Redis) error
 | 
						Save(ctx context.Context, re *entity.Redis) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 删除数据库信息
 | 
						// 删除数据库信息
 | 
				
			||||||
	Delete(id uint64) error
 | 
						Delete(ctx context.Context, id uint64) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 获取数据库连接实例
 | 
						// 获取数据库连接实例
 | 
				
			||||||
	// id: 数据库实例id
 | 
						// id: 数据库实例id
 | 
				
			||||||
@@ -52,7 +53,7 @@ func (r *redisAppImpl) Count(condition *entity.RedisQuery) int64 {
 | 
				
			|||||||
	return r.GetRepo().Count(condition)
 | 
						return r.GetRepo().Count(condition)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r *redisAppImpl) Save(re *entity.Redis) error {
 | 
					func (r *redisAppImpl) Save(ctx context.Context, re *entity.Redis) error {
 | 
				
			||||||
	// ’修改信息且密码不为空‘ or ‘新增’需要测试是否可连接
 | 
						// ’修改信息且密码不为空‘ or ‘新增’需要测试是否可连接
 | 
				
			||||||
	if (re.Id != 0 && re.Password != "") || re.Id == 0 {
 | 
						if (re.Id != 0 && re.Password != "") || re.Id == 0 {
 | 
				
			||||||
		if err := r.TestConn(re); err != nil {
 | 
							if err := r.TestConn(re); err != nil {
 | 
				
			||||||
@@ -72,7 +73,7 @@ func (r *redisAppImpl) Save(re *entity.Redis) error {
 | 
				
			|||||||
			return errorx.NewBiz("该实例已存在")
 | 
								return errorx.NewBiz("该实例已存在")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		re.PwdEncrypt()
 | 
							re.PwdEncrypt()
 | 
				
			||||||
		return r.Insert(re)
 | 
							return r.Insert(ctx, re)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 如果存在该库,则校验修改的库是否为该库
 | 
						// 如果存在该库,则校验修改的库是否为该库
 | 
				
			||||||
@@ -87,11 +88,11 @@ func (r *redisAppImpl) Save(re *entity.Redis) error {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	re.PwdEncrypt()
 | 
						re.PwdEncrypt()
 | 
				
			||||||
	return r.UpdateById(re)
 | 
						return r.UpdateById(ctx, re)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 删除Redis信息
 | 
					// 删除Redis信息
 | 
				
			||||||
func (r *redisAppImpl) Delete(id uint64) error {
 | 
					func (r *redisAppImpl) Delete(ctx context.Context, id uint64) error {
 | 
				
			||||||
	re, err := r.GetById(new(entity.Redis), id)
 | 
						re, err := r.GetById(new(entity.Redis), id)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return errorx.NewBiz("该redis信息不存在")
 | 
							return errorx.NewBiz("该redis信息不存在")
 | 
				
			||||||
@@ -101,7 +102,7 @@ func (r *redisAppImpl) Delete(id uint64) error {
 | 
				
			|||||||
		db, _ := strconv.Atoi(dbStr)
 | 
							db, _ := strconv.Atoi(dbStr)
 | 
				
			||||||
		rdm.CloseConn(re.Id, db)
 | 
							rdm.CloseConn(re.Id, db)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return r.DeleteById(id)
 | 
						return r.DeleteById(ctx, id)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 获取数据库连接实例
 | 
					// 获取数据库连接实例
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,7 +35,7 @@ type Account struct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// 获取当前登录用户的菜单与权限码
 | 
					// 获取当前登录用户的菜单与权限码
 | 
				
			||||||
func (a *Account) GetPermissions(rc *req.Ctx) {
 | 
					func (a *Account) GetPermissions(rc *req.Ctx) {
 | 
				
			||||||
	account := rc.LoginAccount
 | 
						account := rc.GetLoginAccount()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var resources vo.AccountResourceVOList
 | 
						var resources vo.AccountResourceVOList
 | 
				
			||||||
	// 获取账号菜单资源
 | 
						// 获取账号菜单资源
 | 
				
			||||||
@@ -78,15 +78,13 @@ func (a *Account) ChangePassword(rc *req.Ctx) {
 | 
				
			|||||||
	updateAccount := new(entity.Account)
 | 
						updateAccount := new(entity.Account)
 | 
				
			||||||
	updateAccount.Id = account.Id
 | 
						updateAccount.Id = account.Id
 | 
				
			||||||
	updateAccount.Password = cryptox.PwdHash(originNewPwd)
 | 
						updateAccount.Password = cryptox.PwdHash(originNewPwd)
 | 
				
			||||||
	biz.ErrIsNil(a.AccountApp.Update(updateAccount), "更新账号密码失败")
 | 
						biz.ErrIsNil(a.AccountApp.Update(rc.MetaCtx, updateAccount), "更新账号密码失败")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 赋值loginAccount 主要用于记录操作日志,因为操作日志保存请求上下文没有该信息不保存日志
 | 
						// 赋值loginAccount 主要用于记录操作日志,因为操作日志保存请求上下文没有该信息不保存日志
 | 
				
			||||||
	if rc.LoginAccount == nil {
 | 
						contextx.WithLoginAccount(rc.MetaCtx, &model.LoginAccount{
 | 
				
			||||||
		rc.LoginAccount = &model.LoginAccount{
 | 
							Id:       account.Id,
 | 
				
			||||||
			Id:       account.Id,
 | 
							Username: account.Username,
 | 
				
			||||||
			Username: account.Username,
 | 
						})
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 获取个人账号信息
 | 
					// 获取个人账号信息
 | 
				
			||||||
@@ -94,7 +92,7 @@ func (a *Account) AccountInfo(rc *req.Ctx) {
 | 
				
			|||||||
	ap := new(vo.AccountPersonVO)
 | 
						ap := new(vo.AccountPersonVO)
 | 
				
			||||||
	// 角色信息
 | 
						// 角色信息
 | 
				
			||||||
	roles := new([]vo.AccountRoleVO)
 | 
						roles := new([]vo.AccountRoleVO)
 | 
				
			||||||
	a.RoleApp.GetAccountRoles(rc.LoginAccount.Id, roles)
 | 
						a.RoleApp.GetAccountRoles(rc.GetLoginAccount().Id, roles)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ap.Roles = *roles
 | 
						ap.Roles = *roles
 | 
				
			||||||
	rc.ResData = ap
 | 
						rc.ResData = ap
 | 
				
			||||||
@@ -104,7 +102,7 @@ func (a *Account) AccountInfo(rc *req.Ctx) {
 | 
				
			|||||||
func (a *Account) UpdateAccount(rc *req.Ctx) {
 | 
					func (a *Account) UpdateAccount(rc *req.Ctx) {
 | 
				
			||||||
	updateAccount := ginx.BindJsonAndCopyTo[*entity.Account](rc.GinCtx, new(form.AccountUpdateForm), new(entity.Account))
 | 
						updateAccount := ginx.BindJsonAndCopyTo[*entity.Account](rc.GinCtx, new(form.AccountUpdateForm), new(entity.Account))
 | 
				
			||||||
	// 账号id为登录者账号
 | 
						// 账号id为登录者账号
 | 
				
			||||||
	updateAccount.Id = rc.LoginAccount.Id
 | 
						updateAccount.Id = rc.GetLoginAccount().Id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if updateAccount.Password != "" {
 | 
						if updateAccount.Password != "" {
 | 
				
			||||||
		biz.IsTrue(utils.CheckAccountPasswordLever(updateAccount.Password), "密码强度必须8位以上且包含字⺟⼤⼩写+数字+特殊符号")
 | 
							biz.IsTrue(utils.CheckAccountPasswordLever(updateAccount.Password), "密码强度必须8位以上且包含字⺟⼤⼩写+数字+特殊符号")
 | 
				
			||||||
@@ -118,7 +116,7 @@ func (a *Account) UpdateAccount(rc *req.Ctx) {
 | 
				
			|||||||
		// 禁止更新用户名,防止误传被更新
 | 
							// 禁止更新用户名,防止误传被更新
 | 
				
			||||||
		updateAccount.Username = ""
 | 
							updateAccount.Username = ""
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	biz.ErrIsNil(a.AccountApp.Update(updateAccount))
 | 
						biz.ErrIsNil(a.AccountApp.Update(rc.MetaCtx, updateAccount))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**    后台账号操作    **/
 | 
					/**    后台账号操作    **/
 | 
				
			||||||
@@ -139,10 +137,9 @@ func (a *Account) SaveAccount(rc *req.Ctx) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	form.Password = "*****"
 | 
						form.Password = "*****"
 | 
				
			||||||
	rc.ReqParam = form
 | 
						rc.ReqParam = form
 | 
				
			||||||
	account.SetBaseInfo(rc.LoginAccount)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if account.Id == 0 {
 | 
						if account.Id == 0 {
 | 
				
			||||||
		biz.ErrIsNil(a.AccountApp.Create(account))
 | 
							biz.ErrIsNil(a.AccountApp.Create(rc.MetaCtx, account))
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		if account.Password != "" {
 | 
							if account.Password != "" {
 | 
				
			||||||
			biz.IsTrue(utils.CheckAccountPasswordLever(account.Password), "密码强度必须8位以上且包含字⺟⼤⼩写+数字+特殊符号")
 | 
								biz.IsTrue(utils.CheckAccountPasswordLever(account.Password), "密码强度必须8位以上且包含字⺟⼤⼩写+数字+特殊符号")
 | 
				
			||||||
@@ -150,7 +147,7 @@ func (a *Account) SaveAccount(rc *req.Ctx) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		// 更新操作不允许修改用户名、防止误传更新
 | 
							// 更新操作不允许修改用户名、防止误传更新
 | 
				
			||||||
		account.Username = ""
 | 
							account.Username = ""
 | 
				
			||||||
		biz.ErrIsNil(a.AccountApp.Update(account))
 | 
							biz.ErrIsNil(a.AccountApp.Update(rc.MetaCtx, account))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -161,7 +158,7 @@ func (a *Account) ChangeStatus(rc *req.Ctx) {
 | 
				
			|||||||
	account.Id = uint64(ginx.PathParamInt(g, "id"))
 | 
						account.Id = uint64(ginx.PathParamInt(g, "id"))
 | 
				
			||||||
	account.Status = int8(ginx.PathParamInt(g, "status"))
 | 
						account.Status = int8(ginx.PathParamInt(g, "status"))
 | 
				
			||||||
	rc.ReqParam = collx.Kvs("accountId", account.Id, "status", account.Status)
 | 
						rc.ReqParam = collx.Kvs("accountId", account.Id, "status", account.Status)
 | 
				
			||||||
	biz.ErrIsNil(a.AccountApp.Update(account))
 | 
						biz.ErrIsNil(a.AccountApp.Update(rc.MetaCtx, account))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (a *Account) DeleteAccount(rc *req.Ctx) {
 | 
					func (a *Account) DeleteAccount(rc *req.Ctx) {
 | 
				
			||||||
@@ -172,7 +169,7 @@ func (a *Account) DeleteAccount(rc *req.Ctx) {
 | 
				
			|||||||
	for _, v := range ids {
 | 
						for _, v := range ids {
 | 
				
			||||||
		value, err := strconv.Atoi(v)
 | 
							value, err := strconv.Atoi(v)
 | 
				
			||||||
		biz.ErrIsNilAppendErr(err, "string类型转换为int异常: %s")
 | 
							biz.ErrIsNilAppendErr(err, "string类型转换为int异常: %s")
 | 
				
			||||||
		biz.ErrIsNilAppendErr(a.AccountApp.Delete(uint64(value)), "删除失败:%s")
 | 
							biz.ErrIsNilAppendErr(a.AccountApp.Delete(rc.MetaCtx, uint64(value)), "删除失败:%s")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -207,7 +204,7 @@ func (a *Account) SaveRoles(rc *req.Ctx) {
 | 
				
			|||||||
		return uint64(id)
 | 
							return uint64(id)
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	a.RoleApp.SaveAccountRole(contextx.NewLoginAccount(rc.LoginAccount), form.Id, newIds)
 | 
						a.RoleApp.SaveAccountRole(rc.MetaCtx, form.Id, newIds)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 重置otp秘钥
 | 
					// 重置otp秘钥
 | 
				
			||||||
@@ -216,5 +213,5 @@ func (a *Account) ResetOtpSecret(rc *req.Ctx) {
 | 
				
			|||||||
	accountId := uint64(ginx.PathParamInt(rc.GinCtx, "id"))
 | 
						accountId := uint64(ginx.PathParamInt(rc.GinCtx, "id"))
 | 
				
			||||||
	account.Id = accountId
 | 
						account.Id = accountId
 | 
				
			||||||
	rc.ReqParam = collx.Kvs("accountId", accountId)
 | 
						rc.ReqParam = collx.Kvs("accountId", accountId)
 | 
				
			||||||
	biz.ErrIsNil(a.AccountApp.Update(account))
 | 
						biz.ErrIsNil(a.AccountApp.Update(rc.MetaCtx, account))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,7 +16,7 @@ type Config struct {
 | 
				
			|||||||
func (c *Config) Configs(rc *req.Ctx) {
 | 
					func (c *Config) Configs(rc *req.Ctx) {
 | 
				
			||||||
	g := rc.GinCtx
 | 
						g := rc.GinCtx
 | 
				
			||||||
	condition := &entity.Config{Key: g.Query("key")}
 | 
						condition := &entity.Config{Key: g.Query("key")}
 | 
				
			||||||
	condition.Permission = rc.LoginAccount.Username
 | 
						condition.Permission = rc.GetLoginAccount().Username
 | 
				
			||||||
	res, err := c.ConfigApp.GetPageList(condition, ginx.GetPageParam(g), new([]entity.Config))
 | 
						res, err := c.ConfigApp.GetPageList(condition, ginx.GetPageParam(g), new([]entity.Config))
 | 
				
			||||||
	biz.ErrIsNil(err)
 | 
						biz.ErrIsNil(err)
 | 
				
			||||||
	rc.ResData = res
 | 
						rc.ResData = res
 | 
				
			||||||
@@ -40,6 +40,5 @@ func (c *Config) SaveConfig(rc *req.Ctx) {
 | 
				
			|||||||
	form := &form.ConfigForm{}
 | 
						form := &form.ConfigForm{}
 | 
				
			||||||
	config := ginx.BindJsonAndCopyTo(rc.GinCtx, form, new(entity.Config))
 | 
						config := ginx.BindJsonAndCopyTo(rc.GinCtx, form, new(entity.Config))
 | 
				
			||||||
	rc.ReqParam = form
 | 
						rc.ReqParam = form
 | 
				
			||||||
	config.SetBaseInfo(rc.LoginAccount)
 | 
						biz.ErrIsNil(c.ConfigApp.Save(rc.MetaCtx, config))
 | 
				
			||||||
	biz.ErrIsNil(c.ConfigApp.Save(config))
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,19 +39,18 @@ func (r *Resource) SaveResource(rc *req.Ctx) {
 | 
				
			|||||||
	bytes, _ := json.Marshal(form.Meta)
 | 
						bytes, _ := json.Marshal(form.Meta)
 | 
				
			||||||
	entity.Meta = string(bytes)
 | 
						entity.Meta = string(bytes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	entity.SetBaseInfo(rc.LoginAccount)
 | 
						biz.ErrIsNil(r.ResourceApp.Save(rc.MetaCtx, entity))
 | 
				
			||||||
	biz.ErrIsNil(r.ResourceApp.Save(entity))
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r *Resource) DelResource(rc *req.Ctx) {
 | 
					func (r *Resource) DelResource(rc *req.Ctx) {
 | 
				
			||||||
	biz.ErrIsNil(r.ResourceApp.Delete(uint64(ginx.PathParamInt(rc.GinCtx, "id"))))
 | 
						biz.ErrIsNil(r.ResourceApp.Delete(rc.MetaCtx, uint64(ginx.PathParamInt(rc.GinCtx, "id"))))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r *Resource) ChangeStatus(rc *req.Ctx) {
 | 
					func (r *Resource) ChangeStatus(rc *req.Ctx) {
 | 
				
			||||||
	rid := uint64(ginx.PathParamInt(rc.GinCtx, "id"))
 | 
						rid := uint64(ginx.PathParamInt(rc.GinCtx, "id"))
 | 
				
			||||||
	status := int8(ginx.PathParamInt(rc.GinCtx, "status"))
 | 
						status := int8(ginx.PathParamInt(rc.GinCtx, "status"))
 | 
				
			||||||
	rc.ReqParam = collx.Kvs("id", rid, "status", status)
 | 
						rc.ReqParam = collx.Kvs("id", rid, "status", status)
 | 
				
			||||||
	biz.ErrIsNil(r.ResourceApp.ChangeStatus(rid, status))
 | 
						biz.ErrIsNil(r.ResourceApp.ChangeStatus(rc.MetaCtx, rid, status))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r *Resource) Sort(rc *req.Ctx) {
 | 
					func (r *Resource) Sort(rc *req.Ctx) {
 | 
				
			||||||
@@ -62,6 +61,6 @@ func (r *Resource) Sort(rc *req.Ctx) {
 | 
				
			|||||||
	for _, v := range rs {
 | 
						for _, v := range rs {
 | 
				
			||||||
		sortE := &entity.Resource{Pid: v.Pid, Weight: v.Weight}
 | 
							sortE := &entity.Resource{Pid: v.Pid, Weight: v.Weight}
 | 
				
			||||||
		sortE.Id = uint64(v.Id)
 | 
							sortE.Id = uint64(v.Id)
 | 
				
			||||||
		r.ResourceApp.Sort(sortE)
 | 
							r.ResourceApp.Sort(rc.MetaCtx, sortE)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,7 +6,6 @@ import (
 | 
				
			|||||||
	"mayfly-go/internal/sys/application"
 | 
						"mayfly-go/internal/sys/application"
 | 
				
			||||||
	"mayfly-go/internal/sys/domain/entity"
 | 
						"mayfly-go/internal/sys/domain/entity"
 | 
				
			||||||
	"mayfly-go/pkg/biz"
 | 
						"mayfly-go/pkg/biz"
 | 
				
			||||||
	"mayfly-go/pkg/contextx"
 | 
					 | 
				
			||||||
	"mayfly-go/pkg/ginx"
 | 
						"mayfly-go/pkg/ginx"
 | 
				
			||||||
	"mayfly-go/pkg/req"
 | 
						"mayfly-go/pkg/req"
 | 
				
			||||||
	"mayfly-go/pkg/utils/collx"
 | 
						"mayfly-go/pkg/utils/collx"
 | 
				
			||||||
@@ -32,9 +31,8 @@ func (r *Role) SaveRole(rc *req.Ctx) {
 | 
				
			|||||||
	form := &form.RoleForm{}
 | 
						form := &form.RoleForm{}
 | 
				
			||||||
	role := ginx.BindJsonAndCopyTo(rc.GinCtx, form, new(entity.Role))
 | 
						role := ginx.BindJsonAndCopyTo(rc.GinCtx, form, new(entity.Role))
 | 
				
			||||||
	rc.ReqParam = form
 | 
						rc.ReqParam = form
 | 
				
			||||||
	role.SetBaseInfo(rc.LoginAccount)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	r.RoleApp.SaveRole(role)
 | 
						r.RoleApp.SaveRole(rc.MetaCtx, role)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 删除角色及其资源关联关系
 | 
					// 删除角色及其资源关联关系
 | 
				
			||||||
@@ -46,7 +44,7 @@ func (r *Role) DelRole(rc *req.Ctx) {
 | 
				
			|||||||
	for _, v := range ids {
 | 
						for _, v := range ids {
 | 
				
			||||||
		value, err := strconv.Atoi(v)
 | 
							value, err := strconv.Atoi(v)
 | 
				
			||||||
		biz.ErrIsNilAppendErr(err, "string类型转换为int异常: %s")
 | 
							biz.ErrIsNilAppendErr(err, "string类型转换为int异常: %s")
 | 
				
			||||||
		r.RoleApp.DeleteRole(uint64(value))
 | 
							r.RoleApp.DeleteRole(rc.MetaCtx, uint64(value))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -77,5 +75,5 @@ func (r *Role) SaveResource(rc *req.Ctx) {
 | 
				
			|||||||
		return uint64(id)
 | 
							return uint64(id)
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	r.RoleApp.SaveRoleResource(contextx.NewLoginAccount(rc.LoginAccount), form.Id, newIds)
 | 
						r.RoleApp.SaveRoleResource(rc.MetaCtx, form.Id, newIds)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -38,8 +38,6 @@ func (s *System) ConnectWs(g *gin.Context) {
 | 
				
			|||||||
	biz.ErrIsNil(err, "sys websocket没有权限连接")
 | 
						biz.ErrIsNil(err, "sys websocket没有权限连接")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 登录账号信息
 | 
						// 登录账号信息
 | 
				
			||||||
	la := rc.LoginAccount
 | 
						la := rc.GetLoginAccount()
 | 
				
			||||||
	if la != nil {
 | 
						ws.AddClient(ws.UserId(la.Id), clientId, wsConn)
 | 
				
			||||||
		ws.AddClient(ws.UserId(la.Id), clientId, wsConn)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
package application
 | 
					package application
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
	"mayfly-go/internal/sys/domain/entity"
 | 
						"mayfly-go/internal/sys/domain/entity"
 | 
				
			||||||
	"mayfly-go/internal/sys/domain/repository"
 | 
						"mayfly-go/internal/sys/domain/repository"
 | 
				
			||||||
	"mayfly-go/pkg/base"
 | 
						"mayfly-go/pkg/base"
 | 
				
			||||||
@@ -17,11 +18,11 @@ type Account interface {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	GetPageList(condition *entity.Account, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error)
 | 
						GetPageList(condition *entity.Account, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Create(account *entity.Account) error
 | 
						Create(ctx context.Context, account *entity.Account) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Update(account *entity.Account) error
 | 
						Update(ctx context.Context, account *entity.Account) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Delete(id uint64) error
 | 
						Delete(ctx context.Context, id uint64) error
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func newAccountApp(accountRepo repository.Account) Account {
 | 
					func newAccountApp(accountRepo repository.Account) Account {
 | 
				
			||||||
@@ -36,17 +37,17 @@ func (a *accountAppImpl) GetPageList(condition *entity.Account, pageParam *model
 | 
				
			|||||||
	return a.GetRepo().GetPageList(condition, pageParam, toEntity)
 | 
						return a.GetRepo().GetPageList(condition, pageParam, toEntity)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (a *accountAppImpl) Create(account *entity.Account) error {
 | 
					func (a *accountAppImpl) Create(ctx context.Context, account *entity.Account) error {
 | 
				
			||||||
	if a.GetBy(&entity.Account{Username: account.Username}) == nil {
 | 
						if a.GetBy(&entity.Account{Username: account.Username}) == nil {
 | 
				
			||||||
		return errorx.NewBiz("该账号用户名已存在")
 | 
							return errorx.NewBiz("该账号用户名已存在")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// 默认密码为账号用户名
 | 
						// 默认密码为账号用户名
 | 
				
			||||||
	account.Password = cryptox.PwdHash(account.Username)
 | 
						account.Password = cryptox.PwdHash(account.Username)
 | 
				
			||||||
	account.Status = entity.AccountEnableStatus
 | 
						account.Status = entity.AccountEnableStatus
 | 
				
			||||||
	return a.Insert(account)
 | 
						return a.Insert(ctx, account)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (a *accountAppImpl) Update(account *entity.Account) error {
 | 
					func (a *accountAppImpl) Update(ctx context.Context, account *entity.Account) error {
 | 
				
			||||||
	if account.Username != "" {
 | 
						if account.Username != "" {
 | 
				
			||||||
		unAcc := &entity.Account{Username: account.Username}
 | 
							unAcc := &entity.Account{Username: account.Username}
 | 
				
			||||||
		err := a.GetBy(unAcc)
 | 
							err := a.GetBy(unAcc)
 | 
				
			||||||
@@ -55,14 +56,14 @@ func (a *accountAppImpl) Update(account *entity.Account) error {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return a.UpdateById(account)
 | 
						return a.UpdateById(ctx, account)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (a *accountAppImpl) Delete(id uint64) error {
 | 
					func (a *accountAppImpl) Delete(ctx context.Context, id uint64) error {
 | 
				
			||||||
	return gormx.Tx(
 | 
						return gormx.Tx(
 | 
				
			||||||
		func(db *gorm.DB) error {
 | 
							func(db *gorm.DB) error {
 | 
				
			||||||
			// 删除account信息
 | 
								// 删除account信息
 | 
				
			||||||
			return a.DeleteByIdWithDb(db, id)
 | 
								return a.DeleteByIdWithDb(ctx, db, id)
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		func(db *gorm.DB) error {
 | 
							func(db *gorm.DB) error {
 | 
				
			||||||
			// 删除账号关联的角色信息
 | 
								// 删除账号关联的角色信息
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
package application
 | 
					package application
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
	"encoding/json"
 | 
						"encoding/json"
 | 
				
			||||||
	"mayfly-go/internal/sys/domain/entity"
 | 
						"mayfly-go/internal/sys/domain/entity"
 | 
				
			||||||
	"mayfly-go/internal/sys/domain/repository"
 | 
						"mayfly-go/internal/sys/domain/repository"
 | 
				
			||||||
@@ -20,7 +21,7 @@ type Config interface {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	GetPageList(condition *entity.Config, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error)
 | 
						GetPageList(condition *entity.Config, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Save(config *entity.Config) error
 | 
						Save(ctx context.Context, config *entity.Config) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// GetConfig 获取指定key的配置信息, 不会返回nil, 若不存在则值都默认值即空字符串
 | 
						// GetConfig 获取指定key的配置信息, 不会返回nil, 若不存在则值都默认值即空字符串
 | 
				
			||||||
	GetConfig(key string) *entity.Config
 | 
						GetConfig(key string) *entity.Config
 | 
				
			||||||
@@ -41,9 +42,9 @@ func (a *configAppImpl) GetPageList(condition *entity.Config, pageParam *model.P
 | 
				
			|||||||
	return a.GetRepo().GetPageList(condition, pageParam, toEntity)
 | 
						return a.GetRepo().GetPageList(condition, pageParam, toEntity)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (a *configAppImpl) Save(config *entity.Config) error {
 | 
					func (a *configAppImpl) Save(ctx context.Context, config *entity.Config) error {
 | 
				
			||||||
	if config.Id == 0 {
 | 
						if config.Id == 0 {
 | 
				
			||||||
		if err := a.Insert(config); err != nil {
 | 
							if err := a.Insert(ctx, config); err != nil {
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
@@ -52,7 +53,7 @@ func (a *configAppImpl) Save(config *entity.Config) error {
 | 
				
			|||||||
			return errorx.NewBiz("您无权修改该配置")
 | 
								return errorx.NewBiz("您无权修改该配置")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if err := a.UpdateById(config); err != nil {
 | 
							if err := a.UpdateById(ctx, config); err != nil {
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
package application
 | 
					package application
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
	"mayfly-go/internal/common/consts"
 | 
						"mayfly-go/internal/common/consts"
 | 
				
			||||||
	"mayfly-go/internal/sys/domain/entity"
 | 
						"mayfly-go/internal/sys/domain/entity"
 | 
				
			||||||
	"mayfly-go/internal/sys/domain/repository"
 | 
						"mayfly-go/internal/sys/domain/repository"
 | 
				
			||||||
@@ -15,13 +16,13 @@ import (
 | 
				
			|||||||
type Resource interface {
 | 
					type Resource interface {
 | 
				
			||||||
	base.App[*entity.Resource]
 | 
						base.App[*entity.Resource]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Save(entity *entity.Resource) error
 | 
						Save(ctx context.Context, entity *entity.Resource) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Delete(id uint64) error
 | 
						Delete(ctx context.Context, id uint64) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ChangeStatus(resourceId uint64, status int8) error
 | 
						ChangeStatus(ctx context.Context, resourceId uint64, status int8) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Sort(re *entity.Resource) error
 | 
						Sort(ctx context.Context, re *entity.Resource) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	GetAccountResources(accountId uint64, toEntity any) error
 | 
						GetAccountResources(accountId uint64, toEntity any) error
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -36,7 +37,7 @@ type resourceAppImpl struct {
 | 
				
			|||||||
	base.AppImpl[*entity.Resource, repository.Resource]
 | 
						base.AppImpl[*entity.Resource, repository.Resource]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r *resourceAppImpl) Save(resource *entity.Resource) error {
 | 
					func (r *resourceAppImpl) Save(ctx context.Context, resource *entity.Resource) error {
 | 
				
			||||||
	// 更新操作
 | 
						// 更新操作
 | 
				
			||||||
	if resource.Id != 0 {
 | 
						if resource.Id != 0 {
 | 
				
			||||||
		if resource.Code != "" {
 | 
							if resource.Code != "" {
 | 
				
			||||||
@@ -51,7 +52,7 @@ func (r *resourceAppImpl) Save(resource *entity.Resource) error {
 | 
				
			|||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return gormx.UpdateById(resource)
 | 
							return r.UpdateById(ctx, resource)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 生成随机八位唯一标识符
 | 
						// 生成随机八位唯一标识符
 | 
				
			||||||
@@ -73,10 +74,10 @@ func (r *resourceAppImpl) Save(resource *entity.Resource) error {
 | 
				
			|||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	resource.Weight = int(time.Now().Unix())
 | 
						resource.Weight = int(time.Now().Unix())
 | 
				
			||||||
	return gormx.Insert(resource)
 | 
						return r.Insert(ctx, resource)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r *resourceAppImpl) ChangeStatus(resourceId uint64, status int8) error {
 | 
					func (r *resourceAppImpl) ChangeStatus(ctx context.Context, resourceId uint64, status int8) error {
 | 
				
			||||||
	resource, err := r.GetById(new(entity.Resource), resourceId)
 | 
						resource, err := r.GetById(new(entity.Resource), resourceId)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return errorx.NewBiz("资源不存在")
 | 
							return errorx.NewBiz("资源不存在")
 | 
				
			||||||
@@ -85,7 +86,7 @@ func (r *resourceAppImpl) ChangeStatus(resourceId uint64, status int8) error {
 | 
				
			|||||||
	return r.GetRepo().UpdateByUiPathLike(resource)
 | 
						return r.GetRepo().UpdateByUiPathLike(resource)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r *resourceAppImpl) Sort(sortResource *entity.Resource) error {
 | 
					func (r *resourceAppImpl) Sort(ctx context.Context, sortResource *entity.Resource) error {
 | 
				
			||||||
	resource, err := r.GetById(new(entity.Resource), sortResource.Id)
 | 
						resource, err := r.GetById(new(entity.Resource), sortResource.Id)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return errorx.NewBiz("资源不存在")
 | 
							return errorx.NewBiz("资源不存在")
 | 
				
			||||||
@@ -95,7 +96,7 @@ func (r *resourceAppImpl) Sort(sortResource *entity.Resource) error {
 | 
				
			|||||||
	if sortResource.Pid == resource.Pid {
 | 
						if sortResource.Pid == resource.Pid {
 | 
				
			||||||
		saveE := &entity.Resource{Weight: sortResource.Weight}
 | 
							saveE := &entity.Resource{Weight: sortResource.Weight}
 | 
				
			||||||
		saveE.Id = sortResource.Id
 | 
							saveE.Id = sortResource.Id
 | 
				
			||||||
		return r.Save(saveE)
 | 
							return r.Save(ctx, saveE)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 若资源原本唯一标识路径为:xxxx/yyyy/zzzz/,则获取其父节点路径标识 xxxx/yyyy/ 与自身节点标识 zzzz/
 | 
						// 若资源原本唯一标识路径为:xxxx/yyyy/zzzz/,则获取其父节点路径标识 xxxx/yyyy/ 与自身节点标识 zzzz/
 | 
				
			||||||
@@ -131,7 +132,7 @@ func (r *resourceAppImpl) Sort(sortResource *entity.Resource) error {
 | 
				
			|||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			updateUiPath.UiPath = strings.ReplaceAll(v.UiPath, parentResourceUiPath, newParentResourceUiPath)
 | 
								updateUiPath.UiPath = strings.ReplaceAll(v.UiPath, parentResourceUiPath, newParentResourceUiPath)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		r.Save(updateUiPath)
 | 
							r.Save(ctx, updateUiPath)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 更新零值使用map,因为pid=0表示根节点
 | 
						// 更新零值使用map,因为pid=0表示根节点
 | 
				
			||||||
@@ -155,7 +156,7 @@ func (r *resourceAppImpl) checkCode(code string) error {
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r *resourceAppImpl) Delete(id uint64) error {
 | 
					func (r *resourceAppImpl) Delete(ctx context.Context, id uint64) error {
 | 
				
			||||||
	resource, err := r.GetById(new(entity.Resource), id)
 | 
						resource, err := r.GetById(new(entity.Resource), id)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return errorx.NewBiz("资源不存在")
 | 
							return errorx.NewBiz("资源不存在")
 | 
				
			||||||
@@ -164,7 +165,7 @@ func (r *resourceAppImpl) Delete(id uint64) error {
 | 
				
			|||||||
	// 删除当前节点及其所有子节点
 | 
						// 删除当前节点及其所有子节点
 | 
				
			||||||
	children := r.GetRepo().GetChildren(resource.UiPath)
 | 
						children := r.GetRepo().GetChildren(resource.UiPath)
 | 
				
			||||||
	for _, v := range children {
 | 
						for _, v := range children {
 | 
				
			||||||
		r.GetRepo().DeleteById(v.Id)
 | 
							r.GetRepo().DeleteById(ctx, v.Id)
 | 
				
			||||||
		// 删除角色关联的资源信息
 | 
							// 删除角色关联的资源信息
 | 
				
			||||||
		gormx.DeleteBy(&entity.RoleResource{ResourceId: v.Id})
 | 
							gormx.DeleteBy(&entity.RoleResource{ResourceId: v.Id})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,9 +17,9 @@ import (
 | 
				
			|||||||
type Role interface {
 | 
					type Role interface {
 | 
				
			||||||
	GetPageList(condition *entity.Role, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error)
 | 
						GetPageList(condition *entity.Role, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	SaveRole(role *entity.Role) error
 | 
						SaveRole(ctx context.Context, role *entity.Role) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	DeleteRole(id uint64) error
 | 
						DeleteRole(ctx context.Context, id uint64) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	GetRoleResourceIds(roleId uint64) []uint64
 | 
						GetRoleResourceIds(roleId uint64) []uint64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -29,7 +29,7 @@ type Role interface {
 | 
				
			|||||||
	SaveRoleResource(ctx context.Context, roleId uint64, resourceIds []uint64)
 | 
						SaveRoleResource(ctx context.Context, roleId uint64, resourceIds []uint64)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 删除角色资源关联记录
 | 
						// 删除角色资源关联记录
 | 
				
			||||||
	DeleteRoleResource(roleId uint64, resourceId uint64)
 | 
						DeleteRoleResource(ctx context.Context, roleId uint64, resourceId uint64)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 获取账号角色id列表
 | 
						// 获取账号角色id列表
 | 
				
			||||||
	GetAccountRoleIds(accountId uint64) []uint64
 | 
						GetAccountRoleIds(accountId uint64) []uint64
 | 
				
			||||||
@@ -37,7 +37,7 @@ type Role interface {
 | 
				
			|||||||
	// 保存账号角色关联信息
 | 
						// 保存账号角色关联信息
 | 
				
			||||||
	SaveAccountRole(ctx context.Context, accountId uint64, roleIds []uint64)
 | 
						SaveAccountRole(ctx context.Context, accountId uint64, roleIds []uint64)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	DeleteAccountRole(accountId, roleId uint64)
 | 
						DeleteAccountRole(ctx context.Context, accountId, roleId uint64)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	GetAccountRoles(accountId uint64, toEntity any)
 | 
						GetAccountRoles(accountId uint64, toEntity any)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -56,7 +56,7 @@ func (m *roleAppImpl) GetPageList(condition *entity.Role, pageParam *model.PageP
 | 
				
			|||||||
	return m.roleRepo.GetPageList(condition, pageParam, toEntity, orderBy...)
 | 
						return m.roleRepo.GetPageList(condition, pageParam, toEntity, orderBy...)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *roleAppImpl) SaveRole(role *entity.Role) error {
 | 
					func (m *roleAppImpl) SaveRole(ctx context.Context, role *entity.Role) error {
 | 
				
			||||||
	role.Code = strings.ToUpper(role.Code)
 | 
						role.Code = strings.ToUpper(role.Code)
 | 
				
			||||||
	if role.Id != 0 {
 | 
						if role.Id != 0 {
 | 
				
			||||||
		// code不可更改,防止误传
 | 
							// code不可更改,防止误传
 | 
				
			||||||
@@ -68,11 +68,11 @@ func (m *roleAppImpl) SaveRole(role *entity.Role) error {
 | 
				
			|||||||
	return gormx.Insert(role)
 | 
						return gormx.Insert(role)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *roleAppImpl) DeleteRole(id uint64) error {
 | 
					func (m *roleAppImpl) DeleteRole(ctx context.Context, id uint64) error {
 | 
				
			||||||
	// 删除角色与资源的关联关系
 | 
						// 删除角色与资源的关联关系
 | 
				
			||||||
	return gormx.Tx(
 | 
						return gormx.Tx(
 | 
				
			||||||
		func(db *gorm.DB) error {
 | 
							func(db *gorm.DB) error {
 | 
				
			||||||
			return m.roleRepo.DeleteByIdWithDb(db, id)
 | 
								return m.roleRepo.DeleteByIdWithDb(ctx, db, id)
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		func(db *gorm.DB) error {
 | 
							func(db *gorm.DB) error {
 | 
				
			||||||
			return gormx.DeleteByWithDb(db, &entity.RoleResource{RoleId: id})
 | 
								return gormx.DeleteByWithDb(db, &entity.RoleResource{RoleId: id})
 | 
				
			||||||
@@ -110,11 +110,11 @@ func (m *roleAppImpl) SaveRoleResource(ctx context.Context, roleId uint64, resou
 | 
				
			|||||||
	m.roleRepo.SaveRoleResource(addVals)
 | 
						m.roleRepo.SaveRoleResource(addVals)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, v := range delIds {
 | 
						for _, v := range delIds {
 | 
				
			||||||
		m.DeleteRoleResource(roleId, v)
 | 
							m.DeleteRoleResource(ctx, roleId, v)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *roleAppImpl) DeleteRoleResource(roleId uint64, resourceId uint64) {
 | 
					func (m *roleAppImpl) DeleteRoleResource(ctx context.Context, roleId uint64, resourceId uint64) {
 | 
				
			||||||
	m.roleRepo.DeleteRoleResource(roleId, resourceId)
 | 
						m.roleRepo.DeleteRoleResource(roleId, resourceId)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -140,11 +140,11 @@ func (m *roleAppImpl) SaveAccountRole(ctx context.Context, accountId uint64, rol
 | 
				
			|||||||
		m.roleRepo.SaveAccountRole(rr)
 | 
							m.roleRepo.SaveAccountRole(rr)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for _, v := range delIds {
 | 
						for _, v := range delIds {
 | 
				
			||||||
		m.DeleteAccountRole(accountId, v)
 | 
							m.DeleteAccountRole(ctx, accountId, v)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *roleAppImpl) DeleteAccountRole(accountId, roleId uint64) {
 | 
					func (m *roleAppImpl) DeleteAccountRole(ctx context.Context, accountId, roleId uint64) {
 | 
				
			||||||
	m.roleRepo.DeleteAccountRole(accountId, roleId)
 | 
						m.roleRepo.DeleteAccountRole(accountId, roleId)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,7 @@ import (
 | 
				
			|||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"mayfly-go/internal/sys/domain/entity"
 | 
						"mayfly-go/internal/sys/domain/entity"
 | 
				
			||||||
	"mayfly-go/internal/sys/domain/repository"
 | 
						"mayfly-go/internal/sys/domain/repository"
 | 
				
			||||||
 | 
						"mayfly-go/pkg/contextx"
 | 
				
			||||||
	"mayfly-go/pkg/errorx"
 | 
						"mayfly-go/pkg/errorx"
 | 
				
			||||||
	"mayfly-go/pkg/model"
 | 
						"mayfly-go/pkg/model"
 | 
				
			||||||
	"mayfly-go/pkg/req"
 | 
						"mayfly-go/pkg/req"
 | 
				
			||||||
@@ -34,7 +35,7 @@ func (m *syslogAppImpl) GetPageList(condition *entity.SysLogQuery, pageParam *mo
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *syslogAppImpl) SaveFromReq(req *req.Ctx) {
 | 
					func (m *syslogAppImpl) SaveFromReq(req *req.Ctx) {
 | 
				
			||||||
	lg := req.LoginAccount
 | 
						lg := contextx.GetLoginAccount(req.MetaCtx)
 | 
				
			||||||
	if lg == nil {
 | 
						if lg == nil {
 | 
				
			||||||
		lg = &model.LoginAccount{Id: 0, Username: "-"}
 | 
							lg = &model.LoginAccount{Id: 0, Username: "-"}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -74,5 +75,5 @@ func (m *syslogAppImpl) SaveFromReq(req *req.Ctx) {
 | 
				
			|||||||
		syslog.Type = entity.SyslogTypeNorman
 | 
							syslog.Type = entity.SyslogTypeNorman
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	m.syslogRepo.Insert(syslog)
 | 
						m.syslogRepo.Insert(req.MetaCtx, syslog)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,7 +16,7 @@ type TagTree struct {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (p *TagTree) GetAccountTags(rc *req.Ctx) {
 | 
					func (p *TagTree) GetAccountTags(rc *req.Ctx) {
 | 
				
			||||||
	tagPaths := p.TagTreeApp.ListTagByAccountId(rc.LoginAccount.Id)
 | 
						tagPaths := p.TagTreeApp.ListTagByAccountId(rc.GetLoginAccount().Id)
 | 
				
			||||||
	allTagPath := make([]string, 0)
 | 
						allTagPath := make([]string, 0)
 | 
				
			||||||
	if len(tagPaths) > 0 {
 | 
						if len(tagPaths) > 0 {
 | 
				
			||||||
		tags := p.TagTreeApp.ListTagByPath(tagPaths...)
 | 
							tags := p.TagTreeApp.ListTagByPath(tagPaths...)
 | 
				
			||||||
@@ -46,13 +46,11 @@ func (p *TagTree) SaveTagTree(rc *req.Ctx) {
 | 
				
			|||||||
	tagTree := &entity.TagTree{}
 | 
						tagTree := &entity.TagTree{}
 | 
				
			||||||
	ginx.BindJsonAndValid(rc.GinCtx, tagTree)
 | 
						ginx.BindJsonAndValid(rc.GinCtx, tagTree)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	loginAccount := rc.LoginAccount
 | 
					 | 
				
			||||||
	tagTree.SetBaseInfo(loginAccount)
 | 
					 | 
				
			||||||
	rc.ReqParam = fmt.Sprintf("tagTreeId: %d, tagName: %s, codePath: %s", tagTree.Id, tagTree.Name, tagTree.CodePath)
 | 
						rc.ReqParam = fmt.Sprintf("tagTreeId: %d, tagName: %s, codePath: %s", tagTree.Id, tagTree.Name, tagTree.CodePath)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	biz.ErrIsNil(p.TagTreeApp.Save(tagTree))
 | 
						biz.ErrIsNil(p.TagTreeApp.Save(rc.MetaCtx, tagTree))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (p *TagTree) DelTagTree(rc *req.Ctx) {
 | 
					func (p *TagTree) DelTagTree(rc *req.Ctx) {
 | 
				
			||||||
	biz.ErrIsNil(p.TagTreeApp.Delete(uint64(ginx.PathParamInt(rc.GinCtx, "id"))))
 | 
						biz.ErrIsNil(p.TagTreeApp.Delete(rc.MetaCtx, uint64(ginx.PathParamInt(rc.GinCtx, "id"))))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,9 +35,8 @@ func (p *Team) SaveTeam(rc *req.Ctx) {
 | 
				
			|||||||
	rc.ReqParam = team
 | 
						rc.ReqParam = team
 | 
				
			||||||
	isAdd := team.Id == 0
 | 
						isAdd := team.Id == 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	loginAccount := rc.LoginAccount
 | 
						loginAccount := rc.GetLoginAccount()
 | 
				
			||||||
	team.SetBaseInfo(loginAccount)
 | 
						p.TeamApp.Save(rc.MetaCtx, team)
 | 
				
			||||||
	p.TeamApp.Save(team)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 如果是新增团队则默认将自己加入该团队
 | 
						// 如果是新增团队则默认将自己加入该团队
 | 
				
			||||||
	if isAdd {
 | 
						if isAdd {
 | 
				
			||||||
@@ -46,8 +45,7 @@ func (p *Team) SaveTeam(rc *req.Ctx) {
 | 
				
			|||||||
		teamMem.Username = loginAccount.Username
 | 
							teamMem.Username = loginAccount.Username
 | 
				
			||||||
		teamMem.TeamId = team.Id
 | 
							teamMem.TeamId = team.Id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		teamMem.SetBaseInfo(rc.LoginAccount)
 | 
							p.TeamApp.SaveMember(rc.MetaCtx, teamMem)
 | 
				
			||||||
		p.TeamApp.SaveMember(teamMem)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -59,7 +57,7 @@ func (p *Team) DelTeam(rc *req.Ctx) {
 | 
				
			|||||||
	for _, v := range ids {
 | 
						for _, v := range ids {
 | 
				
			||||||
		value, err := strconv.Atoi(v)
 | 
							value, err := strconv.Atoi(v)
 | 
				
			||||||
		biz.ErrIsNilAppendErr(err, "string类型转换为int异常: %s")
 | 
							biz.ErrIsNilAppendErr(err, "string类型转换为int异常: %s")
 | 
				
			||||||
		p.TeamApp.Delete(uint64(value))
 | 
							p.TeamApp.Delete(rc.MetaCtx, uint64(value))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -94,8 +92,7 @@ func (p *Team) SaveTeamMember(rc *req.Ctx) {
 | 
				
			|||||||
		teamMember.TeamId = teamId
 | 
							teamMember.TeamId = teamId
 | 
				
			||||||
		teamMember.AccountId = accountId
 | 
							teamMember.AccountId = accountId
 | 
				
			||||||
		teamMember.Username = account.Username
 | 
							teamMember.Username = account.Username
 | 
				
			||||||
		teamMember.SetBaseInfo(rc.LoginAccount)
 | 
							p.TeamApp.SaveMember(rc.MetaCtx, teamMember)
 | 
				
			||||||
		p.TeamApp.SaveMember(teamMember)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rc.ReqParam = teamMems
 | 
						rc.ReqParam = teamMems
 | 
				
			||||||
@@ -108,7 +105,7 @@ func (p *Team) DelTeamMember(rc *req.Ctx) {
 | 
				
			|||||||
	aid := ginx.PathParamInt(g, "accountId")
 | 
						aid := ginx.PathParamInt(g, "accountId")
 | 
				
			||||||
	rc.ReqParam = fmt.Sprintf("teamId: %d, accountId: %d", tid, aid)
 | 
						rc.ReqParam = fmt.Sprintf("teamId: %d, accountId: %d", tid, aid)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	p.TeamApp.DeleteMember(uint64(tid), uint64(aid))
 | 
						p.TeamApp.DeleteMember(rc.MetaCtx, uint64(tid), uint64(aid))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 获取团队关联的标签id
 | 
					// 获取团队关联的标签id
 | 
				
			||||||
@@ -133,18 +130,16 @@ func (p *Team) SaveTags(rc *req.Ctx) {
 | 
				
			|||||||
		return i1 == i2
 | 
							return i1 == i2
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	loginAccount := rc.LoginAccount
 | 
					 | 
				
			||||||
	for _, v := range addIds {
 | 
						for _, v := range addIds {
 | 
				
			||||||
		tagId := v
 | 
							tagId := v
 | 
				
			||||||
		tag, err := p.TagApp.GetById(new(entity.TagTree), tagId)
 | 
							tag, err := p.TagApp.GetById(new(entity.TagTree), tagId)
 | 
				
			||||||
		biz.ErrIsNil(err, "存在非法标签id")
 | 
							biz.ErrIsNil(err, "存在非法标签id")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ptt := &entity.TagTreeTeam{TeamId: teamId, TagId: tagId, TagPath: tag.CodePath}
 | 
							ptt := &entity.TagTreeTeam{TeamId: teamId, TagId: tagId, TagPath: tag.CodePath}
 | 
				
			||||||
		ptt.SetBaseInfo(loginAccount)
 | 
							p.TeamApp.SaveTag(rc.MetaCtx, ptt)
 | 
				
			||||||
		p.TeamApp.SaveTag(ptt)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for _, v := range delIds {
 | 
						for _, v := range delIds {
 | 
				
			||||||
		p.TeamApp.DeleteTag(teamId, v)
 | 
							p.TeamApp.DeleteTag(rc.MetaCtx, teamId, v)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rc.ReqParam = form
 | 
						rc.ReqParam = form
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
package application
 | 
					package application
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
	dbapp "mayfly-go/internal/db/application"
 | 
						dbapp "mayfly-go/internal/db/application"
 | 
				
			||||||
	dbentity "mayfly-go/internal/db/domain/entity"
 | 
						dbentity "mayfly-go/internal/db/domain/entity"
 | 
				
			||||||
	machineapp "mayfly-go/internal/machine/application"
 | 
						machineapp "mayfly-go/internal/machine/application"
 | 
				
			||||||
@@ -23,9 +24,9 @@ type TagTree interface {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	ListByQuery(condition *entity.TagTreeQuery, toEntity any)
 | 
						ListByQuery(condition *entity.TagTreeQuery, toEntity any)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Save(tt *entity.TagTree) error
 | 
						Save(ctx context.Context, tt *entity.TagTree) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Delete(id uint64) error
 | 
						Delete(ctx context.Context, id uint64) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 获取账号id拥有的可访问的标签id
 | 
						// 获取账号id拥有的可访问的标签id
 | 
				
			||||||
	ListTagIdByAccountId(accountId uint64) []uint64
 | 
						ListTagIdByAccountId(accountId uint64) []uint64
 | 
				
			||||||
@@ -74,7 +75,7 @@ type tagTreeAppImpl struct {
 | 
				
			|||||||
	dbApp           dbapp.Db
 | 
						dbApp           dbapp.Db
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (p *tagTreeAppImpl) Save(tag *entity.TagTree) error {
 | 
					func (p *tagTreeAppImpl) Save(ctx context.Context, tag *entity.TagTree) error {
 | 
				
			||||||
	// 新建项目树节点信息
 | 
						// 新建项目树节点信息
 | 
				
			||||||
	if tag.Id == 0 {
 | 
						if tag.Id == 0 {
 | 
				
			||||||
		if strings.Contains(tag.Code, entity.CodePathSeparator) {
 | 
							if strings.Contains(tag.Code, entity.CodePathSeparator) {
 | 
				
			||||||
@@ -96,13 +97,13 @@ func (p *tagTreeAppImpl) Save(tag *entity.TagTree) error {
 | 
				
			|||||||
			return errorx.NewBiz("已存在该标签路径开头的标签, 请修改该标识code")
 | 
								return errorx.NewBiz("已存在该标签路径开头的标签, 请修改该标识code")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return p.GetRepo().Insert(tag)
 | 
							return p.Insert(ctx, tag)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 防止误传导致被更新
 | 
						// 防止误传导致被更新
 | 
				
			||||||
	tag.Code = ""
 | 
						tag.Code = ""
 | 
				
			||||||
	tag.CodePath = ""
 | 
						tag.CodePath = ""
 | 
				
			||||||
	return p.GetRepo().UpdateById(tag)
 | 
						return p.UpdateById(ctx, tag)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (p *tagTreeAppImpl) ListByQuery(condition *entity.TagTreeQuery, toEntity any) {
 | 
					func (p *tagTreeAppImpl) ListByQuery(condition *entity.TagTreeQuery, toEntity any) {
 | 
				
			||||||
@@ -161,7 +162,7 @@ func (p *tagTreeAppImpl) CanAccess(accountId uint64, tagPath string) error {
 | 
				
			|||||||
	return errorx.NewBiz("您无权操作该资源")
 | 
						return errorx.NewBiz("您无权操作该资源")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (p *tagTreeAppImpl) Delete(id uint64) error {
 | 
					func (p *tagTreeAppImpl) Delete(ctx context.Context, id uint64) error {
 | 
				
			||||||
	tagIds := [1]uint64{id}
 | 
						tagIds := [1]uint64{id}
 | 
				
			||||||
	if p.machineApp.Count(&machineentity.MachineQuery{TagIds: tagIds[:]}) > 0 {
 | 
						if p.machineApp.Count(&machineentity.MachineQuery{TagIds: tagIds[:]}) > 0 {
 | 
				
			||||||
		return errorx.NewBiz("请先删除该标签关联的机器信息")
 | 
							return errorx.NewBiz("请先删除该标签关联的机器信息")
 | 
				
			||||||
@@ -176,7 +177,7 @@ func (p *tagTreeAppImpl) Delete(id uint64) error {
 | 
				
			|||||||
		return errorx.NewBiz("请先删除该标签关联的Mongo信息")
 | 
							return errorx.NewBiz("请先删除该标签关联的Mongo信息")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	p.DeleteById(id)
 | 
						p.DeleteById(ctx, id)
 | 
				
			||||||
	// 删除该标签关联的团队信息
 | 
						// 删除该标签关联的团队信息
 | 
				
			||||||
	return p.tagTreeTeamRepo.DeleteByCond(&entity.TagTreeTeam{TagId: id})
 | 
						return p.tagTreeTeamRepo.DeleteByCond(ctx, &entity.TagTreeTeam{TagId: id})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
package application
 | 
					package application
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
	"mayfly-go/internal/tag/domain/entity"
 | 
						"mayfly-go/internal/tag/domain/entity"
 | 
				
			||||||
	"mayfly-go/internal/tag/domain/repository"
 | 
						"mayfly-go/internal/tag/domain/repository"
 | 
				
			||||||
	"mayfly-go/pkg/biz"
 | 
						"mayfly-go/pkg/biz"
 | 
				
			||||||
@@ -14,17 +15,17 @@ type Team interface {
 | 
				
			|||||||
	// 分页获取项目团队信息列表
 | 
						// 分页获取项目团队信息列表
 | 
				
			||||||
	GetPageList(condition *entity.Team, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error)
 | 
						GetPageList(condition *entity.Team, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Save(team *entity.Team) error
 | 
						Save(ctx context.Context, team *entity.Team) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Delete(id uint64) error
 | 
						Delete(ctx context.Context, id uint64) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	//--------------- 团队成员相关接口 ---------------
 | 
						//--------------- 团队成员相关接口 ---------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	GetMemberPage(condition *entity.TeamMember, pageParam *model.PageParam, toEntity any) (*model.PageResult[any], error)
 | 
						GetMemberPage(condition *entity.TeamMember, pageParam *model.PageParam, toEntity any) (*model.PageResult[any], error)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	SaveMember(tagTeamMember *entity.TeamMember)
 | 
						SaveMember(ctx context.Context, tagTeamMember *entity.TeamMember)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	DeleteMember(teamId, accountId uint64)
 | 
						DeleteMember(tx context.Context, teamId, accountId uint64)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	IsExistMember(teamId, accounId uint64) bool
 | 
						IsExistMember(teamId, accounId uint64) bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -32,9 +33,9 @@ type Team interface {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	ListTagIds(teamId uint64) []uint64
 | 
						ListTagIds(teamId uint64) []uint64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	SaveTag(tagTeam *entity.TagTreeTeam) error
 | 
						SaveTag(ctx context.Context, tagTeam *entity.TagTreeTeam) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	DeleteTag(teamId, tagId uint64) error
 | 
						DeleteTag(tx context.Context, teamId, tagId uint64) error
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func newTeamApp(teamRepo repository.Team,
 | 
					func newTeamApp(teamRepo repository.Team,
 | 
				
			||||||
@@ -58,23 +59,23 @@ func (p *teamAppImpl) GetPageList(condition *entity.Team, pageParam *model.PageP
 | 
				
			|||||||
	return p.teamRepo.GetPageList(condition, pageParam, toEntity, orderBy...)
 | 
						return p.teamRepo.GetPageList(condition, pageParam, toEntity, orderBy...)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (p *teamAppImpl) Save(team *entity.Team) error {
 | 
					func (p *teamAppImpl) Save(ctx context.Context, team *entity.Team) error {
 | 
				
			||||||
	if team.Id == 0 {
 | 
						if team.Id == 0 {
 | 
				
			||||||
		return p.teamRepo.Insert(team)
 | 
							return p.teamRepo.Insert(ctx, team)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return p.teamRepo.UpdateById(team)
 | 
						return p.teamRepo.UpdateById(ctx, team)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (p *teamAppImpl) Delete(id uint64) error {
 | 
					func (p *teamAppImpl) Delete(ctx context.Context, id uint64) error {
 | 
				
			||||||
	return gormx.Tx(
 | 
						return gormx.Tx(
 | 
				
			||||||
		func(db *gorm.DB) error {
 | 
							func(db *gorm.DB) error {
 | 
				
			||||||
			return p.teamRepo.DeleteByIdWithDb(db, id)
 | 
								return p.teamRepo.DeleteByIdWithDb(ctx, db, id)
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		func(db *gorm.DB) error {
 | 
							func(db *gorm.DB) error {
 | 
				
			||||||
			return p.teamMemberRepo.DeleteByCondWithDb(db, &entity.TeamMember{TeamId: id})
 | 
								return p.teamMemberRepo.DeleteByCondWithDb(ctx, db, &entity.TeamMember{TeamId: id})
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		func(db *gorm.DB) error {
 | 
							func(db *gorm.DB) error {
 | 
				
			||||||
			return p.tagTreeTeamRepo.DeleteByCondWithDb(db, &entity.TagTreeTeam{TeamId: id})
 | 
								return p.tagTreeTeamRepo.DeleteByCondWithDb(ctx, db, &entity.TagTreeTeam{TeamId: id})
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -86,15 +87,15 @@ func (p *teamAppImpl) GetMemberPage(condition *entity.TeamMember, pageParam *mod
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 保存团队成员信息
 | 
					// 保存团队成员信息
 | 
				
			||||||
func (p *teamAppImpl) SaveMember(teamMember *entity.TeamMember) {
 | 
					func (p *teamAppImpl) SaveMember(ctx context.Context, teamMember *entity.TeamMember) {
 | 
				
			||||||
	teamMember.Id = 0
 | 
						teamMember.Id = 0
 | 
				
			||||||
	biz.IsTrue(!p.teamMemberRepo.IsExist(teamMember.TeamId, teamMember.AccountId), "该成员已存在")
 | 
						biz.IsTrue(!p.teamMemberRepo.IsExist(teamMember.TeamId, teamMember.AccountId), "该成员已存在")
 | 
				
			||||||
	p.teamMemberRepo.Insert(teamMember)
 | 
						p.teamMemberRepo.Insert(ctx, teamMember)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 删除团队成员信息
 | 
					// 删除团队成员信息
 | 
				
			||||||
func (p *teamAppImpl) DeleteMember(teamId, accountId uint64) {
 | 
					func (p *teamAppImpl) DeleteMember(ctx context.Context, teamId, accountId uint64) {
 | 
				
			||||||
	p.teamMemberRepo.DeleteByCond(&entity.TeamMember{TeamId: teamId, AccountId: accountId})
 | 
						p.teamMemberRepo.DeleteByCond(ctx, &entity.TeamMember{TeamId: teamId, AccountId: accountId})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (p *teamAppImpl) IsExistMember(teamId, accounId uint64) bool {
 | 
					func (p *teamAppImpl) IsExistMember(teamId, accounId uint64) bool {
 | 
				
			||||||
@@ -114,12 +115,12 @@ func (p *teamAppImpl) ListTagIds(teamId uint64) []uint64 {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 保存关联项目信息
 | 
					// 保存关联项目信息
 | 
				
			||||||
func (p *teamAppImpl) SaveTag(tagTreeTeam *entity.TagTreeTeam) error {
 | 
					func (p *teamAppImpl) SaveTag(ctx context.Context, tagTreeTeam *entity.TagTreeTeam) error {
 | 
				
			||||||
	tagTreeTeam.Id = 0
 | 
						tagTreeTeam.Id = 0
 | 
				
			||||||
	return p.tagTreeTeamRepo.Insert(tagTreeTeam)
 | 
						return p.tagTreeTeamRepo.Insert(ctx, tagTreeTeam)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 删除关联项目信息
 | 
					// 删除关联项目信息
 | 
				
			||||||
func (p *teamAppImpl) DeleteTag(teamId, tagId uint64) error {
 | 
					func (p *teamAppImpl) DeleteTag(ctx context.Context, teamId, tagId uint64) error {
 | 
				
			||||||
	return p.tagTreeTeamRepo.DeleteByCond(&entity.TagTreeTeam{TeamId: teamId, TagId: tagId})
 | 
						return p.tagTreeTeamRepo.DeleteByCond(ctx, &entity.TagTreeTeam{TeamId: teamId, TagId: tagId})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,44 +1,47 @@
 | 
				
			|||||||
package base
 | 
					package base
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
 | 
						"mayfly-go/pkg/model"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"gorm.io/gorm"
 | 
						"gorm.io/gorm"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 基础application接口
 | 
					// 基础application接口
 | 
				
			||||||
type App[T any] interface {
 | 
					type App[T model.ModelI] interface {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 新增一个实体
 | 
						// 新增一个实体
 | 
				
			||||||
	Insert(e T) error
 | 
						Insert(ctx context.Context, e T) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 使用指定gorm db执行,主要用于事务执行
 | 
						// 使用指定gorm db执行,主要用于事务执行
 | 
				
			||||||
	InsertWithDb(db *gorm.DB, e T) error
 | 
						InsertWithDb(ctx context.Context, db *gorm.DB, e T) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 批量新增实体
 | 
						// 批量新增实体
 | 
				
			||||||
	BatchInsert(models []T) error
 | 
						BatchInsert(ctx context.Context, models []T) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 使用指定gorm db执行,主要用于事务执行
 | 
						// 使用指定gorm db执行,主要用于事务执行
 | 
				
			||||||
	BatchInsertWithDb(db *gorm.DB, es []T) error
 | 
						BatchInsertWithDb(ctx context.Context, db *gorm.DB, es []T) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 根据实体id更新实体信息
 | 
						// 根据实体id更新实体信息
 | 
				
			||||||
	UpdateById(e T) error
 | 
						UpdateById(ctx context.Context, e T) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 使用指定gorm db执行,主要用于事务执行
 | 
						// 使用指定gorm db执行,主要用于事务执行
 | 
				
			||||||
	UpdateByIdWithDb(db *gorm.DB, e T) error
 | 
						UpdateByIdWithDb(ctx context.Context, db *gorm.DB, e T) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 根据实体主键删除实体
 | 
						// 根据实体主键删除实体
 | 
				
			||||||
	DeleteById(id uint64) error
 | 
						DeleteById(ctx context.Context, id uint64) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 使用指定gorm db执行,主要用于事务执行
 | 
						// 使用指定gorm db执行,主要用于事务执行
 | 
				
			||||||
	DeleteByIdWithDb(db *gorm.DB, id uint64) error
 | 
						DeleteByIdWithDb(ctx context.Context, db *gorm.DB, id uint64) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 根据实体条件,更新参数udpateFields指定字段
 | 
						// 根据实体条件,更新参数udpateFields指定字段
 | 
				
			||||||
	Updates(cond any, udpateFields map[string]any) error
 | 
						Updates(ctx context.Context, cond any, udpateFields map[string]any) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 根据实体条件删除实体
 | 
						// 根据实体条件删除实体
 | 
				
			||||||
	DeleteByCond(cond any) error
 | 
						DeleteByCond(ctx context.Context, cond any) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 使用指定gorm db执行,主要用于事务执行
 | 
						// 使用指定gorm db执行,主要用于事务执行
 | 
				
			||||||
	DeleteByCondWithDb(db *gorm.DB, cond any) error
 | 
						DeleteByCondWithDb(ctx context.Context, db *gorm.DB, cond any) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 根据实体id查询
 | 
						// 根据实体id查询
 | 
				
			||||||
	GetById(e T, id uint64, cols ...string) (T, error)
 | 
						GetById(e T, id uint64, cols ...string) (T, error)
 | 
				
			||||||
@@ -62,7 +65,7 @@ type App[T any] interface {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 基础application接口实现
 | 
					// 基础application接口实现
 | 
				
			||||||
type AppImpl[T any, R Repo[T]] struct {
 | 
					type AppImpl[T model.ModelI, R Repo[T]] struct {
 | 
				
			||||||
	Repo R // repo接口
 | 
						Repo R // repo接口
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -72,57 +75,57 @@ func (ai *AppImpl[T, R]) GetRepo() R {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 新增一个实体 (单纯新增,不做其他业务逻辑处理)
 | 
					// 新增一个实体 (单纯新增,不做其他业务逻辑处理)
 | 
				
			||||||
func (ai *AppImpl[T, R]) Insert(e T) error {
 | 
					func (ai *AppImpl[T, R]) Insert(ctx context.Context, e T) error {
 | 
				
			||||||
	return ai.GetRepo().Insert(e)
 | 
						return ai.GetRepo().Insert(ctx, e)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 使用指定gorm db执行,主要用于事务执行
 | 
					// 使用指定gorm db执行,主要用于事务执行
 | 
				
			||||||
func (ai *AppImpl[T, R]) InsertWithDb(db *gorm.DB, e T) error {
 | 
					func (ai *AppImpl[T, R]) InsertWithDb(ctx context.Context, db *gorm.DB, e T) error {
 | 
				
			||||||
	return ai.GetRepo().InsertWithDb(db, e)
 | 
						return ai.GetRepo().InsertWithDb(ctx, db, e)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 批量新增实体 (单纯新增,不做其他业务逻辑处理)
 | 
					// 批量新增实体 (单纯新增,不做其他业务逻辑处理)
 | 
				
			||||||
func (ai *AppImpl[T, R]) BatchInsert(es []T) error {
 | 
					func (ai *AppImpl[T, R]) BatchInsert(ctx context.Context, es []T) error {
 | 
				
			||||||
	return ai.GetRepo().BatchInsert(es)
 | 
						return ai.GetRepo().BatchInsert(ctx, es)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 使用指定gorm db执行,主要用于事务执行
 | 
					// 使用指定gorm db执行,主要用于事务执行
 | 
				
			||||||
func (ai *AppImpl[T, R]) BatchInsertWithDb(db *gorm.DB, es []T) error {
 | 
					func (ai *AppImpl[T, R]) BatchInsertWithDb(ctx context.Context, db *gorm.DB, es []T) error {
 | 
				
			||||||
	return ai.GetRepo().BatchInsertWithDb(db, es)
 | 
						return ai.GetRepo().BatchInsertWithDb(ctx, db, es)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 根据实体id更新实体信息 (单纯更新,不做其他业务逻辑处理)
 | 
					// 根据实体id更新实体信息 (单纯更新,不做其他业务逻辑处理)
 | 
				
			||||||
func (ai *AppImpl[T, R]) UpdateById(e T) error {
 | 
					func (ai *AppImpl[T, R]) UpdateById(ctx context.Context, e T) error {
 | 
				
			||||||
	return ai.GetRepo().UpdateById(e)
 | 
						return ai.GetRepo().UpdateById(ctx, e)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 使用指定gorm db执行,主要用于事务执行
 | 
					// 使用指定gorm db执行,主要用于事务执行
 | 
				
			||||||
func (ai *AppImpl[T, R]) UpdateByIdWithDb(db *gorm.DB, e T) error {
 | 
					func (ai *AppImpl[T, R]) UpdateByIdWithDb(ctx context.Context, db *gorm.DB, e T) error {
 | 
				
			||||||
	return ai.GetRepo().UpdateByIdWithDb(db, e)
 | 
						return ai.GetRepo().UpdateByIdWithDb(ctx, db, e)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 根据实体条件,更新参数udpateFields指定字段 (单纯更新,不做其他业务逻辑处理)
 | 
					// 根据实体条件,更新参数udpateFields指定字段 (单纯更新,不做其他业务逻辑处理)
 | 
				
			||||||
func (ai *AppImpl[T, R]) Updates(cond any, udpateFields map[string]any) error {
 | 
					func (ai *AppImpl[T, R]) Updates(ctx context.Context, cond any, udpateFields map[string]any) error {
 | 
				
			||||||
	return ai.GetRepo().Updates(cond, udpateFields)
 | 
						return ai.GetRepo().Updates(cond, udpateFields)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 根据实体主键删除实体 (单纯删除实体,不做其他业务逻辑处理)
 | 
					// 根据实体主键删除实体 (单纯删除实体,不做其他业务逻辑处理)
 | 
				
			||||||
func (ai *AppImpl[T, R]) DeleteById(id uint64) error {
 | 
					func (ai *AppImpl[T, R]) DeleteById(ctx context.Context, id uint64) error {
 | 
				
			||||||
	return ai.GetRepo().DeleteById(id)
 | 
						return ai.GetRepo().DeleteById(ctx, id)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (ai *AppImpl[T, R]) DeleteByIdWithDb(db *gorm.DB, id uint64) error {
 | 
					func (ai *AppImpl[T, R]) DeleteByIdWithDb(ctx context.Context, db *gorm.DB, id uint64) error {
 | 
				
			||||||
	return ai.GetRepo().DeleteByCondWithDb(db, id)
 | 
						return ai.GetRepo().DeleteByCondWithDb(ctx, db, id)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 根据指定条件删除实体 (单纯删除实体,不做其他业务逻辑处理)
 | 
					// 根据指定条件删除实体 (单纯删除实体,不做其他业务逻辑处理)
 | 
				
			||||||
func (ai *AppImpl[T, R]) DeleteByCond(cond any) error {
 | 
					func (ai *AppImpl[T, R]) DeleteByCond(ctx context.Context, cond any) error {
 | 
				
			||||||
	return ai.GetRepo().DeleteByCond(cond)
 | 
						return ai.GetRepo().DeleteByCond(ctx, cond)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 使用指定gorm db执行,主要用于事务执行
 | 
					// 使用指定gorm db执行,主要用于事务执行
 | 
				
			||||||
func (ai *AppImpl[T, R]) DeleteByCondWithDb(db *gorm.DB, cond any) error {
 | 
					func (ai *AppImpl[T, R]) DeleteByCondWithDb(ctx context.Context, db *gorm.DB, cond any) error {
 | 
				
			||||||
	return ai.GetRepo().DeleteByCondWithDb(db, cond)
 | 
						return ai.GetRepo().DeleteByCondWithDb(ctx, db, cond)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 根据实体id查询
 | 
					// 根据实体id查询
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,47 +1,50 @@
 | 
				
			|||||||
package base
 | 
					package base
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
	"mayfly-go/pkg/biz"
 | 
						"mayfly-go/pkg/biz"
 | 
				
			||||||
 | 
						"mayfly-go/pkg/contextx"
 | 
				
			||||||
	"mayfly-go/pkg/gormx"
 | 
						"mayfly-go/pkg/gormx"
 | 
				
			||||||
 | 
						"mayfly-go/pkg/model"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"gorm.io/gorm"
 | 
						"gorm.io/gorm"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 基础repo接口
 | 
					// 基础repo接口
 | 
				
			||||||
type Repo[T any] interface {
 | 
					type Repo[T model.ModelI] interface {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 新增一个实体
 | 
						// 新增一个实体
 | 
				
			||||||
	Insert(e T) error
 | 
						Insert(ctx context.Context, e T) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 使用指定gorm db执行,主要用于事务执行
 | 
						// 使用指定gorm db执行,主要用于事务执行
 | 
				
			||||||
	InsertWithDb(db *gorm.DB, e T) error
 | 
						InsertWithDb(ctx context.Context, db *gorm.DB, e T) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 批量新增实体
 | 
						// 批量新增实体
 | 
				
			||||||
	BatchInsert(models []T) error
 | 
						BatchInsert(ctx context.Context, models []T) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 使用指定gorm db执行,主要用于事务执行
 | 
						// 使用指定gorm db执行,主要用于事务执行
 | 
				
			||||||
	BatchInsertWithDb(db *gorm.DB, es []T) error
 | 
						BatchInsertWithDb(ctx context.Context, db *gorm.DB, es []T) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 根据实体id更新实体信息
 | 
						// 根据实体id更新实体信息
 | 
				
			||||||
	UpdateById(e T) error
 | 
						UpdateById(ctx context.Context, e T) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 使用指定gorm db执行,主要用于事务执行
 | 
						// 使用指定gorm db执行,主要用于事务执行
 | 
				
			||||||
	UpdateByIdWithDb(db *gorm.DB, e T) error
 | 
						UpdateByIdWithDb(ctx context.Context, db *gorm.DB, e T) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 根据实体主键删除实体
 | 
						// 根据实体主键删除实体
 | 
				
			||||||
	DeleteById(id uint64) error
 | 
						DeleteById(ctx context.Context, id uint64) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 使用指定gorm db执行,主要用于事务执行
 | 
						// 使用指定gorm db执行,主要用于事务执行
 | 
				
			||||||
	DeleteByIdWithDb(db *gorm.DB, id uint64) error
 | 
						DeleteByIdWithDb(ctx context.Context, db *gorm.DB, id uint64) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 根据实体条件,更新参数udpateFields指定字段
 | 
						// 根据实体条件,更新参数udpateFields指定字段
 | 
				
			||||||
	Updates(cond any, udpateFields map[string]any) error
 | 
						Updates(cond any, udpateFields map[string]any) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 根据实体条件删除实体
 | 
						// 根据实体条件删除实体
 | 
				
			||||||
	DeleteByCond(cond any) error
 | 
						DeleteByCond(ctx context.Context, cond any) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 使用指定gorm db执行,主要用于事务执行
 | 
						// 使用指定gorm db执行,主要用于事务执行
 | 
				
			||||||
	DeleteByCondWithDb(db *gorm.DB, cond any) error
 | 
						DeleteByCondWithDb(ctx context.Context, db *gorm.DB, cond any) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 根据实体id查询
 | 
						// 根据实体id查询
 | 
				
			||||||
	GetById(e T, id uint64, cols ...string) error
 | 
						GetById(e T, id uint64, cols ...string) error
 | 
				
			||||||
@@ -66,52 +69,58 @@ type Repo[T any] interface {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 基础repo接口
 | 
					// 基础repo接口
 | 
				
			||||||
type RepoImpl[T any] struct {
 | 
					type RepoImpl[T model.ModelI] struct {
 | 
				
			||||||
	M any // 模型实例
 | 
						M any // 模型实例
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (br *RepoImpl[T]) Insert(e T) error {
 | 
					func (br *RepoImpl[T]) Insert(ctx context.Context, e T) error {
 | 
				
			||||||
	return gormx.Insert(e)
 | 
						return gormx.Insert(br.setBaseInfo(ctx, e))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (br *RepoImpl[T]) InsertWithDb(db *gorm.DB, e T) error {
 | 
					func (br *RepoImpl[T]) InsertWithDb(ctx context.Context, db *gorm.DB, e T) error {
 | 
				
			||||||
	return gormx.InsertWithDb(db, e)
 | 
						return gormx.InsertWithDb(db, br.setBaseInfo(ctx, e))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (br *RepoImpl[T]) BatchInsert(es []T) error {
 | 
					func (br *RepoImpl[T]) BatchInsert(ctx context.Context, es []T) error {
 | 
				
			||||||
 | 
						for _, e := range es {
 | 
				
			||||||
 | 
							br.setBaseInfo(ctx, e)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return gormx.BatchInsert(es)
 | 
						return gormx.BatchInsert(es)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 使用指定gorm db执行,主要用于事务执行
 | 
					// 使用指定gorm db执行,主要用于事务执行
 | 
				
			||||||
func (br *RepoImpl[T]) BatchInsertWithDb(db *gorm.DB, es []T) error {
 | 
					func (br *RepoImpl[T]) BatchInsertWithDb(ctx context.Context, db *gorm.DB, es []T) error {
 | 
				
			||||||
 | 
						for _, e := range es {
 | 
				
			||||||
 | 
							br.setBaseInfo(ctx, e)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return gormx.BatchInsertWithDb(db, es)
 | 
						return gormx.BatchInsertWithDb(db, es)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (br *RepoImpl[T]) UpdateById(e T) error {
 | 
					func (br *RepoImpl[T]) UpdateById(ctx context.Context, e T) error {
 | 
				
			||||||
	return gormx.UpdateById(e)
 | 
						return gormx.UpdateById(br.setBaseInfo(ctx, e))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (br *RepoImpl[T]) UpdateByIdWithDb(db *gorm.DB, e T) error {
 | 
					func (br *RepoImpl[T]) UpdateByIdWithDb(ctx context.Context, db *gorm.DB, e T) error {
 | 
				
			||||||
	return gormx.UpdateByIdWithDb(db, e)
 | 
						return gormx.UpdateByIdWithDb(db, br.setBaseInfo(ctx, e))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (br *RepoImpl[T]) Updates(cond any, udpateFields map[string]any) error {
 | 
					func (br *RepoImpl[T]) Updates(cond any, udpateFields map[string]any) error {
 | 
				
			||||||
	return gormx.Updates(cond, udpateFields)
 | 
						return gormx.Updates(cond, udpateFields)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (br *RepoImpl[T]) DeleteById(id uint64) error {
 | 
					func (br *RepoImpl[T]) DeleteById(ctx context.Context, id uint64) error {
 | 
				
			||||||
	return gormx.DeleteById(br.getModel(), id)
 | 
						return gormx.DeleteById(br.getModel(), id)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (br *RepoImpl[T]) DeleteByIdWithDb(db *gorm.DB, id uint64) error {
 | 
					func (br *RepoImpl[T]) DeleteByIdWithDb(ctx context.Context, db *gorm.DB, id uint64) error {
 | 
				
			||||||
	return gormx.DeleteByCondWithDb(db, br.getModel(), id)
 | 
						return gormx.DeleteByCondWithDb(db, br.getModel(), id)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (br *RepoImpl[T]) DeleteByCond(cond any) error {
 | 
					func (br *RepoImpl[T]) DeleteByCond(ctx context.Context, cond any) error {
 | 
				
			||||||
	return gormx.DeleteByCond(br.getModel(), cond)
 | 
						return gormx.DeleteByCond(br.getModel(), cond)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (br *RepoImpl[T]) DeleteByCondWithDb(db *gorm.DB, cond any) error {
 | 
					func (br *RepoImpl[T]) DeleteByCondWithDb(ctx context.Context, db *gorm.DB, cond any) error {
 | 
				
			||||||
	return gormx.DeleteByCondWithDb(db, br.getModel(), cond)
 | 
						return gormx.DeleteByCondWithDb(db, br.getModel(), cond)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -147,3 +156,11 @@ func (br *RepoImpl[T]) getModel() any {
 | 
				
			|||||||
	biz.IsTrue(br.M != nil, "base.RepoImpl的M字段不能为空")
 | 
						biz.IsTrue(br.M != nil, "base.RepoImpl的M字段不能为空")
 | 
				
			||||||
	return br.M
 | 
						return br.M
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 从上下文获取登录账号信息,并赋值至实体
 | 
				
			||||||
 | 
					func (br *RepoImpl[T]) setBaseInfo(ctx context.Context, e T) T {
 | 
				
			||||||
 | 
						if la := contextx.GetLoginAccount(ctx); la != nil {
 | 
				
			||||||
 | 
							e.SetBaseInfo(la)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return e
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,9 +21,12 @@ func WithLoginAccount(ctx context.Context, la *model.LoginAccount) context.Conte
 | 
				
			|||||||
	return context.WithValue(ctx, LoginAccountKey, la)
 | 
						return context.WithValue(ctx, LoginAccountKey, la)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 从context中获取登录账号信息
 | 
					// 从context中获取登录账号信息,不存在返回nil
 | 
				
			||||||
func GetLoginAccount(ctx context.Context) *model.LoginAccount {
 | 
					func GetLoginAccount(ctx context.Context) *model.LoginAccount {
 | 
				
			||||||
	return ctx.Value(LoginAccountKey).(*model.LoginAccount)
 | 
						if la, ok := ctx.Value(LoginAccountKey).(*model.LoginAccount); ok {
 | 
				
			||||||
 | 
							return la
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewTraceId() context.Context {
 | 
					func NewTraceId() context.Context {
 | 
				
			||||||
@@ -31,10 +34,13 @@ func NewTraceId() context.Context {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func WithTraceId(ctx context.Context) context.Context {
 | 
					func WithTraceId(ctx context.Context) context.Context {
 | 
				
			||||||
	return context.WithValue(ctx, TraceIdKey, stringx.Rand(16))
 | 
						return context.WithValue(ctx, TraceIdKey, stringx.RandByChars(16, stringx.Nums+stringx.LowerChars))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 从context中获取traceId
 | 
					// 从context中获取traceId
 | 
				
			||||||
func GetTraceId(ctx context.Context) string {
 | 
					func GetTraceId(ctx context.Context) string {
 | 
				
			||||||
	return ctx.Value(TraceIdKey).(string)
 | 
						if val, ok := ctx.Value(TraceIdKey).(string); ok {
 | 
				
			||||||
 | 
							return val
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ""
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,6 +4,7 @@ import (
 | 
				
			|||||||
	"context"
 | 
						"context"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"log/slog"
 | 
						"log/slog"
 | 
				
			||||||
 | 
						"mayfly-go/pkg/contextx"
 | 
				
			||||||
	"mayfly-go/pkg/utils/runtimex"
 | 
						"mayfly-go/pkg/utils/runtimex"
 | 
				
			||||||
	"path/filepath"
 | 
						"path/filepath"
 | 
				
			||||||
	"runtime"
 | 
						"runtime"
 | 
				
			||||||
@@ -47,7 +48,7 @@ func Debugf(format string, args ...any) {
 | 
				
			|||||||
	Log(context.Background(), slog.LevelDebug, fmt.Sprintf(format, args...))
 | 
						Log(context.Background(), slog.LevelDebug, fmt.Sprintf(format, args...))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func DebugWithFields(msg string, mapFields map[string]any) {
 | 
					func DebugWithFields(ctx context.Context, msg string, mapFields map[string]any) {
 | 
				
			||||||
	Log(context.Background(), slog.LevelDebug, msg, map2Attrs(mapFields)...)
 | 
						Log(context.Background(), slog.LevelDebug, msg, map2Attrs(mapFields)...)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -68,8 +69,8 @@ func Infof(format string, args ...any) {
 | 
				
			|||||||
	Log(context.Background(), slog.LevelInfo, fmt.Sprintf(format, args...))
 | 
						Log(context.Background(), slog.LevelInfo, fmt.Sprintf(format, args...))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func InfoWithFields(msg string, mapFields map[string]any) {
 | 
					func InfoWithFields(ctx context.Context, msg string, mapFields map[string]any) {
 | 
				
			||||||
	Log(context.Background(), slog.LevelInfo, msg, map2Attrs(mapFields)...)
 | 
						Log(ctx, slog.LevelInfo, msg, map2Attrs(mapFields)...)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Warn(msg string, args ...any) {
 | 
					func Warn(msg string, args ...any) {
 | 
				
			||||||
@@ -97,8 +98,8 @@ func ErrorTrace(msg string, err error) {
 | 
				
			|||||||
	Log(context.Background(), slog.LevelError, fmt.Sprintf(msg+" %s\n%s", err.Error(), runtimex.StatckStr(2, 10)))
 | 
						Log(context.Background(), slog.LevelError, fmt.Sprintf(msg+" %s\n%s", err.Error(), runtimex.StatckStr(2, 10)))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func ErrorWithFields(msg string, mapFields map[string]any) {
 | 
					func ErrorWithFields(ctx context.Context, msg string, mapFields map[string]any) {
 | 
				
			||||||
	Log(context.Background(), slog.LevelError, msg, map2Attrs(mapFields)...)
 | 
						Log(ctx, slog.LevelError, msg, map2Attrs(mapFields)...)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Panic(msg string, args ...any) {
 | 
					func Panic(msg string, args ...any) {
 | 
				
			||||||
@@ -120,6 +121,10 @@ func Log(ctx context.Context, level slog.Level, msg string, args ...any) {
 | 
				
			|||||||
func getCommonAttr(ctx context.Context, level slog.Level) []any {
 | 
					func getCommonAttr(ctx context.Context, level slog.Level) []any {
 | 
				
			||||||
	commonAttrs := make([]any, 0)
 | 
						commonAttrs := make([]any, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 尝试从上下文获取traceId,若存在则记录
 | 
				
			||||||
 | 
						if traceId := contextx.GetTraceId(ctx); traceId != "" {
 | 
				
			||||||
 | 
							commonAttrs = append(commonAttrs, "tid", traceId)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// 如果系统配置添加方法信息或者为错误级别时则 记录方法信息及行号
 | 
						// 如果系统配置添加方法信息或者为错误级别时则 记录方法信息及行号
 | 
				
			||||||
	if GetConfig().AddSource || level == slog.LevelError {
 | 
						if GetConfig().AddSource || level == slog.LevelError {
 | 
				
			||||||
		// skip [runtime.Callers, getCommonAttr, appendCommonAttr, logx.Log, logx.Info|Debug|Warn|Error..]
 | 
							// skip [runtime.Callers, getCommonAttr, appendCommonAttr, logx.Log, logx.Info|Debug|Warn|Error..]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,6 +12,15 @@ const (
 | 
				
			|||||||
	ModelUndeleted   int8 = 0
 | 
						ModelUndeleted   int8 = 0
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 实体接口
 | 
				
			||||||
 | 
					type ModelI interface {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 使用当前登录账号信息设置实体结构体的基础信息
 | 
				
			||||||
 | 
						//
 | 
				
			||||||
 | 
						// 如创建时间,修改时间,创建者,修改者信息
 | 
				
			||||||
 | 
						SetBaseInfo(account *LoginAccount)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 含有删除字段模型
 | 
					// 含有删除字段模型
 | 
				
			||||||
type DeletedModel struct {
 | 
					type DeletedModel struct {
 | 
				
			||||||
	Id         uint64     `json:"id"`
 | 
						Id         uint64     `json:"id"`
 | 
				
			||||||
@@ -19,6 +28,13 @@ type DeletedModel struct {
 | 
				
			|||||||
	DeleteTime *time.Time `json:"-"`
 | 
						DeleteTime *time.Time `json:"-"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *DeletedModel) SetBaseInfo(account *LoginAccount) {
 | 
				
			||||||
 | 
						isCreate := m.Id == 0
 | 
				
			||||||
 | 
						if isCreate {
 | 
				
			||||||
 | 
							m.IsDeleted = ModelUndeleted
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 基础实体模型,数据表最基础字段,每张表必备字段
 | 
					// 基础实体模型,数据表最基础字段,每张表必备字段
 | 
				
			||||||
type Model struct {
 | 
					type Model struct {
 | 
				
			||||||
	DeletedModel
 | 
						DeletedModel
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,6 +2,7 @@ package req
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
 | 
						"mayfly-go/pkg/contextx"
 | 
				
			||||||
	"mayfly-go/pkg/errorx"
 | 
						"mayfly-go/pkg/errorx"
 | 
				
			||||||
	"mayfly-go/pkg/logx"
 | 
						"mayfly-go/pkg/logx"
 | 
				
			||||||
	"mayfly-go/pkg/utils/anyx"
 | 
						"mayfly-go/pkg/utils/anyx"
 | 
				
			||||||
@@ -54,7 +55,7 @@ func LogHandler(rc *Ctx) error {
 | 
				
			|||||||
	req := rc.GinCtx.Request
 | 
						req := rc.GinCtx.Request
 | 
				
			||||||
	attrMap[req.Method] = req.URL.Path
 | 
						attrMap[req.Method] = req.URL.Path
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if la := rc.LoginAccount; la != nil {
 | 
						if la := contextx.GetLoginAccount(rc.MetaCtx); la != nil {
 | 
				
			||||||
		attrMap["uid"] = la.Id
 | 
							attrMap["uid"] = la.Id
 | 
				
			||||||
		attrMap["uname"] = la.Username
 | 
							attrMap["uname"] = la.Username
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -93,10 +94,10 @@ func LogHandler(rc *Ctx) error {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := rc.Err; err != nil {
 | 
						if err := rc.Err; err != nil {
 | 
				
			||||||
		logx.ErrorWithFields(logMsg, attrMap)
 | 
							logx.ErrorWithFields(rc.MetaCtx, logMsg, attrMap)
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	logx.InfoWithFields(logMsg, attrMap)
 | 
						logx.InfoWithFields(rc.MetaCtx, logMsg, attrMap)
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,7 @@ import (
 | 
				
			|||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"mayfly-go/pkg/cache"
 | 
						"mayfly-go/pkg/cache"
 | 
				
			||||||
	"mayfly-go/pkg/config"
 | 
						"mayfly-go/pkg/config"
 | 
				
			||||||
 | 
						"mayfly-go/pkg/contextx"
 | 
				
			||||||
	"mayfly-go/pkg/errorx"
 | 
						"mayfly-go/pkg/errorx"
 | 
				
			||||||
	"mayfly-go/pkg/model"
 | 
						"mayfly-go/pkg/model"
 | 
				
			||||||
	"mayfly-go/pkg/rediscli"
 | 
						"mayfly-go/pkg/rediscli"
 | 
				
			||||||
@@ -60,12 +61,10 @@ func PermissionHandler(rc *Ctx) error {
 | 
				
			|||||||
			return errorx.PermissionErr
 | 
								return errorx.PermissionErr
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if rc.LoginAccount == nil {
 | 
						rc.MetaCtx = contextx.WithLoginAccount(rc.MetaCtx, &model.LoginAccount{
 | 
				
			||||||
		rc.LoginAccount = &model.LoginAccount{
 | 
							Id:       userId,
 | 
				
			||||||
			Id:       userId,
 | 
							Username: userName,
 | 
				
			||||||
			Username: userName,
 | 
						})
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,10 @@
 | 
				
			|||||||
package req
 | 
					package req
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
	"io"
 | 
						"io"
 | 
				
			||||||
 | 
						"mayfly-go/pkg/biz"
 | 
				
			||||||
 | 
						"mayfly-go/pkg/contextx"
 | 
				
			||||||
	"mayfly-go/pkg/ginx"
 | 
						"mayfly-go/pkg/ginx"
 | 
				
			||||||
	"mayfly-go/pkg/model"
 | 
						"mayfly-go/pkg/model"
 | 
				
			||||||
	"mayfly-go/pkg/utils/assert"
 | 
						"mayfly-go/pkg/utils/assert"
 | 
				
			||||||
@@ -16,12 +19,13 @@ type HandlerFunc func(*Ctx)
 | 
				
			|||||||
type Ctx struct {
 | 
					type Ctx struct {
 | 
				
			||||||
	Conf *Conf // 请求配置
 | 
						Conf *Conf // 请求配置
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	GinCtx       *gin.Context        // gin context
 | 
						GinCtx   *gin.Context // gin context
 | 
				
			||||||
	LoginAccount *model.LoginAccount // 登录账号信息,只有校验token后才会有值
 | 
						ReqParam any          // 请求参数,主要用于记录日志
 | 
				
			||||||
	ReqParam     any                 // 请求参数,主要用于记录日志
 | 
						ResData  any          // 响应结果
 | 
				
			||||||
	ResData      any                 // 响应结果
 | 
						Err      any          // 请求错误
 | 
				
			||||||
	Err          any                 // 请求错误
 | 
						timed    int64        // 执行时间
 | 
				
			||||||
	timed        int64               // 执行时间
 | 
					
 | 
				
			||||||
 | 
						MetaCtx context.Context // 元数据上下文信息,如登录账号(只有校验token后才会有值),traceId等
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (rc *Ctx) Handle(handler HandlerFunc) {
 | 
					func (rc *Ctx) Handle(handler HandlerFunc) {
 | 
				
			||||||
@@ -59,6 +63,15 @@ func (rc *Ctx) Download(reader io.Reader, filename string) {
 | 
				
			|||||||
	ginx.Download(rc.GinCtx, reader, filename)
 | 
						ginx.Download(rc.GinCtx, reader, filename)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 获取当前登录账号信息,不存在则会报错。
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// 若不需要报错,则使用contextx.GetLoginAccount方法
 | 
				
			||||||
 | 
					func (rc *Ctx) GetLoginAccount() *model.LoginAccount {
 | 
				
			||||||
 | 
						la := contextx.GetLoginAccount(rc.MetaCtx)
 | 
				
			||||||
 | 
						biz.IsTrue(la != nil, "获取登录账号信息失败, 请确认该接口是否通过鉴权")
 | 
				
			||||||
 | 
						return la
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (rc *Ctx) WithConf(conf *Conf) *Ctx {
 | 
					func (rc *Ctx) WithConf(conf *Conf) *Ctx {
 | 
				
			||||||
	rc.Conf = conf
 | 
						rc.Conf = conf
 | 
				
			||||||
	return rc
 | 
						return rc
 | 
				
			||||||
@@ -87,7 +100,7 @@ func (rc *Ctx) GetLogInfo() *LogInfo {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewCtxWithGin(g *gin.Context) *Ctx {
 | 
					func NewCtxWithGin(g *gin.Context) *Ctx {
 | 
				
			||||||
	return &Ctx{GinCtx: g}
 | 
						return &Ctx{GinCtx: g, MetaCtx: contextx.NewTraceId()}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 处理器拦截器函数
 | 
					// 处理器拦截器函数
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,6 +13,11 @@ func ToMap(jsonStr string) map[string]any {
 | 
				
			|||||||
	return ToMapByBytes([]byte(jsonStr))
 | 
						return ToMapByBytes([]byte(jsonStr))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// json字符串转结构体
 | 
				
			||||||
 | 
					func To[T any](jsonStr string, res T) (T, error) {
 | 
				
			||||||
 | 
						return res, json.Unmarshal([]byte(jsonStr), &res)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// json字节数组转map
 | 
					// json字节数组转map
 | 
				
			||||||
func ToMapByBytes(bytes []byte) map[string]any {
 | 
					func ToMapByBytes(bytes []byte) map[string]any {
 | 
				
			||||||
	var res map[string]any
 | 
						var res map[string]any
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,11 +5,18 @@ import (
 | 
				
			|||||||
	"time"
 | 
						"time"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const randChar = "0123456789abcdefghigklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
 | 
					const Nums = "0123456789"
 | 
				
			||||||
 | 
					const LowerChars = "abcdefghigklmnopqrstuvwxyz"
 | 
				
			||||||
 | 
					const UpperChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 生成随机字符串
 | 
					// 生成随机字符串
 | 
				
			||||||
func Rand(l int) string {
 | 
					func Rand(l int) string {
 | 
				
			||||||
	strList := []byte(randChar)
 | 
						return RandByChars(l, Nums+LowerChars+UpperChars)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 根据传入的chars,随机生成指定位数的字符串
 | 
				
			||||||
 | 
					func RandByChars(l int, chars string) string {
 | 
				
			||||||
 | 
						strList := []byte(chars)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	result := []byte{}
 | 
						result := []byte{}
 | 
				
			||||||
	i := 0
 | 
						i := 0
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										26
									
								
								server/pkg/utils/stringx/template_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								server/pkg/utils/stringx/template_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					package stringx
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"mayfly-go/pkg/utils/collx"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestTemplateParse(t *testing.T) {
 | 
				
			||||||
 | 
						tmpl := `
 | 
				
			||||||
 | 
						{{if gt .cpu 10*5}}
 | 
				
			||||||
 | 
							当前服务器[{{.asset.host}}]cpu使用率为{{.cpu}}
 | 
				
			||||||
 | 
						{{end}}
 | 
				
			||||||
 | 
						`
 | 
				
			||||||
 | 
						vars := collx.M{
 | 
				
			||||||
 | 
							"cpu": 60,
 | 
				
			||||||
 | 
							"asset": collx.M{
 | 
				
			||||||
 | 
								"host": "localhost:121",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						res, _ := TemplateParse(tmpl, vars)
 | 
				
			||||||
 | 
						res2 := strings.TrimSpace(res)
 | 
				
			||||||
 | 
						fmt.Println(res2)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user