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