fix 前端菜单 icon

This commit is contained in:
bwcx_jzy 2023-04-16 16:49:01 +08:00
parent 37bc2d6b9a
commit b9c4049592
No known key found for this signature in database
GPG Key ID: E187D6E9DDDE8C53
34 changed files with 680 additions and 407 deletions

View File

@ -1,3 +1,14 @@
{ "recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin", "mikestead.dotenv", "steoates.autoimport",
"formulahendry.auto-rename-tag", "EditorConfig.EditorConfig", "dbaeumer.vscode-eslint", "esbenp.prettier-vscode",
"stylelint.vscode-stylelint", "eamodio.gitlens"] }
{
"recommendations": [
"Vue.volar",
"Vue.vscode-typescript-vue-plugin",
"mikestead.dotenv",
"steoates.autoimport",
"formulahendry.auto-rename-tag",
"EditorConfig.EditorConfig",
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"stylelint.vscode-stylelint",
"eamodio.gitlens"
]
}

View File

@ -32,9 +32,7 @@ const reload = () => {
})
}
provide('app', {
reload
})
provide('reload', reload)
</script>
<style lang="less">

View File

@ -1,10 +1,45 @@
import { createVNode } from 'vue'
import * as Icons from '@ant-design/icons-vue'
import {
FileOutlined,
SettingOutlined,
FileTextOutlined,
CloudServerOutlined,
UserOutlined,
DesktopOutlined,
ToolOutlined,
MonitorOutlined,
CodeOutlined,
BuildOutlined,
SaveOutlined,
HddOutlined,
ApartmentOutlined,
DashboardOutlined,
ProjectOutlined,
GatewayOutlined
} from '@ant-design/icons-vue'
const iconObj = {
file: FileOutlined,
desktop: DesktopOutlined,
setting: SettingOutlined,
hdd: HddOutlined,
save: SaveOutlined,
user: UserOutlined,
apartment: ApartmentOutlined,
build: BuildOutlined,
code: CodeOutlined,
'file-text': FileTextOutlined,
'cloud-server': CloudServerOutlined,
monitor: MonitorOutlined,
tool: ToolOutlined,
dashboard: DashboardOutlined,
project: ProjectOutlined,
gateway: GatewayOutlined
}
const Icon = (props: { type: string }) => {
const { type } = props
// @ts-ignore
return createVNode(Icons[type])
return createVNode(iconObj[type])
}
export default Icon

View File

@ -48,7 +48,7 @@
<li>Alt-G Jump to line</li>
</ul>
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</a-space>
</div>

View File

@ -4,7 +4,7 @@
:getPopupContainer="
this.popupContainerParent
? (triggerNode) => {
return triggerNode.parentNode || document.body;
return triggerNode.parentNode || document.body
}
: null
"
@ -39,7 +39,7 @@
<template slot="title">
<slot name="inputTips"></slot>
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</a-input-search>
</div>
@ -53,111 +53,111 @@
</template>
<script>
import { Select } from "ant-design-vue";
import { Select } from 'ant-design-vue'
export default {
components: {
Select,
VNodes: {
functional: true,
render: (h, ctx) => ctx.props.vnodes,
},
render: (h, ctx) => ctx.props.vnodes
}
},
data() {
return {
selectInput: "",
selectInput: '',
selectOpen: false,
selectFocus: false,
inputFocus: false,
optionList: [],
selected: "",
};
selected: ''
}
},
props: {
// props
...Select.props,
data: {
type: Array,
default: () => [],
default: () => []
},
inputPlaceholder: {
type: String,
default: "请输入...",
default: '请输入...'
},
selectPlaceholder: {
type: String,
default: "请选择",
default: '请选择'
},
selStyle: { type: String, default: "" },
selStyle: { type: String, default: '' },
suffixIcon: {
type: String,
default: "reload",
default: 'reload'
},
maxLength: {
type: Number,
default: 200,
default: 200
},
popupContainerParent: {
type: Boolean,
default: true,
},
default: true
}
},
watch: {
value: {
handler(v) {
this.selected = v;
this.selected = v
},
immediate: true,
immediate: true
},
data: {
handler(v) {
this.optionList = v;
this.optionList = v
},
deep: true,
immediate: true,
},
immediate: true
}
},
methods: {
refreshSelect() {
this.$emit("onRefreshSelect");
this.$emit('onRefreshSelect')
},
selectChange(v) {
this.$emit("input", v);
this.selectOpen = false;
this.$emit("change", v);
this.$emit('input', v)
this.selectOpen = false
this.$emit('change', v)
},
onSearch(v) {
if (!v) {
return;
return
}
let index = this.optionList.indexOf(v);
let index = this.optionList.indexOf(v)
if (index === -1) {
this.optionList = [...this.optionList, v];
this.optionList = [...this.optionList, v]
}
this.selectInput = "";
this.selected = v;
this.selectInput = ''
this.selected = v
//
this.selectChange(v);
this.$emit("addOption", this.optionList);
this.selectChange(v)
this.$emit('addOption', this.optionList)
},
setSelectOpen(v) {
this.selectFocus = v;
this.selectFocus = v
if (this.inputFocus || this.selectFocus) {
this.selectOpen = true;
return;
this.selectOpen = true
return
}
this.selectOpen = false;
this.selectOpen = false
},
visibleInput(v) {
this.inputFocus = v;
this.inputFocus = v
if (this.inputFocus || this.selectFocus) {
this.selectOpen = true;
return;
this.selectOpen = true
return
}
this.selectOpen = false;
},
},
};
this.selectOpen = false
}
}
}
</script>

View File

@ -71,13 +71,22 @@ declare module '@vue/runtime-core' {
ATimelineItem: typeof import('ant-design-vue/es')['TimelineItem']
ATooltip: typeof import('ant-design-vue/es')['Tooltip']
AUpload: typeof import('ant-design-vue/es')['Upload']
BarsOutlined: typeof import('@ant-design/icons-vue')['BarsOutlined']
CodeEditor: typeof import('./../components/codeEditor/index.vue')['default']
CompositionTransfer: typeof import('./../components/compositionTransfer/composition-transfer.vue')['default']
CustomSelect: typeof import('./../components/customSelect/index.vue')['default']
DownloadOutlined: typeof import('@ant-design/icons-vue')['DownloadOutlined']
DownOutlined: typeof import('@ant-design/icons-vue')['DownOutlined']
LoadingOutlined: typeof import('@ant-design/icons-vue')['LoadingOutlined']
LockOutlined: typeof import('@ant-design/icons-vue')['LockOutlined']
LogoutOutlined: typeof import('@ant-design/icons-vue')['LogoutOutlined']
LogView: typeof import('./../components/logView/index.vue')['default']
ProfileOutlined: typeof import('@ant-design/icons-vue')['ProfileOutlined']
QuestionCircleFilled: typeof import('@ant-design/icons-vue')['QuestionCircleFilled']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
SkinOutlined: typeof import('@ant-design/icons-vue')['SkinOutlined']
SwapOutlined: typeof import('@ant-design/icons-vue')['SwapOutlined']
Terminal: typeof import('./../components/terminal/index.vue')['default']
Upgrade: typeof import('./../components/upgrade/index.vue')['default']
ViewPre: typeof import('./../components/logView/view-pre.vue')['default']

View File

@ -4,7 +4,7 @@
<template slot="description">
<a-result status="404" title="404" sub-title="Sorry, the page you visited does not exist.">
<a-button type="primary" @click="goBack">
<a-icon type="left"/>
<left-outlined />
<span>Go Back</span>
</a-button>
</a-result>
@ -12,19 +12,10 @@
</a-card-meta>
</a-card>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
//
goBack() {
this.$router.back(-1);
}
}
<script lang="ts" setup>
const router = useRouter()
const goBack = () => {
router.back()
}
</script>
<style scoped>
@ -33,7 +24,7 @@ export default {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
transform: translate(-50%, -50%);
text-align: center;
}
</style>
</style>

View File

@ -62,7 +62,7 @@
<div>如果不需要保留较多构建历史信息可以到服务端修改构建相关配置参数</div>
<div>构建历史可能占有较多硬盘空间,建议根据实际情况配置保留个数</div>
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</a-space>
</template>

View File

@ -570,7 +570,7 @@
<span>
<a-tooltip>
<template slot="title"> 差异构建是指构建时候是否判断仓库代码有变动如果没有变动则不执行构建 </template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
该选项仅本次构建生效
</span>

View File

@ -54,7 +54,7 @@
</ul>
</div>
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
<a-statistic-countdown format=" s 秒" title="刷新倒计时" :value="countdownTime" @finish="silenceLoadData" />
</a-space>
@ -166,7 +166,7 @@
分发 ID
<a-tooltip v-show="temp.type !== 'edit'">
<template slot="title">分发 ID 等同于项目 ID</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-input
@ -295,7 +295,7 @@
时候需要保证项目能正常重启,并等待上一个项目启动完成才能关闭下一个项目,请根据自身项目启动时间来配置
<li>一般建议 10 秒以上</li>
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-input-number
@ -315,7 +315,7 @@
<template slot="title">
清空发布是指在上传新文件前,会将项目文件夹目录里面的所有文件先删除后再保存新文件
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-row>
@ -329,7 +329,7 @@
发布前停止是指在发布文件到项目文件时先将项目关闭再进行文件替换避免 windows
环境下出现文件被占用的情况
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
发布前停止
</a-col>
@ -350,7 +350,7 @@
<li>异步请求不能保证有序性</li>
</ul>
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-input v-model="temp.webhook" placeholder="分发过程请求,非必填GET请求" />
@ -372,7 +372,7 @@
分发 ID
<a-tooltip v-show="temp.type !== 'edit'">
<template slot="title">分发 ID 等同于项目 ID</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-input
@ -434,7 +434,7 @@
<li><b>File</b> 项目为静态文件夹,没有项目状态以及控制等功能</li>
</ul>
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-select v-model="temp.runMode" placeholder="请选择运行方式">
@ -454,7 +454,7 @@
<li>项目文件会存放到 <br />&nbsp;&nbsp;<b>项目白名单路径+项目文件夹</b></li>
</ul>
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-input-group compact>
@ -475,7 +475,7 @@
<template slot="title">
<ul></ul>
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
@ -499,7 +499,7 @@
</p>
<p>配置详情请参考配置示例</p>
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-tabs>
@ -532,7 +532,7 @@
<li>可选择的列表和项目白名单目录是一致的即相同配置</li>
</ul>
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-select v-model="temp.logPath" placeholder="请选择日志目录">
@ -568,7 +568,7 @@
时候需要保证项目能正常重启,并等待上一个项目启动完成才能关闭下一个项目,请根据自身项目启动时间来配置
<li>一般建议 10 秒以上</li>
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-input-number
@ -588,7 +588,7 @@
<template slot="title">
清空发布是指在上传新文件前,会将项目文件夹目录里面的所有文件先删除后再保存新文件
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-row>
@ -601,7 +601,7 @@
发布前停止是指在发布文件到项目文件时先将项目关闭再进行文件替换避免 windows
环境下出现文件被占用的情况
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
发布前停止
</a-col>
@ -643,7 +643,7 @@
自启动
<a-tooltip v-show="temp.type !== 'edit'">
<template slot="title">插件端启动的时候检查项目状态如果项目状态是未运行则尝试执行启动项目</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-switch v-model="temp[`${nodeId}_autoStart`]" checked-children="" un-checked-children="" />
@ -659,7 +659,7 @@
<li>type 的值有stopbeforeStopstartbeforeRestart</li>
</ul>
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-input
@ -678,7 +678,7 @@
<li>副本是指同一个项目在一个节点服务器中运行多份</li>
</ul>
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<!-- 副本信息 -->
@ -745,7 +745,7 @@
<li>异步请求不能保证有序性</li>
</ul>
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-input v-model="temp.webhook" placeholder="分发过程请求,非必填GET请求" />
@ -801,7 +801,7 @@
<template slot="title">
清空发布是指在上传新文件前,会将项目文件夹目录里面的所有文件先删除后再保存新文件
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-switch v-model="temp.clearOld" checked-children="" un-checked-children="" />
@ -813,7 +813,7 @@
<template slot="title">
如果上传的压缩文件是否自动解压 支持的压缩包类型有 tar.bz2, tar.gz, tar, bz2, zip, gz</template
>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-switch v-model="temp.autoUnzip" checked-children="" un-checked-children="" />

View File

@ -117,7 +117,7 @@
Block IO 权重
<a-tooltip>
<template slot="title"> Block IO 权重相对权重 </template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-input-number
@ -133,7 +133,7 @@
CPU 权重
<a-tooltip>
<template slot="title"> 一个整数值表示此容器相对于其他容器的相对 CPU 权重 </template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-input-number
@ -147,7 +147,7 @@
执行的 CPU
<a-tooltip>
<template slot="title"> 允许执行的 CPU例如0-30,1 </template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-input style="width: 100%" v-model="temp.cpusetCpus" placeholder="允许执行的 CPU例如0-3、0,1。" />
@ -157,7 +157,7 @@
CpusetMems
<a-tooltip>
<template slot="title"> 允许执行的内存节点 (MEM) (0-3, 0,1) 仅在 NUMA 系统上有效 </template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-input
@ -171,7 +171,7 @@
CPU 周期
<a-tooltip>
<template slot="title"> CPU 周期的长度以微秒为单位 </template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-input-number
@ -185,7 +185,7 @@
CPU 时间
<a-tooltip>
<template slot="title"> 容器在一个 CPU 周期内可以获得的 CPU 时间的微秒 </template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-input-number
@ -200,7 +200,7 @@
内存
<a-tooltip>
<template slot="title"> 设置内存限制 </template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-input style="width: 100%" v-model="temp.memory" placeholder="设置内存限制。" />
@ -210,7 +210,7 @@
总内存
<a-tooltip>
<template slot="title"> 总内存内存 + 交换 设置为 -1 以禁用交换 </template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-input
@ -224,7 +224,7 @@
软内存
<a-tooltip>
<template slot="title"> 软内存限制 </template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-input style="width: 100%" v-model="temp.memoryReservation" placeholder="软内存限制。" />

View File

@ -1,7 +1,13 @@
<template>
<div>
<a-menu v-if="userInfo && userInfo.systemUser" theme="dark" mode="inline" v-model="mangerMenuOpenkeys"
@click="mangerMenuClick" :openKeys="mangerMenuOpenkeys">
<a-menu
v-if="userInfo && userInfo.systemUser"
theme="dark"
mode="inline"
v-model="mangerMenuOpenkeys"
@click="mangerMenuClick"
:openKeys="mangerMenuOpenkeys"
>
<a-menu-item key="admin-manager">
<template v-if="props.mode === 'normal'">
<icon type="setting" :style="{ fontSize: '18px' }" />
@ -19,8 +25,12 @@
<icon :type="menu.icon_v3" :style="{ fontSize: '18px' }" />
<span>{{ menu.title }}</span>
</template>
<a-menu-item v-for="subMenu in menu.childs" :key="subMenu.id" :p="(subMenu.parent = menu)"
@click="handleClick(subMenu)">
<a-menu-item
v-for="subMenu in menu.childs"
:key="subMenu.id"
:p="(subMenu.parent = menu)"
@click="handleClick(subMenu)"
>
<span>{{ subMenu.title }}</span>
</a-menu-item>
</a-sub-menu>
@ -28,17 +38,14 @@
</div>
</template>
<script lang="ts" setup>
import Icon from '@/components/Icon';
import { useGuideStore } from '@/stores/guide';
import { useMenuStore } from '@/stores/menu';
import { useUserStore } from '@/stores/user';
import { notification } from 'ant-design-vue';
import { computed, nextTick, onMounted, ref, toRefs } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import Icon from '@/components/Icon'
import { useGuideStore } from '@/stores/guide'
import { useMenuStore } from '@/stores/menu'
import { useUserStore } from '@/stores/user'
const props = defineProps<{
mode: string;
}>();
mode: string
}>()
const menuStore = useMenuStore()
const userStore = useUserStore()
@ -65,85 +72,83 @@ const mangerMenuOpenkeys = ref([])
const { userInfo } = toRefs(userStore)
const mangerMenuClick = () => {
mangerMenuOpenkeys.value = [];
mangerMenuOpenkeys.value = []
nextTick(() => {
mangerMenuOpenkeys.value = []
router.push({
path: props.mode == "normal" ? "/system/management" : "/node/list",
});
path: props.mode == 'normal' ? '/system/management' : '/node/list'
})
})
}
//
const openChange = (keys: string[]) => {
const menuMultipleFlag = guideStore.getGuideCache.menuMultipleFlag;
const menuMultipleFlag = guideStore.getGuideCache.menuMultipleFlag
if (keys.length && !menuMultipleFlag) {
//
keys = [keys[keys.length - 1]];
keys = [keys[keys.length - 1]]
}
menuOpenKeys.value = keys;
menuOpenKeys.value = keys
// menuStore[props.mode == "normal" ? "menuOpenKeys" : "menuManagementOpenKeys"] = keys
menuStore["menuOpenKeys"] = keys
menuStore['menuOpenKeys'] = keys
}
//
const handleClick = (subMenu: any) => {
//
if (!subMenu.path) {
notification.error({
message: "路由无效,无法跳转",
});
return false;
$notification.error({
message: '路由无效,无法跳转'
})
return false
}
//
if (route.path === subMenu.path) {
return false;
return false
}
//
router.push({
query: { ...route.query, sPid: subMenu.parent.id, sId: subMenu.id },
path: subMenu.path,
});
path: subMenu.path
})
}
const selectedKeys = computed(() => {
// todo menu manageMenuStore.getManagementActiveMenuKey
return props.mode == "normal" ? [menuStore.getActiveMenuKey] : [];
return props.mode == 'normal' ? [menuStore.getActiveMenuKey] : []
})
onMounted(() => {
// const key = props.mode == "normal" ? "menuOpenKeys" : "menuManagementOpenKeys"
menuStore["menuOpenKeys"] = [route.query.sPid] as string[] || [""]
menuStore['menuOpenKeys'] = ([route.query.sPid] as string[]) || ['']
})
// export default {
// computed: {
// ...mapGetters(["getMenus", "getManagementMenus", "getActiveMenuKey", "getManagementActiveMenuKey", "getMenuOpenKeys", "getManagementMenuOpenKeys", "getCollapsed", "getGuideCache", "getUserInfo"]),
// selectedKeys: {
// get() {
// return props.mode == "normal" ? [this.getActiveMenuKey] : [this.getManagementActiveMenuKey];
// },
// set() { },
// },
// getMenuOpenKeys2() {
// if (this.getCollapsed) {
// // 使
// return this.menuOpenKeys;
// }
// //
// return props.mode == "normal" ? this.getMenuOpenKeys : this.getManagementMenuOpenKeys;
// },
// menuMultipleFlag() {
// return this.getGuideCache.menuMultipleFlag === undefined ? true : this.getGuideCache.menuMultipleFlag;
// },
// },
// created() {
//
// },
// computed: {
// ...mapGetters(["getMenus", "getManagementMenus", "getActiveMenuKey", "getManagementActiveMenuKey", "getMenuOpenKeys", "getManagementMenuOpenKeys", "getCollapsed", "getGuideCache", "getUserInfo"]),
// selectedKeys: {
// get() {
// return props.mode == "normal" ? [this.getActiveMenuKey] : [this.getManagementActiveMenuKey];
// },
// set() { },
// },
// getMenuOpenKeys2() {
// if (this.getCollapsed) {
// // 使
// return this.menuOpenKeys;
// }
// //
// return props.mode == "normal" ? this.getMenuOpenKeys : this.getManagementMenuOpenKeys;
// },
// menuMultipleFlag() {
// return this.getGuideCache.menuMultipleFlag === undefined ? true : this.getGuideCache.menuMultipleFlag;
// },
// },
// created() {
//
// },
// };
</script>

View File

@ -3,8 +3,10 @@
<a-button-group>
<a-button v-if="mode === 'normal'" type="dashed" class="workspace jpom-workspace btn-group-item">
<div class="workspace-name">
<a-tooltip :title="selectWorkspace && myWorkspaceList.filter((item) => item.id === selectWorkspace)[0].name">
{{ selectWorkspace && myWorkspaceList.filter((item) => item.id === selectWorkspace)[0].name }}
<a-tooltip
:title="selectWorkspace && myWorkspaceList.filter((item:any) => item.id === selectWorkspace)[0].name"
>
{{ selectWorkspace && myWorkspaceList.filter((item: any) => item.id === selectWorkspace)[0].name }}
</a-tooltip>
</div>
</a-button>
@ -14,44 +16,50 @@
</div>
</a-button>
<a-dropdown>
<a-button type="primary" class="jpom-user-operation btn-group-item" icon="down"> </a-button>
<a-button type="primary" class="jpom-user-operation btn-group-item">
<template #icon> <DownOutlined /> </template>
</a-button>
<template #overlay>
<a-menu>
<!-- <template v-if="mode === 'normal'">
<a-sub-menu>
<template #title>
<a-button type="link" icon="swap">切换工作空间</a-button>
</template>
<template v-for="(item, index) in myWorkspaceList">
<a-menu-item v-if="index != -1" :disabled="item.id === selectWorkspace"
@click="handleWorkspaceChange(item.id)" :key="index">
<a-button type="link" :disabled="item.id === selectWorkspace">
{{ item.name }}
</a-button>
</a-menu-item>
<a-menu-divider v-if="index != -1" :key="`${item.id}-divider`" />
</template>
</a-sub-menu>
<a-menu-divider />
</template> -->
<template v-if="mode === 'normal'">
<a-sub-menu>
<template #title>
<a-button type="link"><swap-outlined />切换工作空间</a-button>
</template>
<template v-for="(item, index) in myWorkspaceList">
<a-menu-item
v-if="index != -1"
:disabled="item.id === selectWorkspace"
@click="handleWorkspaceChange(item.id)"
:key="index"
>
<a-button type="link" :disabled="item.id === selectWorkspace">
{{ item.name }}
</a-button>
</a-menu-item>
<a-menu-divider v-if="index != -1" :key="`${item.id}-divider`" />
</template>
</a-sub-menu>
<a-menu-divider />
</template>
<a-menu-item @click="handleUpdatePwd">
<a-button type="link" icon="lock"> 安全管理 </a-button>
<a-button type="link"><lock-outlined /> 安全管理 </a-button>
</a-menu-item>
<a-menu-divider />
<a-menu-item @click="handleUpdateUser">
<a-button type="link" icon="profile"> 用户资料 </a-button>
<a-button type="link"><profile-outlined /> 用户资料 </a-button>
</a-menu-item>
<a-menu-divider />
<a-menu-item @click="handleUserlog">
<a-button type="link" icon="bars"> 操作日志 </a-button>
<a-button type="link"> <bars-outlined /> 操作日志 </a-button>
</a-menu-item>
<a-menu-divider />
<a-menu-item @click="customize">
<a-button type="link" icon="skin"> 个性配置 </a-button>
<a-button type="link"><skin-outlined /> 个性配置 </a-button>
</a-menu-item>
<a-menu-divider />
<a-menu-item @click="logOut">
<a-button type="link" icon="logout"> 退出登录 </a-button>
<a-button type="link"><logout-outlined /> 退出登录 </a-button>
</a-menu-item>
</a-menu>
</template>
@ -59,7 +67,14 @@
</a-button-group>
<!-- 修改密码区 -->
<a-modal destroyOnClose v-model="updateNameVisible" :width="'60vw'" title="安全管理" :footer="null" :maskClosable="false">
<a-modal
destroyOnClose
v-model="updateNameVisible"
:width="'60vw'"
title="安全管理"
:footer="null"
:maskClosable="false"
>
<a-tabs v-model="tabActiveKey" @change="tabChange">
<a-tab-pane :key="1" tab="修改密码">
<a-form :rules="pwdRules" :model="pwdState" :label-col="{ span: 6 }" :wrapper-col="{ span: 14 }">
@ -93,8 +108,13 @@
</template>
</a-alert>
<a-col :span="12">
<a-form ref="mfaForm" :model="mfaState" :rules="mfaRules" :label-col="{ span: 6 }"
:wrapper-col="{ span: 14 }">
<a-form
ref="mfaForm"
:model="mfaState"
:rules="mfaRules"
:label-col="{ span: 6 }"
:wrapper-col="{ span: 14 }"
>
<a-form-item label="当前状态" name="status">
<a-switch checked-children="开启中" disabled un-checked-children="关闭中" v-model="mfaState.status" />
</a-form-item>
@ -107,15 +127,22 @@
</a-row>
</a-form-item>
<a-form-item label="MFA key">
<a-input v-clipboard:copy="mfaState.mfaKey" v-clipboard:success="
() => {
// tempVue.prototype.$notification.success({ message: '' })
}
" v-clipboard:error="
() => {
// tempVue.prototype.$notification.error({ message: '' })
}
" readOnly disabled v-model="mfaState.mfaKey">
<a-input
v-clipboard:copy="mfaState.mfaKey"
v-clipboard:success="
() => {
// tempVue.prototype.$notification.success({ message: '' })
}
"
v-clipboard:error="
() => {
// tempVue.prototype.$notification.error({ message: '' })
}
"
readOnly
disabled
v-model="mfaState.mfaKey"
>
<a-icon slot="prefix" type="copy" />
</a-input>
</a-form-item>
@ -162,34 +189,52 @@
</a-modal>
<!-- 修改用户资料区 -->
<a-modal destroyOnClose v-model="updateUserVisible" title="修改用户资料" @ok="handleUpdateUserOk" :maskClosable="false">
<a-modal
destroyOnClose
v-model="updateUserVisible"
title="修改用户资料"
@ok="handleUpdateUserOk"
:maskClosable="false"
>
<a-form :rules="userRules" :model="temp" :label-col="{ span: 8 }" :wrapper-col="{ span: 15 }">
<a-form-item label="临时token" name="token">
<a-input disabled v-model="userState.token" placeholder="Token">
<a-tooltip slot="suffix" title="复制" v-clipboard:copy="userState.token" v-clipboard:success="
() => {
// tempVue.prototype.$notification.success({ message: '' })
}
" v-clipboard:error="
() => {
// tempVue.prototype.$notification.error({ message: '' })
}
">
<a-tooltip
slot="suffix"
title="复制"
v-clipboard:copy="userState.token"
v-clipboard:success="
() => {
// tempVue.prototype.$notification.success({ message: '' })
}
"
v-clipboard:error="
() => {
// tempVue.prototype.$notification.error({ message: '' })
}
"
>
<a-icon type="copy" />
</a-tooltip>
</a-input>
</a-form-item>
<a-form-item label="长期token" name="md5Token">
<a-input disabled v-model="userState.md5Token" placeholder="Token">
<a-tooltip slot="suffix" title="复制" v-clipboard:copy="userState.md5Token" v-clipboard:success="
() => {
// tempVue.prototype.$notification.success({ message: '' })
}
" v-clipboard:error="
() => {
// tempVue.prototype.$notification.error({ message: '' })
}
">
<a-tooltip
slot="suffix"
title="复制"
v-clipboard:copy="userState.md5Token"
v-clipboard:success="
() => {
// tempVue.prototype.$notification.success({ message: '' })
}
"
v-clipboard:error="
() => {
// tempVue.prototype.$notification.error({ message: '' })
}
"
>
<a-icon type="copy" />
</a-tooltip>
</a-input>
@ -239,38 +284,69 @@
<a-form-item label="菜单配置" name="token">
<a-space>
同时展开多个
<a-switch checked-children="" @click="toggleMenuMultiple" :checked="guideCache.menuMultipleFlag"
un-checked-children="否" />
<a-switch
checked-children="是"
@click="toggleMenuMultiple"
:checked="guideCache.menuMultipleFlag"
un-checked-children="否"
/>
</a-space>
</a-form-item>
<a-form-item label="页面配置" name="token">
<a-space>
自动撑开
<a-switch checked-children="" @click="toggleFullScreenFlag" :checked="guideCache.fullScreenFlag"
un-checked-children="否" />
<a-switch
checked-children="是"
@click="toggleFullScreenFlag"
:checked="guideCache.fullScreenFlag"
un-checked-children="否"
/>
</a-space>
</a-form-item>
<a-form-item label="滚动条显示" name="token">
<a-space>
全局配置
<a-switch checked-children="显示" @click="toggleScrollbarFlag" :checked="guideCache.scrollbarFlag"
un-checked-children="不显示" />
<a-switch
checked-children="显示"
@click="toggleScrollbarFlag"
:checked="guideCache.scrollbarFlag"
un-checked-children="不显示"
/>
</a-space>
</a-form-item>
</a-form>
</a-modal>
<!-- mfa 提示 -->
<a-modal destroyOnClose v-model="bindMfaTip" title="安全提醒" :footer="null" :maskClosable="false" :closable="false"
:keyboard="false">
<a-modal
destroyOnClose
v-model="bindMfaTip"
title="安全提醒"
:footer="null"
:maskClosable="false"
:closable="false"
:keyboard="false"
>
<a-space direction="vertical">
<a-alert message="安全提醒" description="为了您的账号安全系统要求必须开启两步验证来确保账号的安全性" type="error" :closable="false" />
<a-alert
message="安全提醒"
description="为了您的账号安全系统要求必须开启两步验证来确保账号的安全性"
type="error"
:closable="false"
/>
<a-row align="middle" type="flex" justify="center">
<a-button type="danger" @click="toBindMfa"> 立即开启 </a-button>
</a-row>
</a-space>
</a-modal>
<!-- 查看操作日志 -->
<a-modal destroyOnClose v-model="viewLogVisible" :width="'90vw'" title="操作日志" :footer="null" :maskClosable="false">
<a-modal
destroyOnClose
v-model="viewLogVisible"
:width="'90vw'"
title="操作日志"
:footer="null"
:maskClosable="false"
>
<user-log v-if="viewLogVisible"></user-log>
</a-modal>
</div>
@ -306,8 +382,6 @@ const props = defineProps<{
mode: string
}>()
const reload = inject('reload')
const { userInfo } = toRefs(userStore)
const { guideCache } = toRefs(guideStore)
@ -315,7 +389,7 @@ const collapsed = ref(false)
const updateNameVisible = ref(false)
const updateUserVisible = ref(false)
const temp = reactive({})
const myWorkspaceList = ref([])
const myWorkspaceList = ref(<any>[])
const selectWorkspace = ref('')
const customizeVisible = ref(false)
@ -580,13 +654,17 @@ const handleUpdateUserOk = () => {
})
})
}
const pageReload = inject<Function>('reload')
const handleWorkspaceChange = (value: string) => {
appStore.changeWorkspace(value)
router.push({
query: { ...route.query, wid: value }
})
router
.push({
query: { ...route.query, wid: value }
})
.then(() => {
pageReload?.()
})
}
const tabActiveKey = ref(1)
@ -661,10 +739,10 @@ const openMfaFn = () => {
if (res.code === 200) {
mfaState.status = true
mfaState.mfaKey = res.data.mfaKey
; (mfaState.url = res.data.url),
(mfaState.needVerify = true),
(mfaState.showSaveTip = true),
(mfaState.twoCode = '')
;(mfaState.url = res.data.url),
(mfaState.needVerify = true),
(mfaState.showSaveTip = true),
(mfaState.twoCode = '')
// this.showQrCode()
$notification.info({
@ -696,8 +774,6 @@ const handleUserlog = () => {
onMounted(() => {
init()
})
</script>
<style scoped lang="less">

View File

@ -163,7 +163,7 @@
<template slot="title">
如果这里的报警联系人无法选择说明这里面的管理员没有设置邮箱在右上角下拉菜单里面的用户资料里可以设置
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-transfer
@ -206,7 +206,7 @@
<li>runStatus 值为 true 表示项目当前为运行中(异常恢复),false 表示项目当前未运行(发生异常)</li>
</ul>
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-input v-model="temp.webhook" placeholder="接收报警消息,非必填GET请求" />

View File

@ -107,7 +107,7 @@
<template slot="title">
如果这里的报警联系人无法选择说明这里面的管理员没有设置邮箱在右上角下拉菜单里面的用户资料里可以设置
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-transfer

View File

@ -6,7 +6,8 @@
<template #extra>
<a-button type="primary" @click="fastInstallNodeShow">快速安装 </a-button>
<router-link to="/system/assets/machine-list">
<a-button key="console" type="primary">手动添加</a-button></router-link>
<a-button key="console" type="primary">手动添加</a-button></router-link
>
</template>
<div class="desc">
<p style="font-size: 16px">
@ -27,22 +28,35 @@
<a-space>
<a-input v-model="listQuery['%name%']" @pressEnter="loadData" placeholder="节点名称" />
<a-select show-search option-filter-prop="children" v-model="listQuery.group" allowClear placeholder="分组"
class="search-input-item">
<a-select
show-search
option-filter-prop="children"
v-model="listQuery.group"
allowClear
placeholder="分组"
class="search-input-item"
>
<a-select-option v-for="item in groupList" :key="item">{{ item }}</a-select-option>
</a-select>
<a-tooltip title="按住 Ctr 或者 Alt/Option 键点击按钮快速回到第一页">
<a-button :loading="loading" type="primary" @click="loadData">搜索</a-button>
</a-tooltip>
<a-button type="primary" @click="
() => {
fastInstallNode = true
}
">快速安装
<a-button
type="primary"
@click="
() => {
fastInstallNode = true
}
"
>快速安装
</a-button>
<a-dropdown v-if="layoutType === 'table'">
<a-button type="primary" :disabled="!tableSelections || !tableSelections.length"
@click="syncToWorkspaceShow">工作空间同步</a-button>
<a-button
type="primary"
:disabled="!tableSelections || !tableSelections.length"
@click="syncToWorkspaceShow"
>工作空间同步</a-button
>
</a-dropdown>
<a-tooltip v-else title="表格视图才能使用工作空间同步功能">
<a-button :disabled="true" type="primary"> 工作空间同步 </a-button>
@ -66,20 +80,29 @@
</ul>
</div>
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
<div class="header-statistic">
<a-statistic-countdown format="s 秒" title="刷新倒计时 " :value="deadline" @finish="onFinish" />
</div>
</a-space>
</template>
<a-table v-if="layoutType === 'table'" :columns="columns" :data-source="list" bordered size="middle" rowKey="id"
:pagination="pagination" @change="
<a-table
v-if="layoutType === 'table'"
:columns="columns"
:data-source="list"
bordered
size="middle"
rowKey="id"
:pagination="pagination"
@change="
(pagination, filters, sorter) => {
listQuery.value = CHANGE_PAGE(listQuery.value, { pagination, sorter })
loadData()
}
" :row-selection="rowSelection">
"
:row-selection="rowSelection"
>
<a-tooltip slot="url" slot-scope="text, record" placement="topLeft" :title="text">
<template v-if="record.machineNodeData">
<span>{{ record.machineNodeData.jpomProtocol }}://{{ record.machineNodeData.jpomUrl }}</span>
@ -100,11 +123,19 @@
</a-tooltip>
</template>
</template>
<a-tooltip slot="status" slot-scope="text, item" placement="topLeft" :title="`${statusMap[item.machineNodeData && item.machineNodeData.status] || '未知'} ${item.machineNodeData && item.machineNodeData.statusMsg
}`">
<a-tooltip
slot="status"
slot-scope="text, item"
placement="topLeft"
:title="`${statusMap[item.machineNodeData && item.machineNodeData.status] || '未知'} ${
item.machineNodeData && item.machineNodeData.statusMsg
}`"
>
<template v-if="item.openStatus === 1">
<a-tag :color="item.machineNodeData && item.machineNodeData.status === 1 ? 'green' : 'pink'"
style="margin-right: 0px">
<a-tag
:color="item.machineNodeData && item.machineNodeData.status === 1 ? 'green' : 'pink'"
style="margin-right: 0px"
>
{{ statusMap[item.machineNodeData && item.machineNodeData.status] || '未知' }}
</a-tag>
</template>
@ -116,18 +147,29 @@
<a-tooltip slot="javaVersion" slot-scope="text, item" placement="topLeft" :title="text">
<span>{{ item.machineNodeData && item.machineNodeData.javaVersion }}</span>
</a-tooltip>
<a-tooltip slot="jvmInfo" slot-scope="text, item" placement="topLeft" :title="`剩余内存${renderSize(
item.machineNodeData && item.machineNodeData.jvmFreeMemory
)} 总内存${renderSize(item.machineNodeData && item.machineNodeData.jvmTotalMemory)}`">
<span>{{ renderSize(item.machineNodeData && item.machineNodeData.jvmFreeMemory) }} /
{{ renderSize(item.machineNodeData && item.machineNodeData.jvmTotalMemory) }}</span>
<a-tooltip
slot="jvmInfo"
slot-scope="text, item"
placement="topLeft"
:title="`剩余内存:${renderSize(
item.machineNodeData && item.machineNodeData.jvmFreeMemory
)} 总内存${renderSize(item.machineNodeData && item.machineNodeData.jvmTotalMemory)}`"
>
<span
>{{ renderSize(item.machineNodeData && item.machineNodeData.jvmFreeMemory) }} /
{{ renderSize(item.machineNodeData && item.machineNodeData.jvmTotalMemory) }}</span
>
</a-tooltip>
<!-- <a-tooltip slot="freeMemory" slot-scope="text" placement="topLeft" :title="renderSize(text)">
<span>{{ renderSize(text) }}</span>
</a-tooltip> -->
<a-tooltip slot="runTime" slot-scope="text, item" placement="topLeft"
:title="formatDuration(item.machineNodeData && item.machineNodeData.jpomUptime)">
<a-tooltip
slot="runTime"
slot-scope="text, item"
placement="topLeft"
:title="formatDuration(item.machineNodeData && item.machineNodeData.jpomUptime)"
>
<span>{{ formatDuration(item.machineNodeData && item.machineNodeData.jpomUptime, '', 2) }}</span>
</a-tooltip>
<template slot="projectCount" slot-scope="text, item">
@ -152,12 +194,19 @@
<template slot="operation" slot-scope="text, record, index">
<a-space>
<a-tooltip title="如果按钮不可用则表示当前节点已经关闭啦,需要去编辑中启用">
<a-button size="small" class="jpom-node-manage-btn" type="primary" @click="handleNode(record)"
:disabled="record.openStatus !== 1"><a-icon type="apartment" />管理</a-button>
<a-button
size="small"
class="jpom-node-manage-btn"
type="primary"
@click="handleNode(record)"
:disabled="record.openStatus !== 1"
><a-icon type="apartment" />管理</a-button
>
</a-tooltip>
<a-tooltip title="需要到编辑中去为一个节点绑定一个 ssh信息才能启用该功能">
<a-button size="small" type="primary" @click="handleTerminal(record)" :disabled="!record.sshId"><a-icon
type="code" />终端</a-button>
<a-button size="small" type="primary" @click="handleTerminal(record)" :disabled="!record.sshId"
><a-icon type="code" />终端</a-button
>
</a-tooltip>
<a-dropdown>
@ -176,25 +225,39 @@
</a-tooltip>
</a-menu-item>
<a-menu-item>
<a-tooltip placement="leftBottom" title="解绑会检查数据关联性,同时将自动删除节点项目和脚本缓存信息,一般用于服务器无法连接且已经确定不再使用">
<a-tooltip
placement="leftBottom"
title="解绑会检查数据关联性,同时将自动删除节点项目和脚本缓存信息,一般用于服务器无法连接且已经确定不再使用"
>
<a-button size="small" type="danger" @click="handleUnbind(record)">解绑</a-button>
</a-tooltip>
</a-menu-item>
<a-menu-divider />
<a-menu-item>
<a-button size="small" type="primary"
<a-button
size="small"
type="primary"
:disabled="(listQuery.page - 1) * listQuery.limit + (index + 1) <= 1"
@click="sortItemHander(record, index, 'top')">置顶</a-button>
@click="sortItemHander(record, index, 'top')"
>置顶</a-button
>
</a-menu-item>
<a-menu-item>
<a-button size="small" type="primary"
<a-button
size="small"
type="primary"
:disabled="(listQuery.page - 1) * listQuery.limit + (index + 1) <= 1"
@click="sortItemHander(record, index, 'up')">上移</a-button>
@click="sortItemHander(record, index, 'up')"
>上移</a-button
>
</a-menu-item>
<a-menu-item>
<a-button size="small" type="primary"
<a-button
size="small"
type="primary"
:disabled="(listQuery.page - 1) * listQuery.limit + (index + 1) === listQuery.total"
@click="sortItemHander(record, index, 'down')">
@click="sortItemHander(record, index, 'down')"
>
下移
</a-button>
</a-menu-item>
@ -212,8 +275,11 @@
<a-card :headStyle="{ padding: '0 6px' }" :bodyStyle="{ padding: '10px' }">
<template slot="title">
<a-row :gutter="[4, 0]">
<a-col :span="17" class="jpom-node-manage-btn"
style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap">
<a-col
:span="17"
class="jpom-node-manage-btn"
style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap"
>
<a-tooltip>
<template slot="title">
点击进入节点管理
@ -236,8 +302,10 @@
状态描述{{ (item.machineNodeData && item.machineNodeData.statusMsg) || '' }}
</div>
</template>
<a-tag :color="item.machineNodeData && item.machineNodeData.status === 1 ? 'green' : 'pink'"
style="margin-right: 0px">
<a-tag
:color="item.machineNodeData && item.machineNodeData.status === 1 ? 'green' : 'pink'"
style="margin-right: 0px"
>
{{ statusMap[item.machineNodeData && item.machineNodeData.status] }}
</a-tag>
</a-tooltip>
@ -248,41 +316,71 @@
<a-row :gutter="[8, 8]">
<a-col :span="8" style="text-align: center">
<a-tooltip @click="handleHistory(item, 'nodeTop')" :title="`CPU 占用率:${item.occupyCpu}%`">
<a-progress type="circle" :width="80" :stroke-color="{
'0%': '#87d068',
'30%': '#87d068',
'100%': '#108ee9'
}" size="small" status="active" :percent="item.occupyCpu" />
<a-progress
type="circle"
:width="80"
:stroke-color="{
'0%': '#87d068',
'30%': '#87d068',
'100%': '#108ee9'
}"
size="small"
status="active"
:percent="item.occupyCpu"
/>
</a-tooltip>
</a-col>
<a-col :span="8" style="text-align: center">
<a-tooltip @click="handleHistory(item, 'nodeTop')" :title="`硬盘占用率:${item.occupyDisk}%`">
<a-progress type="circle" :width="80" :stroke-color="{
'0%': '#87d068',
'30%': '#87d068',
'100%': '#108ee9'
}" size="small" status="active" :percent="item.occupyDisk" />
<a-progress
type="circle"
:width="80"
:stroke-color="{
'0%': '#87d068',
'30%': '#87d068',
'100%': '#108ee9'
}"
size="small"
status="active"
:percent="item.occupyDisk"
/>
</a-tooltip>
</a-col>
<a-col :span="8" style="text-align: center">
<a-tooltip @click="handleHistory(item, 'nodeTop')" :title="`内存占用率:${item.occupyMemory}%`">
<a-progress :width="80" type="circle" :stroke-color="{
'0%': '#87d068',
'30%': '#87d068',
'100%': '#108ee9'
}" size="small" status="active" :percent="item.occupyMemory" />
<a-tooltip
@click="handleHistory(item, 'nodeTop')"
:title="`内存占用率:${item.occupyMemory}%`"
>
<a-progress
:width="80"
type="circle"
:stroke-color="{
'0%': '#87d068',
'30%': '#87d068',
'100%': '#108ee9'
}"
size="small"
status="active"
:percent="item.occupyMemory"
/>
</a-tooltip>
</a-col>
</a-row>
<a-row :gutter="[8, 8]" style="text-align: center">
<a-col :span="8">
<a-tooltip @click="handleHistory(item, 'networkDelay')" :title="`${'延迟' +
(formatDuration(item.machineNodeData && item.machineNodeData.networkDelay, '', 2) ||
'-') +
' 点击查看历史趋势'
}`">
<a-statistic title="延迟" :value="item.machineNodeData && item.machineNodeData.networkDelay"
<a-tooltip
@click="handleHistory(item, 'networkDelay')"
:title="`${
'延迟' +
(formatDuration(item.machineNodeData && item.machineNodeData.networkDelay, '', 2) ||
'-') +
' 点击查看历史趋势'
}`"
>
<a-statistic
title="延迟"
:value="item.machineNodeData && item.machineNodeData.networkDelay"
valueStyle="font-size: 14px;overflow: hidden; text-overflow: ellipsis; white-space: nowrap"
:formatter="
(v) => {
@ -291,14 +389,18 @@
'-'
)
}
" />
"
/>
</a-tooltip>
</a-col>
<a-col :span="8">
<a-tooltip :title="
formatDuration(item.machineNodeData && item.machineNodeData.jpomUptime, '', 1) || '-'
">
<a-statistic title="运行时间"
<a-tooltip
:title="
formatDuration(item.machineNodeData && item.machineNodeData.jpomUptime, '', 1) || '-'
"
>
<a-statistic
title="运行时间"
valueStyle="font-size: 14px;overflow: hidden; text-overflow: ellipsis; white-space: nowrap"
:formatter="
(v) => {
@ -307,13 +409,16 @@
'-'
)
}
" />
"
/>
</a-tooltip>
</a-col>
<a-col :span="8">
<a-tooltip
:title="`${parseTime(item.machineNodeData && item.machineNodeData.modifyTimeMillis)}`">
<a-statistic title="更新时间"
:title="`${parseTime(item.machineNodeData && item.machineNodeData.modifyTimeMillis)}`"
>
<a-statistic
title="更新时间"
valueStyle="font-size: 14px;overflow: hidden; text-overflow: ellipsis; white-space: nowrap"
:formatter="
(v) => {
@ -322,7 +427,8 @@
'{h}:{i}:{s}'
)
}
" />
"
/>
</a-tooltip>
</a-col>
</a-row>
@ -338,17 +444,27 @@
<a-row type="flex" justify="center">
<a-divider v-if="listQuery.total / listQuery.limit > 1" dashed />
<a-col>
<a-pagination v-model="listQuery.page" :showTotal="
(total) => {
return PAGE_DEFAULT_SHOW_TOTAL(total, listQuery)
}
" :showSizeChanger="true" :pageSizeOptions="sizeOptions" :pageSize="listQuery.limit"
:total="listQuery.total" :hideOnSinglePage="true" @showSizeChange="
<a-pagination
v-model="listQuery.page"
:showTotal="
(total) => {
return PAGE_DEFAULT_SHOW_TOTAL(total, listQuery)
}
"
:showSizeChanger="true"
:pageSizeOptions="sizeOptions"
:pageSize="listQuery.limit"
:total="listQuery.total"
:hideOnSinglePage="true"
@showSizeChange="
(current, size) => {
listQuery.value.limit = size
loadData()
}
" @change="loadData" show-less-items />
"
@change="loadData"
show-less-items
/>
</a-col>
</a-row>
</template>
@ -356,24 +472,41 @@
</template>
<!-- 编辑区 -->
<a-modal destroyOnClose v-model="editNodeVisible" width="50%" title="编辑节点" @ok="handleEditNodeOk"
:maskClosable="false">
<a-modal
destroyOnClose
v-model="editNodeVisible"
width="50%"
title="编辑节点"
@ok="handleEditNodeOk"
:maskClosable="false"
>
<a-form ref="editNodeForm" :rules="rules" :model="temp" :label-col="{ span: 4 }" :wrapper-col="{ span: 19 }">
<a-form-item label="节点名称" prop="name">
<a-input :maxLength="50" v-model="temp.name" placeholder="节点名称" />
</a-form-item>
<a-form-item label="分组名称" prop="group">
<custom-select v-model="temp.group" :data="groupList" suffixIcon="" inputPlaceholder="添加分组"
selectPlaceholder="选择分组名">
<custom-select
v-model="temp.group"
:data="groupList"
suffixIcon=""
inputPlaceholder="添加分组"
selectPlaceholder="选择分组名"
>
</custom-select>
</a-form-item>
<a-form-item label="节点状态" prop="openStatus">
<a-switch :checked="temp.openStatus == 1" @change="
(checked) => {
temp.openStatus = checked ? 1 : 0
}
" checked-children="启用" un-checked-children="停用" default-checked />
<a-switch
:checked="temp.openStatus == 1"
@change="
(checked) => {
temp.openStatus = checked ? 1 : 0
}
"
checked-children="启用"
un-checked-children="停用"
default-checked
/>
</a-form-item>
<a-form-item label="绑定 SSH " prop="sshId">
<a-select show-search option-filter-prop="children" v-model="temp.sshId" placeholder="请选择SSH">
@ -386,35 +519,59 @@
</a-form>
</a-modal>
<!-- 管理节点 -->
<a-drawer destroyOnClose :title="`${temp.name}`" placement="right"
:width="`${this.getCollapsed ? 'calc(100vw - 80px)' : 'calc(100vw - 200px)'}`" :visible="drawerVisible"
@close="onClose">
<a-drawer
destroyOnClose
:title="`${temp.name}`"
placement="right"
:width="`${this.getCollapsed ? 'calc(100vw - 80px)' : 'calc(100vw - 200px)'}`"
:visible="drawerVisible"
@close="onClose"
>
<!-- 节点管理组件 -->
<node-layout v-if="drawerVisible" :node="temp" />
</a-drawer>
<!-- Terminal -->
<a-modal v-model="terminalVisible" :bodyStyle="{
padding: '0px 10px',
paddingTop: '10px',
marginRight: '10px',
height: `70vh`
}" width="80%" title="Terminal" :footer="null" :maskClosable="false">
<a-modal
v-model="terminalVisible"
:bodyStyle="{
padding: '0px 10px',
paddingTop: '10px',
marginRight: '10px',
height: `70vh`
}"
width="80%"
title="Terminal"
:footer="null"
:maskClosable="false"
>
<terminal v-if="terminalVisible" :sshId="temp.sshId" :nodeId="temp.id" />
</a-modal>
<!-- 快速安装插件端 -->
<a-modal destroyOnClose v-model="fastInstallNode" width="80%" title="快速安装插件端" :footer="null" :maskClosable="false"
<a-modal
destroyOnClose
v-model="fastInstallNode"
width="80%"
title="快速安装插件端"
:footer="null"
:maskClosable="false"
@cancel="
() => {
fastInstallNode.value = false
loadData()
}
">
"
>
<fastInstall v-if="fastInstallNode"></fastInstall>
</a-modal>
<!-- 同步到其他工作空间 -->
<a-modal destroyOnClose v-model="syncToWorkspaceVisible" title="同步到其他工作空间" @ok="handleSyncToWorkspace"
:maskClosable="false">
<a-modal
destroyOnClose
v-model="syncToWorkspaceVisible"
title="同步到其他工作空间"
@ok="handleSyncToWorkspace"
:maskClosable="false"
>
<a-alert message="温馨提示" type="warning">
<template slot="description">
<ul>
@ -436,8 +593,14 @@
</a-form>
</a-modal>
<!-- 历史监控 -->
<a-modal destroyOnClose v-model="monitorVisible" width="75%" :title="`${temp.name}历史监控图表`" :footer="null"
:maskClosable="false">
<a-modal
destroyOnClose
v-model="monitorVisible"
width="75%"
:title="`${temp.name}历史监控图表`"
:footer="null"
:maskClosable="false"
>
<node-top v-if="monitorVisible" :type="temp.type" :nodeId="temp.id"></node-top>
</a-modal>
</div>
@ -595,7 +758,6 @@ const rules = {
const workspaceList = ref([])
const pagination = computed(() => {
return COMPUTED_PAGINATION(listQuery.value)
})
@ -620,7 +782,6 @@ const useSuggestions = computed(() => {
return dictOrigin.length === 0
})
const tableSelections = ref([])
const rowSelection = computed(() => {
return {
@ -630,8 +791,6 @@ const rowSelection = computed(() => {
}
})
onMounted(() => {
const searchNodeName = route.query.searchNodeName
if (searchNodeName) {
@ -641,7 +800,6 @@ onMounted(() => {
loadGroupList()
})
//
const groupList = ref([])
const loadGroupList = () => {
@ -652,7 +810,6 @@ const loadGroupList = () => {
})
}
// SSH
const sshList = ref([])
const loadSshList = () => {
@ -721,7 +878,7 @@ const handleEdit = (record: any) => {
}
//
const editNodeForm = ref<FormInstance>();
const editNodeForm = ref<FormInstance>()
const handleEditNodeOk = () => {
//
editNodeForm.value?.validate().then((valid) => {
@ -941,31 +1098,24 @@ const handleHistory = (record, type) => {
temp.value = { ...temp.value, type }
}
const fastInstallNodeShow = () => {
fastInstallNode.value = true
}
// export default {
// computed: {
// ...mapGetters(['getCollapsed', 'getWorkspaceId', 'getUserInfo']),
// },
// computed: {
// ...mapGetters(['getCollapsed', 'getWorkspaceId', 'getUserInfo']),
// },
// methods: {
// formatDuration,
// renderSize,
// PAGE_DEFAULT_SHOW_TOTAL,
// parseTime,
// CHANGE_PAGE,
// methods: {
// formatDuration,
// renderSize,
// PAGE_DEFAULT_SHOW_TOTAL,
// parseTime,
// CHANGE_PAGE,
// }
// }
// }
</script>
<style scoped lang="less">

View File

@ -73,7 +73,7 @@
</ul>
</div>
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</a-space>
</template>

View File

@ -47,7 +47,7 @@
</ul>
</div>
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</a-space>
</template>

View File

@ -78,7 +78,7 @@
<template slot="title">
<div>状态数据是异步获取有一定时间延迟</div>
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</a-space>
</template>
@ -298,7 +298,7 @@
<li><b>File</b> 项目为静态文件夹,没有项目状态以及控制等功能</li>
</ul>
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-select v-model="temp.runMode" placeholder="请选择运行方式">
@ -317,7 +317,7 @@
<li>项目文件会存放到 <br />&nbsp;&nbsp;<b>项目白名单路径+项目文件夹</b></li>
</ul>
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-input-group compact>
@ -339,7 +339,7 @@
<template slot="title">
<ul></ul>
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
</a-form-item> -->
@ -362,7 +362,7 @@
</p>
<p>配置详情请参考配置示例</p>
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-tabs>
@ -395,7 +395,7 @@
<li>可选择的列表和项目白名单目录是一致的即相同配置</li>
</ul>
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-select v-model="temp.logPath" placeholder="请选择项目白名单路径">
@ -440,7 +440,7 @@
副本
<a-tooltip v-show="temp.type !== 'edit'">
<template slot="title"> 副本是指同一个项目在一个节点服务器中运行多份 </template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-collapse v-if="temp.javaCopyItemList && temp.javaCopyItemList.length">
@ -496,7 +496,7 @@
自启动
<a-tooltip v-show="temp.type !== 'edit'">
<template slot="title">插件端启动的时候检查项目状态如果项目状态是未运行则尝试执行启动项目</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-switch v-model="temp.autoStart" checked-children="" un-checked-children="" />
@ -512,7 +512,7 @@
<li>type 的值有stopbeforeStopstartbeforeRestartfileChange</li>
</ul>
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-input v-model="temp.token" placeholder="项目启动,停止,重启都将请求对应的地址,非必填GET请求" />

View File

@ -44,7 +44,7 @@
</ul>
</div>
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
<a-tooltip placement="topLeft" title="清除服务端缓存节点所有的脚步模版信息, 需要重新同步">

View File

@ -75,7 +75,7 @@
</ul>
</div>
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</a-space>
</template>

View File

@ -36,7 +36,7 @@
</ul>
</div>
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
<a-col :span="3" class="header-statistic">
<a-statistic-countdown format="s 秒" title="刷新倒计时 " :value="deadline" @finish="onFinish" />

View File

@ -139,7 +139,7 @@
账号
<a-tooltip v-if="!temp.id">
<template slot="title"> 账号支持引用工作空间变量<b>$ref.wEnv.xxxx</b> xxxx 为变量名称</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-input v-model="temp.userName" placeholder="登录用户">
@ -158,7 +158,7 @@
密码
<a-tooltip v-if="!temp.id">
<template slot="title"> 密码支持引用工作空间变量<b>$ref.wEnv.xxxx</b> xxxx 为变量名称</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-input-password v-if="temp.id === undefined" v-model="temp.password" placeholder="登录密码">
@ -188,7 +188,7 @@
密码
<a-tooltip v-if="!temp.id">
<template slot="title"> 密码支持引用工作空间变量<b>$ref.wEnv.xxxx</b> xxxx 为变量名称</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-input-password v-model="temp.password" placeholder="证书密码">
@ -240,7 +240,7 @@
隐藏字段
<a-tooltip>
<template slot="title"> 密码字段和私钥字段在编辑的时候不会返回如果需要重置或者清空就请点我 </template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-button style="margin-left: 10px" type="danger" @click="restHideField(temp)">清除</a-button>

View File

@ -62,7 +62,7 @@
</ul>
</div>
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</a-space>
</template>
@ -207,7 +207,7 @@
分发节点
<a-tooltip v-show="!temp.id">
<template slot="title"> 分发节点是指在编辑完脚本后自动将脚本内容同步节点的脚本中 </template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-select

View File

@ -65,7 +65,7 @@
</ul>
</div>
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</a-space>
</template>
@ -111,7 +111,7 @@
<li>可以引用工作空间的环境变量 变量占位符 ${xxxx} xxxx 为变量名称</li>
</ul>
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<div style="height: 40vh; overflow-y: scroll">

View File

@ -59,7 +59,7 @@
</ul>
</div>
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</a-space>
</template>

View File

@ -30,9 +30,7 @@
批量分配</a-button
>
<a-tooltip title="自动检测服务端所在服务器中是否存在 docker如果存在将自动添加到列表中">
<a-button type="dashed" @click="handleTryLocalDocker">
<a-icon type="question-circle" theme="filled" />自动探测
</a-button>
<a-button type="dashed" @click="handleTryLocalDocker"> <question-circle-filled />自动探测 </a-button>
</a-tooltip>
</a-space>
</template>

View File

@ -72,7 +72,7 @@
<li>节点地址为插件端的 IP:PORT 插件端端口默认为2123</li>
</ul>
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</a-space>
</template>
@ -278,7 +278,7 @@
<li>如果插件端正常运行但是连接失败请检查端口是否开放,防火墙规则,云服务器的安全组入站规则</li>
</ul>
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-input v-model="temp.jpomUrl" placeholder="节点地址 (127.0.0.1:2123)">
@ -306,7 +306,7 @@
节点账号密码默认由系统生成可以通过插件端数据目录下 agent_authorize.json
文件查看如果自定义配置了账号密码将没有此文件
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-input-password v-model="temp.jpomPassword" placeholder="节点密码,请查看节点启动输出的信息" />

View File

@ -75,7 +75,7 @@
</ul>
</div>
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</a-space>
</template>
@ -223,7 +223,7 @@
用户名
<a-tooltip v-if="!temp.id">
<template slot="title"> 账号支持引用工作空间变量<b>$ref.wEnv.xxxx</b> xxxx 为变量名称</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-input v-model="temp.user" placeholder="用户">
@ -248,7 +248,7 @@
密码
<a-tooltip v-if="!temp.id">
<template slot="title"> 密码支持引用工作空间变量<b>$ref.wEnv.xxxx</b> xxxx 为变量名称</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-input-password
@ -263,7 +263,7 @@
<template slot="title"
>不填将使用默认的 $HOME/.ssh 目录中的配置,使用优先级是id_dsa>id_rsa>identity
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
@ -409,7 +409,7 @@
文件目录
<a-tooltip>
<template slot="title"> 绑定指定目录可以在线管理同时构建 ssh 发布目录也需要在此配置 </template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-textarea
@ -439,7 +439,7 @@
<li>其他用户可以配置权限解除限制</li>
</ul>
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-textarea

View File

@ -23,7 +23,7 @@
<li>数据目录大小包含临时文件在线构建文件数据库文件等</li>
</ul>
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</span>
</a-timeline-item>
@ -51,7 +51,7 @@
</li>
</ul>
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</span>
</a-timeline-item>

View File

@ -85,7 +85,7 @@
隐私变量是指一些密码字段或者关键密钥等重要信息隐私字段只能修改不能查看编辑弹窗中无法看到对应值
隐私字段一旦创建后将不能切换为非隐私字段
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-switch
@ -105,7 +105,7 @@
分发节点
<a-tooltip v-show="!envTemp.id">
<template slot="title"> 分发节点是指将变量同步到对应节点在节点脚本中也可以使用当前变量</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-select

View File

@ -31,7 +31,7 @@
<li>工作空间环境变量用于构建命令相关</li>
</ul>
</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</a-space>
</template>

View File

@ -133,7 +133,7 @@
管理员
<a-tooltip v-if="createOption">
<template slot="title"> 管理员拥有管理服务端的部分权限 </template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<a-row>

View File

@ -45,7 +45,7 @@
工作空间
<a-tooltip v-if="!temp.id">
<template slot="title"> 配置工作空间权限,用户限制用户只能对应的工作空间里面操作对应的功能</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<transfer ref="transferRef" :tree-data="workspaceList" :editKey="temp.targetKeys" />
@ -55,7 +55,7 @@
禁用时段
<a-tooltip v-if="!temp.id">
<template slot="title"> 配置后可以控制想要在某个时间段禁止用户操作某些功能优先判断禁用时段</template>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<div v-for="(item, index) in temp.prohibitExecuteArray" :key="item.key">
@ -121,7 +121,7 @@
<template slot="title">
优先判断禁用时段,再判断允许时段配置允许时段后用户只能在对应的时段执行相应功能的操作</template
>
<a-icon type="question-circle" theme="filled" />
<question-circle-filled />
</a-tooltip>
</template>
<div v-for="(item, index) in temp.allowExecuteArray" :key="item.key">