mirror of
https://gitee.com/dromara/Jpom.git
synced 2024-12-01 19:38:09 +08:00
🚀 feat(server): SSH 脚本支持引用全局脚本库
This commit is contained in:
parent
3cfc8e8c05
commit
5741243777
@ -4,7 +4,7 @@
|
||||
|
||||
### 🐣 新增功能
|
||||
|
||||
1. 【server】新增 服务端脚本支持引用全局脚本库(`G@("xx")` xx 为脚本标记)
|
||||
1. 【server】新增 服务端脚本、SSH 脚本支持引用全局脚本库(`G@("xx")` xx 为脚本标记)
|
||||
|
||||
### 🐞 解决BUG、优化功能
|
||||
|
||||
|
@ -9,7 +9,6 @@
|
||||
*/
|
||||
package org.dromara.jpom.service.node.ssh;
|
||||
|
||||
import cn.hutool.core.thread.ThreadUtil;
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
@ -24,6 +23,7 @@ import org.dromara.jpom.common.i18n.I18nMessageUtil;
|
||||
import org.dromara.jpom.common.i18n.I18nThreadUtil;
|
||||
import org.dromara.jpom.cron.CronUtils;
|
||||
import org.dromara.jpom.func.assets.model.MachineSshModel;
|
||||
import org.dromara.jpom.func.assets.server.ScriptLibraryServer;
|
||||
import org.dromara.jpom.model.EnvironmentMapBuilder;
|
||||
import org.dromara.jpom.model.data.CommandExecLogModel;
|
||||
import org.dromara.jpom.model.data.CommandModel;
|
||||
@ -60,15 +60,18 @@ public class SshCommandService extends BaseWorkspaceService<CommandModel> implem
|
||||
private final SshService sshService;
|
||||
private final CommandExecLogService commandExecLogService;
|
||||
private final WorkspaceEnvVarService workspaceEnvVarService;
|
||||
private final ScriptLibraryServer scriptLibraryServer;
|
||||
|
||||
private static final byte[] LINE_BYTES = SystemUtil.getOsInfo().getLineSeparator().getBytes(CharsetUtil.CHARSET_UTF_8);
|
||||
|
||||
public SshCommandService(SshService sshService,
|
||||
CommandExecLogService commandExecLogService,
|
||||
WorkspaceEnvVarService workspaceEnvVarService) {
|
||||
WorkspaceEnvVarService workspaceEnvVarService,
|
||||
ScriptLibraryServer scriptLibraryServer) {
|
||||
this.sshService = sshService;
|
||||
this.commandExecLogService = commandExecLogService;
|
||||
this.workspaceEnvVarService = workspaceEnvVarService;
|
||||
this.scriptLibraryServer = scriptLibraryServer;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -273,7 +276,8 @@ public class SshCommandService extends BaseWorkspaceService<CommandModel> implem
|
||||
environmentMapBuilder.eachStr(logRecorder::system);
|
||||
Map<String, String> environment = environmentMapBuilder.environment();
|
||||
String commands = StringUtil.formatStrByMap(commandModel.getCommand(), environment);
|
||||
|
||||
// 替换全局脚本
|
||||
commands = scriptLibraryServer.referenceReplace(commands);
|
||||
MachineSshModel machineSshModel = sshService.getMachineSshModel(sshModel);
|
||||
//
|
||||
Session session = null;
|
||||
|
@ -108,6 +108,7 @@ public class ScriptExecuteLogServer extends BaseGlobalOrWorkspaceService<ScriptE
|
||||
InputStream templateInputStream = ExtConfigBean.getConfigResourceInputStream("/exec/template." + CommandUtil.SUFFIX);
|
||||
String defaultTemplate = IoUtil.readUtf8(templateInputStream);
|
||||
String context = defaultTemplate + scriptModel.getContext();
|
||||
// 替换全局变量
|
||||
context = scriptLibraryServer.referenceReplace(context);
|
||||
//
|
||||
String dataPath = jpomApplication.getDataPath();
|
||||
|
36
web-vue/src/components/customDrawer/index.vue
Normal file
36
web-vue/src/components/customDrawer/index.vue
Normal file
@ -0,0 +1,36 @@
|
||||
<template>
|
||||
<a-drawer v-bind="props" :root-style="rootStyle">
|
||||
<slot name="default"></slot>
|
||||
<template v-if="slots.footer" #footer>
|
||||
<slot name="footer"></slot>
|
||||
</template>
|
||||
<template v-if="slots.extra" #extra>
|
||||
<slot name="extra"></slot>
|
||||
</template>
|
||||
</a-drawer>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { drawerProps } from 'ant-design-vue/es/drawer'
|
||||
import { initDefaultProps } from 'ant-design-vue/es/_util/props-util'
|
||||
import { CustomSlotsType } from 'ant-design-vue/es/_util/type'
|
||||
import { CSSProperties, defineComponent } from 'vue'
|
||||
import { increaseZIndex } from '@/utils/utils'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'CustomDrawer',
|
||||
props: initDefaultProps(drawerProps(), {}),
|
||||
slots: Object as CustomSlotsType<{ default: any; footer?: any; extra?: any }>,
|
||||
setup(props, { emit, slots }) {
|
||||
const rootStyle: CSSProperties = {
|
||||
zIndex: increaseZIndex(),
|
||||
...props.rootStyle
|
||||
}
|
||||
return {
|
||||
props,
|
||||
rootStyle,
|
||||
emit,
|
||||
slots
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
@ -430,7 +430,7 @@
|
||||
"
|
||||
@tag-confirm="
|
||||
(tag) => {
|
||||
temp = { ...temp, context: temp.context + `\nG@(\"${tag}\")` }
|
||||
temp = { ...temp, context: (temp.context || '') + `\nG@(\"${tag}\")` }
|
||||
scriptLibraryVisible = false
|
||||
}
|
||||
"
|
||||
|
@ -114,7 +114,8 @@
|
||||
</template>
|
||||
</CustomTable>
|
||||
<!-- 编辑命令 -->
|
||||
<a-modal
|
||||
<CustomModal
|
||||
v-if="editCommandVisible"
|
||||
v-model:open="editCommandVisible"
|
||||
destroy-on-close
|
||||
width="80vw"
|
||||
@ -146,7 +147,12 @@
|
||||
v-model:content="temp.command"
|
||||
height="40vh"
|
||||
:options="{ mode: 'shell', tabSize: 2 }"
|
||||
></code-editor>
|
||||
:show-tool="true"
|
||||
>
|
||||
<template #tool_before>
|
||||
<a-button type="link" @click="scriptLibraryVisible = true">脚本库 </a-button>
|
||||
</template>
|
||||
</code-editor>
|
||||
</a-form-item-rest>
|
||||
</a-form-item>
|
||||
<a-form-item :label="$t('pages.ssh.command.9266c899')">
|
||||
@ -228,7 +234,7 @@
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</CustomModal>
|
||||
|
||||
<a-modal
|
||||
v-model:open="executeCommandVisible"
|
||||
@ -417,6 +423,71 @@
|
||||
</a-tabs>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
<!-- 查看脚本库 -->
|
||||
<CustomDrawer
|
||||
v-if="scriptLibraryVisible"
|
||||
destroy-on-close
|
||||
title="查看脚本库"
|
||||
placement="right"
|
||||
:open="scriptLibraryVisible"
|
||||
width="85vw"
|
||||
:footer-style="{ textAlign: 'right' }"
|
||||
@close="
|
||||
() => {
|
||||
scriptLibraryVisible = false
|
||||
}
|
||||
"
|
||||
>
|
||||
<ScriptLibraryNoPermission
|
||||
v-if="scriptLibraryVisible"
|
||||
ref="scriptLibraryRef"
|
||||
@script-confirm="
|
||||
(script) => {
|
||||
temp = { ...temp, command: script }
|
||||
scriptLibraryVisible = false
|
||||
}
|
||||
"
|
||||
@tag-confirm="
|
||||
(tag) => {
|
||||
temp = { ...temp, command: (temp.command || '') + `\nG@(\"${tag}\")` }
|
||||
scriptLibraryVisible = false
|
||||
}
|
||||
"
|
||||
></ScriptLibraryNoPermission>
|
||||
<template #footer>
|
||||
<a-space>
|
||||
<a-button
|
||||
@click="
|
||||
() => {
|
||||
scriptLibraryVisible = false
|
||||
}
|
||||
"
|
||||
>
|
||||
取消
|
||||
</a-button>
|
||||
<a-button
|
||||
type="primary"
|
||||
@click="
|
||||
() => {
|
||||
$refs['scriptLibraryRef'].handerScriptConfirm()
|
||||
}
|
||||
"
|
||||
>
|
||||
替换引用
|
||||
</a-button>
|
||||
<a-button
|
||||
type="primary"
|
||||
@click="
|
||||
() => {
|
||||
$refs['scriptLibraryRef'].handerTagConfirm()
|
||||
}
|
||||
"
|
||||
>
|
||||
标记引用
|
||||
</a-button>
|
||||
</a-space>
|
||||
</template>
|
||||
</CustomDrawer>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
@ -426,12 +497,12 @@ import { CRON_DATA_SOURCE } from '@/utils/const-i18n'
|
||||
import { getSshListAll } from '@/api/ssh'
|
||||
import codeEditor from '@/components/codeEditor'
|
||||
import CommandLog from './command-view-log'
|
||||
|
||||
import ScriptLibraryNoPermission from '@/pages/system/assets/script-library/no-permission'
|
||||
import { getWorkSpaceListAll } from '@/api/workspace'
|
||||
import { mapState } from 'pinia'
|
||||
import { useAppStore } from '@/stores/app'
|
||||
export default {
|
||||
components: { codeEditor, CommandLog },
|
||||
components: { codeEditor, CommandLog, ScriptLibraryNoPermission },
|
||||
data() {
|
||||
return {
|
||||
listQuery: Object.assign({}, PAGE_DEFAULT_LIST_QUERY),
|
||||
@ -503,7 +574,7 @@ export default {
|
||||
width: '240px'
|
||||
}
|
||||
],
|
||||
|
||||
scriptLibraryVisible: false,
|
||||
tableSelections: [],
|
||||
syncToWorkspaceVisible: false,
|
||||
workspaceList: [],
|
||||
|
277
web-vue/src/pages/system/assets/script-library/no-permission.vue
Normal file
277
web-vue/src/pages/system/assets/script-library/no-permission.vue
Normal file
@ -0,0 +1,277 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- 数据表格 -->
|
||||
<CustomTable
|
||||
is-show-tools
|
||||
default-auto-refresh
|
||||
:auto-refresh-time="30"
|
||||
:active-page="activePage"
|
||||
table-name="script-library-no-permission"
|
||||
empty-description="没有任何脚本库"
|
||||
:data-source="list"
|
||||
size="middle"
|
||||
:columns="columns"
|
||||
:pagination="pagination"
|
||||
bordered
|
||||
row-key="id"
|
||||
:scroll="{
|
||||
x: 'max-content'
|
||||
}"
|
||||
:row-selection="rowSelection"
|
||||
@change="changePage"
|
||||
@refresh="loadData"
|
||||
>
|
||||
<template #title>
|
||||
<a-space wrap class="search-box">
|
||||
<a-input
|
||||
v-model:value="listQuery['%tag%']"
|
||||
placeholder="脚本标记"
|
||||
allow-clear
|
||||
class="search-input-item"
|
||||
@press-enter="loadData"
|
||||
/>
|
||||
<a-input
|
||||
v-model:value="listQuery['%version%']"
|
||||
placeholder="版本"
|
||||
allow-clear
|
||||
class="search-input-item"
|
||||
@press-enter="loadData"
|
||||
/>
|
||||
<a-input
|
||||
v-model:value="listQuery['%description%']"
|
||||
placeholder="描述"
|
||||
class="search-input-item"
|
||||
@press-enter="loadData"
|
||||
/>
|
||||
|
||||
<a-tooltip title="按住 Ctr 或者 Alt/Option 键点击按钮快速回到第一页">
|
||||
<a-button :loading="loading" type="primary" @click="loadData">搜索</a-button>
|
||||
</a-tooltip>
|
||||
</a-space>
|
||||
</template>
|
||||
|
||||
<template #tableBodyCell="{ column, text, record }">
|
||||
<template v-if="column.dataIndex === 'nodeId'">
|
||||
<a-tooltip placement="topLeft" :title="text">
|
||||
<span>{{ nodeMap[text] }}</span>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-else-if="column.tooltip">
|
||||
<a-tooltip placement="topLeft" :title="text">
|
||||
<span>{{ text }}</span>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
|
||||
<template v-else-if="column.dataIndex === 'operation'">
|
||||
<a-space>
|
||||
<a-button size="small" type="primary" @click="handleEdit(record)"> 查看</a-button>
|
||||
</a-space>
|
||||
</template>
|
||||
</template>
|
||||
</CustomTable>
|
||||
<!-- pages.system.assets.script-library.ad207008区 -->
|
||||
<CustomModal
|
||||
v-if="editScriptVisible"
|
||||
v-model:open="editScriptVisible"
|
||||
destroy-on-close
|
||||
title="查看脚本"
|
||||
:mask-closable="false"
|
||||
width="80vw"
|
||||
:footer="false"
|
||||
>
|
||||
<a-form ref="editScriptForm" :rules="rules" :model="temp" :label-col="{ span: 3 }" :wrapper-col="{ span: 19 }">
|
||||
<a-form-item label="版本" name="id">
|
||||
<a-input v-model:value="temp.version" disabled read-only />
|
||||
</a-form-item>
|
||||
<a-form-item label="标记" name="tag">
|
||||
<a-input v-model:value="temp.tag" :max-length="50" disabled />
|
||||
</a-form-item>
|
||||
<a-form-item label="内容" name="script">
|
||||
<a-form-item-rest>
|
||||
<code-editor
|
||||
v-model:content="temp.script"
|
||||
:show-tool="true"
|
||||
height="40vh"
|
||||
:options="{ mode: 'shell', tabSize: 2, readOnly: true }"
|
||||
>
|
||||
</code-editor>
|
||||
</a-form-item-rest>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="描述" name="description">
|
||||
<a-textarea v-model:value="temp.description" :max-length="200" :rows="3" style="resize: none" disabled />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</CustomModal>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { getScriptLibraryList } from '@/api/system/script-library'
|
||||
import codeEditor from '@/components/codeEditor'
|
||||
|
||||
import { CRON_DATA_SOURCE } from '@/utils/const-i18n'
|
||||
import { CHANGE_PAGE, COMPUTED_PAGINATION, PAGE_DEFAULT_LIST_QUERY, parseTime } from '@/utils/const'
|
||||
import { increaseZIndex } from '@/utils/utils'
|
||||
// import { getWorkSpaceListAll } from '@/api/workspace'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
codeEditor
|
||||
},
|
||||
props: {},
|
||||
emits: ['scriptConfirm', 'tagConfirm'],
|
||||
|
||||
data() {
|
||||
return {
|
||||
// choose: this.choose,
|
||||
loading: false,
|
||||
listQuery: Object.assign({}, PAGE_DEFAULT_LIST_QUERY),
|
||||
CRON_DATA_SOURCE,
|
||||
list: [],
|
||||
temp: {},
|
||||
nodeList: [],
|
||||
editScriptVisible: false,
|
||||
drawerTitle: '',
|
||||
drawerConsoleVisible: false,
|
||||
columns: [
|
||||
{
|
||||
title: '标记',
|
||||
dataIndex: 'tag',
|
||||
ellipsis: true,
|
||||
sorter: true,
|
||||
width: 150
|
||||
},
|
||||
{
|
||||
title: '版本',
|
||||
dataIndex: 'version',
|
||||
ellipsis: true,
|
||||
sorter: true,
|
||||
width: '100px',
|
||||
tooltip: true
|
||||
},
|
||||
{
|
||||
title: '描述',
|
||||
dataIndex: 'description',
|
||||
ellipsis: true,
|
||||
width: 200,
|
||||
tooltip: true
|
||||
},
|
||||
{
|
||||
title: '修改时间',
|
||||
dataIndex: 'modifyTimeMillis',
|
||||
sorter: true,
|
||||
width: '170px',
|
||||
ellipsis: true,
|
||||
customRender: ({ text }) => parseTime(text)
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
dataIndex: 'createTimeMillis',
|
||||
sorter: true,
|
||||
width: '170px',
|
||||
ellipsis: true,
|
||||
customRender: ({ text }) => parseTime(text)
|
||||
},
|
||||
{
|
||||
title: '创建人',
|
||||
dataIndex: 'createUser',
|
||||
ellipsis: true,
|
||||
tooltip: true,
|
||||
width: '120px'
|
||||
},
|
||||
{
|
||||
title: '修改人',
|
||||
dataIndex: 'modifyUser',
|
||||
ellipsis: true,
|
||||
tooltip: true,
|
||||
width: '120px'
|
||||
},
|
||||
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'operation',
|
||||
align: 'center',
|
||||
|
||||
fixed: 'right',
|
||||
width: '140px'
|
||||
}
|
||||
],
|
||||
tableSelections: [],
|
||||
selectedRowKeys: [],
|
||||
rules: {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
pagination() {
|
||||
return COMPUTED_PAGINATION(this.listQuery)
|
||||
},
|
||||
activePage() {
|
||||
return this.$attrs.routerUrl === this.$route.path
|
||||
},
|
||||
rowSelection() {
|
||||
return {
|
||||
onChange: (selectedRowKeys) => {
|
||||
this.tableSelections = selectedRowKeys
|
||||
},
|
||||
selectedRowKeys: this.tableSelections,
|
||||
type: 'radio'
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {},
|
||||
created() {},
|
||||
mounted() {
|
||||
this.loadData()
|
||||
},
|
||||
methods: {
|
||||
increaseZIndex,
|
||||
// 加载数据
|
||||
loadData(pointerEvent) {
|
||||
this.listQuery.page = pointerEvent?.altKey || pointerEvent?.ctrlKey ? 1 : this.listQuery.page
|
||||
this.loading = true
|
||||
getScriptLibraryList(this.listQuery).then((res) => {
|
||||
if (res.code === 200) {
|
||||
this.list = res.data.result
|
||||
this.listQuery.total = res.data.total
|
||||
}
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
parseTime,
|
||||
// 修改
|
||||
handleEdit(record) {
|
||||
this.temp = Object.assign({}, record)
|
||||
this.editScriptVisible = true
|
||||
},
|
||||
// 分页、排序、筛选变化时触发
|
||||
changePage(pagination, filters, sorter) {
|
||||
this.listQuery = CHANGE_PAGE(this.listQuery, { pagination, sorter })
|
||||
this.loadData()
|
||||
},
|
||||
handerScriptConfirm() {
|
||||
if (!this.tableSelections.length) {
|
||||
$notification.warning({
|
||||
message: '请选择要引用的脚本'
|
||||
})
|
||||
return
|
||||
}
|
||||
const selectData = this.list.filter((item) => {
|
||||
return item.id === this.tableSelections[0]
|
||||
})?.[0]
|
||||
this.$emit('scriptConfirm', `${selectData.script}`)
|
||||
},
|
||||
handerTagConfirm() {
|
||||
if (!this.tableSelections.length) {
|
||||
$notification.warning({
|
||||
message: '请选择要引用的脚本'
|
||||
})
|
||||
return
|
||||
}
|
||||
const selectData = this.list.filter((item) => {
|
||||
return item.id === this.tableSelections[0]
|
||||
})?.[0]
|
||||
this.$emit('tagConfirm', `${selectData.tag}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@ -0,0 +1,386 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- 数据表格 -->
|
||||
<CustomTable
|
||||
is-show-tools
|
||||
default-auto-refresh
|
||||
:auto-refresh-time="30"
|
||||
:active-page="activePage"
|
||||
table-name="script-library"
|
||||
:empty-description="$t('pages.system.assets.script-library.65418a5e')"
|
||||
:data-source="list"
|
||||
size="middle"
|
||||
:columns="columns"
|
||||
:pagination="pagination"
|
||||
bordered
|
||||
row-key="id"
|
||||
:scroll="{
|
||||
x: 'max-content'
|
||||
}"
|
||||
@change="changePage"
|
||||
@refresh="loadData"
|
||||
>
|
||||
<template #title>
|
||||
<a-space wrap class="search-box">
|
||||
<a-input
|
||||
v-model:value="listQuery['%tag%']"
|
||||
:placeholder="$t('pages.system.assets.script-library.95547f9')"
|
||||
allow-clear
|
||||
class="search-input-item"
|
||||
@press-enter="loadData"
|
||||
/>
|
||||
<a-input
|
||||
v-model:value="listQuery['%version%']"
|
||||
:placeholder="$t('pages.system.assets.script-library.81634069')"
|
||||
allow-clear
|
||||
class="search-input-item"
|
||||
@press-enter="loadData"
|
||||
/>
|
||||
<a-input
|
||||
v-model:value="listQuery['%description%']"
|
||||
:placeholder="$t('pages.system.assets.script-library.f89e58f1')"
|
||||
class="search-input-item"
|
||||
@press-enter="loadData"
|
||||
/>
|
||||
|
||||
<a-tooltip :title="$t('pages.system.assets.script-library.986e8dc2')">
|
||||
<a-button :loading="loading" type="primary" @click="loadData">{{
|
||||
$t('pages.system.assets.script-library.43934f6d')
|
||||
}}</a-button>
|
||||
</a-tooltip>
|
||||
<a-button type="primary" @click="createScript">{{
|
||||
$t('pages.system.assets.script-library.9f3089ce')
|
||||
}}</a-button>
|
||||
</a-space>
|
||||
</template>
|
||||
<template #tableHelp>
|
||||
<a-tooltip>
|
||||
<template #title>
|
||||
<div>{{ $t('pages.system.assets.script-library.41c0cbe5') }}</div>
|
||||
|
||||
<div>
|
||||
<ul>
|
||||
<li>{{ $t('pages.system.assets.script-library.423e1405') }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
<QuestionCircleOutlined />
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template #tableBodyCell="{ column, text, record }">
|
||||
<template v-if="column.dataIndex === 'nodeId'">
|
||||
<a-tooltip placement="topLeft" :title="text">
|
||||
<span>{{ nodeMap[text] }}</span>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-else-if="column.tooltip">
|
||||
<a-tooltip placement="topLeft" :title="text">
|
||||
<span>{{ text }}</span>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
|
||||
<template v-else-if="column.dataIndex === 'operation'">
|
||||
<a-space>
|
||||
<a-button size="small" type="primary" @click="handleEdit(record)">{{
|
||||
$t('pages.system.assets.script-library.ad207008')
|
||||
}}</a-button>
|
||||
<a-button size="small" type="primary" danger @click="handleDelete(record)">{{
|
||||
$t('pages.system.assets.script-library.ecbd7449')
|
||||
}}</a-button>
|
||||
</a-space>
|
||||
</template>
|
||||
</template>
|
||||
</CustomTable>
|
||||
<!-- pages.system.assets.script-library.ad207008区 -->
|
||||
<CustomModal
|
||||
v-if="editScriptVisible"
|
||||
v-model:open="editScriptVisible"
|
||||
destroy-on-close
|
||||
:title="$t('pages.system.assets.script-library.16a6aab6')"
|
||||
:mask-closable="false"
|
||||
width="80vw"
|
||||
:confirm-loading="confirmLoading"
|
||||
@ok="handleEditScriptOk"
|
||||
>
|
||||
<a-form ref="editScriptForm" :rules="rules" :model="temp" :label-col="{ span: 3 }" :wrapper-col="{ span: 19 }">
|
||||
<a-form-item v-if="temp.id" :label="$t('pages.system.assets.script-library.81634069')" name="id">
|
||||
<a-input v-model:value="temp.version" disabled read-only />
|
||||
</a-form-item>
|
||||
<a-form-item :label="$t('pages.system.assets.script-library.2d62ebdb')" name="tag">
|
||||
<a-input
|
||||
v-model:value="temp.tag"
|
||||
:max-length="50"
|
||||
:placeholder="$t('pages.system.assets.script-library.e37b1ac9')"
|
||||
:disabled="!!temp.id"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item :label="$t('pages.system.assets.script-library.3e7aa0ad')" name="script">
|
||||
<a-form-item-rest>
|
||||
<code-editor
|
||||
v-model:content="temp.script"
|
||||
:show-tool="true"
|
||||
height="40vh"
|
||||
:options="{ mode: 'shell', tabSize: 2 }"
|
||||
>
|
||||
</code-editor>
|
||||
</a-form-item-rest>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item :label="$t('pages.system.assets.script-library.f89e58f1')" name="description">
|
||||
<a-textarea
|
||||
v-model:value="temp.description"
|
||||
:max-length="200"
|
||||
:rows="3"
|
||||
style="resize: none"
|
||||
:placeholder="$t('pages.system.assets.script-library.43075dd9')"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item>
|
||||
<template #label>
|
||||
<a-tooltip
|
||||
>{{ $t('pages.system.assets.script-library.4f5ca5e3')
|
||||
}}<template #title>{{ $t('pages.system.assets.script-library.33437c9b') }}</template>
|
||||
<QuestionCircleOutlined v-show="!temp.id" />
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template #help>{{ $t('pages.system.assets.script-library.5251812f') }}</template>
|
||||
<a-select
|
||||
v-model:value="temp.chooseNode"
|
||||
show-search
|
||||
:filter-option="false"
|
||||
:placeholder="$t('pages.system.assets.script-library.4722ff63')"
|
||||
mode="multiple"
|
||||
@search="searchMachineList"
|
||||
>
|
||||
<a-select-option v-for="item in nodeList" :key="item.id" :value="item.id">
|
||||
{{ item.name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</CustomModal>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { getScriptLibraryList, editScriptLibrary, delScriptLibrary } from '@/api/system/script-library'
|
||||
import codeEditor from '@/components/codeEditor'
|
||||
import { machineSearch } from '@/api/system/assets-machine'
|
||||
import { CRON_DATA_SOURCE } from '@/utils/const-i18n'
|
||||
import { CHANGE_PAGE, COMPUTED_PAGINATION, PAGE_DEFAULT_LIST_QUERY, parseTime } from '@/utils/const'
|
||||
|
||||
// import { getWorkSpaceListAll } from '@/api/workspace'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
codeEditor
|
||||
},
|
||||
props: {},
|
||||
|
||||
data() {
|
||||
return {
|
||||
// choose: this.choose,
|
||||
loading: false,
|
||||
listQuery: Object.assign({}, PAGE_DEFAULT_LIST_QUERY),
|
||||
CRON_DATA_SOURCE,
|
||||
list: [],
|
||||
temp: {},
|
||||
nodeList: [],
|
||||
editScriptVisible: false,
|
||||
drawerTitle: '',
|
||||
drawerConsoleVisible: false,
|
||||
columns: [
|
||||
{
|
||||
title: this.$t('pages.system.assets.script-library.2d62ebdb'),
|
||||
dataIndex: 'tag',
|
||||
ellipsis: true,
|
||||
sorter: true,
|
||||
width: 150
|
||||
},
|
||||
{
|
||||
title: this.$t('pages.system.assets.script-library.81634069'),
|
||||
dataIndex: 'version',
|
||||
ellipsis: true,
|
||||
sorter: true,
|
||||
width: '100px',
|
||||
tooltip: true
|
||||
},
|
||||
{
|
||||
title: this.$t('pages.system.assets.script-library.f89e58f1'),
|
||||
dataIndex: 'description',
|
||||
ellipsis: true,
|
||||
width: 200,
|
||||
tooltip: true
|
||||
},
|
||||
{
|
||||
title: this.$t('pages.system.assets.script-library.d3b29478'),
|
||||
dataIndex: 'modifyTimeMillis',
|
||||
sorter: true,
|
||||
width: '170px',
|
||||
ellipsis: true,
|
||||
customRender: ({ text }) => parseTime(text)
|
||||
},
|
||||
{
|
||||
title: this.$t('pages.system.assets.script-library.efaf9956'),
|
||||
dataIndex: 'createTimeMillis',
|
||||
sorter: true,
|
||||
width: '170px',
|
||||
ellipsis: true,
|
||||
customRender: ({ text }) => parseTime(text)
|
||||
},
|
||||
{
|
||||
title: this.$t('pages.system.assets.script-library.339d15b5'),
|
||||
dataIndex: 'createUser',
|
||||
ellipsis: true,
|
||||
tooltip: true,
|
||||
width: '120px'
|
||||
},
|
||||
{
|
||||
title: this.$t('pages.system.assets.script-library.8605b4f2'),
|
||||
dataIndex: 'modifyUser',
|
||||
ellipsis: true,
|
||||
tooltip: true,
|
||||
width: '120px'
|
||||
},
|
||||
|
||||
{
|
||||
title: this.$t('pages.system.assets.script-library.fe731dfc'),
|
||||
dataIndex: 'operation',
|
||||
align: 'center',
|
||||
|
||||
fixed: 'right',
|
||||
width: '140px'
|
||||
}
|
||||
],
|
||||
|
||||
rules: {
|
||||
// name: [{ required: true, message: this.$tl('p.inputScriptName'), trigger: 'blur' }],
|
||||
// context: [{ required: true, message: this.$tl('p.inputScriptContent'), trigger: 'blur' }]
|
||||
},
|
||||
confirmLoading: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
pagination() {
|
||||
return COMPUTED_PAGINATION(this.listQuery)
|
||||
},
|
||||
activePage() {
|
||||
return this.$attrs.routerUrl === this.$route.path
|
||||
}
|
||||
},
|
||||
watch: {},
|
||||
created() {
|
||||
// this.columns.push(
|
||||
// );
|
||||
},
|
||||
mounted() {
|
||||
// this.calcTableHeight();
|
||||
|
||||
this.loadData()
|
||||
},
|
||||
methods: {
|
||||
// 加载数据
|
||||
loadData(pointerEvent) {
|
||||
this.listQuery.page = pointerEvent?.altKey || pointerEvent?.ctrlKey ? 1 : this.listQuery.page
|
||||
this.loading = true
|
||||
getScriptLibraryList(this.listQuery).then((res) => {
|
||||
if (res.code === 200) {
|
||||
this.list = res.data.result
|
||||
this.listQuery.total = res.data.total
|
||||
}
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
parseTime,
|
||||
// 获取所有节点
|
||||
searchMachineList(name) {
|
||||
machineSearch({
|
||||
name: name,
|
||||
limit: 10,
|
||||
appendIds: this.temp.machineIds || ''
|
||||
}).then((res) => {
|
||||
this.nodeList = res.data || []
|
||||
})
|
||||
},
|
||||
createScript() {
|
||||
this.temp = {}
|
||||
|
||||
this.editScriptVisible = true
|
||||
this.searchMachineList()
|
||||
},
|
||||
// 修改
|
||||
handleEdit(record) {
|
||||
this.temp = Object.assign({}, record)
|
||||
|
||||
//this.commandParams = data?.defArgs ? JSON.parse(data.defArgs) : []
|
||||
|
||||
this.temp = {
|
||||
...this.temp,
|
||||
chooseNode: record?.machineIds ? record.machineIds.split(',') : []
|
||||
}
|
||||
this.editScriptVisible = true
|
||||
this.searchMachineList()
|
||||
// getScriptItem({
|
||||
// id: record.id
|
||||
// }).then((res) => {
|
||||
// if (res.code === 200) {
|
||||
// const data = res.data.data
|
||||
// }
|
||||
// })
|
||||
},
|
||||
// 提交 Script 数据
|
||||
handleEditScriptOk() {
|
||||
// 检验表单
|
||||
this.$refs['editScriptForm'].validate().then(() => {
|
||||
// 提交数据
|
||||
this.temp.machineIds = this.temp?.chooseNode?.join(',')
|
||||
delete this.temp.nodeList
|
||||
this.confirmLoading = true
|
||||
editScriptLibrary(this.temp)
|
||||
.then((res) => {
|
||||
if (res.code === 200) {
|
||||
// 成功
|
||||
$notification.success({
|
||||
message: res.msg
|
||||
})
|
||||
|
||||
this.editScriptVisible = false
|
||||
this.loadData()
|
||||
this.$refs['editScriptForm'].resetFields()
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.confirmLoading = false
|
||||
})
|
||||
})
|
||||
},
|
||||
handleDelete(record) {
|
||||
$confirm({
|
||||
title: this.$t('pages.system.assets.script-library.3875bf60'),
|
||||
content: this.$t('pages.system.assets.script-library.72df294d'),
|
||||
zIndex: 1009,
|
||||
okText: this.$t('pages.system.assets.script-library.d507abff'),
|
||||
cancelText: this.$t('pages.system.assets.script-library.a0451c97'),
|
||||
onOk: () => {
|
||||
return delScriptLibrary({
|
||||
id: record.id
|
||||
}).then((res) => {
|
||||
if (res.code === 200) {
|
||||
$notification.success({
|
||||
message: res.msg
|
||||
})
|
||||
this.loadData()
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 分页、排序、筛选变化时触发
|
||||
changePage(pagination, filters, sorter) {
|
||||
this.listQuery = CHANGE_PAGE(this.listQuery, { pagination, sorter })
|
||||
this.loadData()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
Loading…
Reference in New Issue
Block a user