mirror of
https://gitee.com/dromara/mayfly-go
synced 2025-11-03 07:50:25 +08:00
feat: 机器新增支持加密方法等
This commit is contained in:
@@ -11,7 +11,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@element-plus/icons-vue": "^2.3.1",
|
||||
"@vueuse/core": "^12.3.0",
|
||||
"@vueuse/core": "^12.4.0",
|
||||
"asciinema-player": "^3.8.1",
|
||||
"axios": "^1.6.2",
|
||||
"clipboard": "^2.0.11",
|
||||
@@ -19,7 +19,7 @@
|
||||
"crypto-js": "^4.2.0",
|
||||
"dayjs": "^1.11.13",
|
||||
"echarts": "^5.6.0",
|
||||
"element-plus": "^2.9.2",
|
||||
"element-plus": "^2.9.3",
|
||||
"js-base64": "^3.7.7",
|
||||
"jsencrypt": "^3.3.2",
|
||||
"lodash": "^4.17.21",
|
||||
@@ -60,8 +60,8 @@
|
||||
"eslint": "^8.35.0",
|
||||
"eslint-plugin-vue": "^9.31.0",
|
||||
"prettier": "^3.2.5",
|
||||
"sass": "^1.83.1",
|
||||
"typescript": "^5.7.2",
|
||||
"sass": "^1.83.4",
|
||||
"typescript": "^5.7.3",
|
||||
"vite": "^6.0.7",
|
||||
"vue-eslint-parser": "^9.4.3"
|
||||
},
|
||||
|
||||
1
frontend/src/assets/icon/menu/permission.svg
Normal file
1
frontend/src/assets/icon/menu/permission.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg t="1737075628303" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10200" width="48" height="48"><path d="M335.36 395.776c0 91.648 69.632 167.424 157.184 179.712v206.336c0 16.384 14.336 30.72 30.72 30.72s30.72-14.336 30.72-30.72v-91.648h71.68c16.384 0 30.72-14.336 30.72-30.72s-14.336-30.72-30.72-30.72h-71.68V573.44c81.92-16.384 144.896-89.6 144.896-177.664 0-99.84-81.92-181.76-181.76-181.76S335.36 295.424 335.36 395.776zM517.12 274.944c67.584 0 120.32 53.248 120.32 120.32 0 67.584-53.248 120.32-120.32 120.32S396.288 462.848 396.288 395.776 449.536 274.944 517.12 274.944z" p-id="10201"></path><path d="M900.608 152.576L522.752 30.208c-6.144-2.048-12.288-2.048-18.432 0L126.976 152.576c-12.288 4.096-20.48 16.384-20.48 28.672v477.696c2.048 16.384 24.576 159.232 396.288 332.8 4.096 2.048 8.192 2.048 12.288 2.048 4.096 0 8.192 0 12.288-2.048 369.664-173.568 394.24-316.416 396.288-332.8V181.248c-2.56-12.288-10.752-24.576-23.04-28.672z m-40.96 502.272c-2.048 10.24-36.864 126.464-347.136 275.456-312.32-148.992-345.088-265.216-347.136-275.456V203.776l347.136-114.176 347.136 114.176v451.072z" p-id="10202"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
1
frontend/src/assets/icon/menu/role.svg
Normal file
1
frontend/src/assets/icon/menu/role.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg t="1737074876174" class="icon" viewBox="0 0 1026 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8851" width="48" height="48"><path d="M392.92 608.306a224.526 224.526 0 1 1 224.527-224.527 224.526 224.526 0 0 1-224.526 224.527z m0-384.902a160.376 160.376 0 1 0 160.377 160.375A160.376 160.376 0 0 0 392.92 223.404z" p-id="8852"></path><path d="M713.673 864.907h-64.15a256.601 256.601 0 0 0-513.204 0H72.17a320.752 320.752 0 0 1 641.504 0zM665.56 576.231v-64.15a144.338 144.338 0 1 0-38.01-283.706l-16.839-61.905a208.489 208.489 0 1 1 54.849 409.76z" p-id="8853"></path><path d="M954.236 800.757h-64.15A224.526 224.526 0 0 0 665.56 576.23v-64.15a288.677 288.677 0 0 1 288.676 288.676z" p-id="8854"></path></svg>
|
||||
|
After Width: | Height: | Size: 728 B |
38
frontend/src/components/form/FormItemTooltip.vue
Normal file
38
frontend/src/components/form/FormItemTooltip.vue
Normal file
@@ -0,0 +1,38 @@
|
||||
<template>
|
||||
<el-form-item v-bind="$attrs">
|
||||
<template #label>
|
||||
{{ props.label }}
|
||||
|
||||
<el-tooltip :placement="props.placement">
|
||||
<template #content>
|
||||
<span v-html="props.tooltip"></span>
|
||||
</template>
|
||||
<SvgIcon name="QuestionFilled" />
|
||||
</el-tooltip>
|
||||
</template>
|
||||
|
||||
<!-- 遍历父组件传入的 solts 透传给子组件 -->
|
||||
<template v-for="(_, key) in useSlots()" v-slot:[key]>
|
||||
<slot :name="key"></slot>
|
||||
</template>
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useSlots } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
label: {
|
||||
type: String,
|
||||
require: true,
|
||||
},
|
||||
tooltip: {
|
||||
type: String,
|
||||
require: true,
|
||||
},
|
||||
placement: {
|
||||
type: String,
|
||||
default: 'top',
|
||||
},
|
||||
});
|
||||
</script>
|
||||
@@ -32,6 +32,9 @@ const MonacoEditorBox = (props: MonacoEditorDialogProps): void => {
|
||||
if (props.canChangeLang === undefined) {
|
||||
props.canChangeLang = true;
|
||||
}
|
||||
if (props.content === undefined) {
|
||||
props.content = '';
|
||||
}
|
||||
|
||||
// 创建 虚拟dom
|
||||
boxInstance = h(MonacoEditorDialog, {
|
||||
@@ -51,7 +54,6 @@ const MonacoEditorBox = (props: MonacoEditorDialogProps): void => {
|
||||
// 移除 container DOM 元素
|
||||
document.body.removeChild(container);
|
||||
props.closeFn && props.closeFn();
|
||||
console.log('close editor');
|
||||
},
|
||||
onConfirm: () => {
|
||||
let value = props.content;
|
||||
|
||||
@@ -31,6 +31,9 @@ export default {
|
||||
ipAndPort: 'ip and port',
|
||||
connSuccess: 'be connected successfully',
|
||||
noAcErrMsg: 'Please complete the voucher account information',
|
||||
ciphers: 'Ciphers',
|
||||
keyExchanges: 'Key Exchanges',
|
||||
multiValuePlaceholder: `multiple values are separated by ','`,
|
||||
|
||||
// MachineRec
|
||||
playback: 'Playback',
|
||||
|
||||
@@ -35,6 +35,7 @@ export default {
|
||||
linkAddress: 'Link Address',
|
||||
linkPlaceholder: 'External/embedded links (http://xxx.com)',
|
||||
menuNameRuleMsg: 'Please enter a resource name',
|
||||
codeRuleMsg: 'Please enter a resource code',
|
||||
routeNameNotEmpty: 'Route names cannot be empty',
|
||||
resourceCodePatternErrMsg: 'Only 1-32 uppercase letters, numbers, and -.: characters are allowed',
|
||||
assignedRole: 'Assigned Role',
|
||||
|
||||
@@ -32,6 +32,9 @@ export default {
|
||||
ipAndPort: 'ip和port',
|
||||
connSuccess: '连接成功',
|
||||
noAcErrMsg: '请完善授权凭证账号信息',
|
||||
ciphers: '加密算法',
|
||||
keyExchanges: '密钥交换',
|
||||
multiValuePlaceholder: `多个值用 ',' 隔开`,
|
||||
|
||||
// MachineRec
|
||||
playback: '回放',
|
||||
|
||||
@@ -34,6 +34,7 @@ export default {
|
||||
linkAddress: '链接地址',
|
||||
linkPlaceholder: '外链/内嵌的链接地址(http://xxx.com)',
|
||||
menuNameRuleMsg: '请输入资源名称',
|
||||
codeRuleMsg: '请输入code',
|
||||
routeNameNotEmpty: '路由名不能为空',
|
||||
resourceCodePatternErrMsg: '只允许输入1-32位大小写字母、数字、_-.:',
|
||||
assignedRole: '已分配角色',
|
||||
|
||||
@@ -15,14 +15,8 @@
|
||||
<el-form-item prop="status" :label="$t('common.status')">
|
||||
<EnumSelect :enums="ProcdefStatus" v-model="form.status" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="condition" :label="$t('flow.triggeringCondition')">
|
||||
<template #label>
|
||||
{{ $t('flow.triggeringCondition') }}
|
||||
<el-tooltip :content="$t('flow.triggeringConditionTips')" placement="top">
|
||||
<SvgIcon name="question-filled" />
|
||||
</el-tooltip>
|
||||
</template>
|
||||
|
||||
<FormItemTooltip prop="condition" :label="$t('flow.triggeringCondition')" :tooltip="$t('flow.triggeringConditionTips')">
|
||||
<el-input
|
||||
v-model="form.condition"
|
||||
:rows="10"
|
||||
@@ -31,7 +25,8 @@
|
||||
auto-complete="off"
|
||||
clearable
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</FormItemTooltip>
|
||||
|
||||
<el-form-item prop="remark" :label="$t('common.remark')">
|
||||
<el-input v-model.trim="form.remark" auto-complete="off" clearable></el-input>
|
||||
</el-form-item>
|
||||
@@ -98,6 +93,7 @@ import { TagResourceTypeEnum, TagResourceTypePath } from '@/common/commonEnum';
|
||||
import EnumSelect from '@/components/enumselect/EnumSelect.vue';
|
||||
import { useI18nFormValidate, useI18nPleaseInput, useI18nSaveSuccessMsg } from '@/hooks/useI18n';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import FormItemTooltip from '@/components/form/FormItemTooltip.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
||||
@@ -1,34 +1,32 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-tree-select
|
||||
v-bind="$attrs"
|
||||
v-model="state.selectTags"
|
||||
@change="changeTag"
|
||||
:data="tags"
|
||||
:placeholder="$t('tag.selectTagPlaceholder')"
|
||||
:default-expanded-keys="defaultExpandedKeys"
|
||||
show-checkbox
|
||||
node-key="codePath"
|
||||
:props="{
|
||||
value: 'codePath',
|
||||
label: 'codePath',
|
||||
children: 'children',
|
||||
}"
|
||||
>
|
||||
<template #default="{ data }">
|
||||
<span class="custom-tree-node">
|
||||
<SvgIcon :name="EnumValue.getEnumByValue(TagResourceTypeEnum, data.type)?.extra.icon" class="mr2" />
|
||||
<span style="font-size: 13px">
|
||||
{{ data.code }}
|
||||
<span style="color: #3c8dbc">【</span>
|
||||
{{ data.name }}
|
||||
<span style="color: #3c8dbc">】</span>
|
||||
<el-tag v-if="data.children !== null" size="small">{{ data.children.length }}</el-tag>
|
||||
</span>
|
||||
<el-tree-select
|
||||
v-bind="$attrs"
|
||||
v-model="state.selectTags"
|
||||
@change="changeTag"
|
||||
:data="tags"
|
||||
:placeholder="$t('tag.selectTagPlaceholder')"
|
||||
:default-expanded-keys="defaultExpandedKeys"
|
||||
show-checkbox
|
||||
node-key="codePath"
|
||||
:props="{
|
||||
value: 'codePath',
|
||||
label: 'codePath',
|
||||
children: 'children',
|
||||
}"
|
||||
>
|
||||
<template #default="{ data }">
|
||||
<span class="custom-tree-node">
|
||||
<SvgIcon :name="EnumValue.getEnumByValue(TagResourceTypeEnum, data.type)?.extra.icon" class="mr2" />
|
||||
<span style="font-size: 13px">
|
||||
{{ data.code }}
|
||||
<span style="color: #3c8dbc">【</span>
|
||||
{{ data.name }}
|
||||
<span style="color: #3c8dbc">】</span>
|
||||
<el-tag v-if="data.children !== null" size="small">{{ data.children.length }}</el-tag>
|
||||
</span>
|
||||
</template>
|
||||
</el-tree-select>
|
||||
</div>
|
||||
</span>
|
||||
</template>
|
||||
</el-tree-select>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
}
|
||||
"
|
||||
:select-tags="form.tagCodePaths"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
@@ -82,45 +82,23 @@
|
||||
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item class="w100" prop="updField">
|
||||
<template #label>
|
||||
{{ $t('db.updateField') }}
|
||||
<el-tooltip :content="$t('db.updateFieldTips')" placement="top">
|
||||
<SvgIcon name="question-filled" />
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<FormItemTooltip :label="$t('db.updateField')" prop="updField" :tooltip="$t('db.updateFieldTips')">
|
||||
<el-input v-model.trim="form.updField" :placeholder="$t('db.updateFiledPlaceholder')" auto-complete="off" />
|
||||
</el-form-item>
|
||||
</FormItemTooltip>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="12">
|
||||
<el-form-item class="w100" prop="updFieldVal">
|
||||
<template #label>
|
||||
{{ $t('db.updateFieldValue') }}
|
||||
<el-tooltip :content="$t('db.updateFieldValueTips')" placement="top">
|
||||
<el-icon>
|
||||
<question-filled />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<FormItemTooltip :label="$t('db.updateFieldValue')" prop="updFieldVal" :tooltip="$t('db.updateFieldValueTips')">
|
||||
<el-input v-model.trim="form.updFieldVal" :placeholder="$t('db.updateFieldValuePlaceholder')" auto-complete="off" />
|
||||
</el-form-item>
|
||||
</FormItemTooltip>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item class="w100" prop="updFieldSrc">
|
||||
<template #label>
|
||||
{{ $t('db.fieldValueSrc') }}
|
||||
<el-tooltip :content="$t('db.fieldValueSrcTips')" placement="top">
|
||||
<el-icon>
|
||||
<question-filled />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<FormItemTooltip :label="$t('db.fieldValueSrc')" prop="updFieldSrc" :tooltip="$t('db.fieldValueSrcTips')">
|
||||
<el-input v-model.trim="form.updFieldSrc" :placeholder="$t('db.fieldValueSrcPlaceholder')" auto-complete="off" />
|
||||
</el-form-item>
|
||||
</FormItemTooltip>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-tab-pane>
|
||||
@@ -228,6 +206,7 @@ import EnumSelect from '@/components/enumselect/EnumSelect.vue';
|
||||
import { DbDataSyncDuplicateStrategyEnum } from './enums';
|
||||
import { useI18nFormValidate, useI18nPleaseInput, useI18nSaveSuccessMsg } from '@/hooks/useI18n';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import FormItemTooltip from '@/components/form/FormItemTooltip.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
}
|
||||
"
|
||||
:select-tags="form.tagCodePaths"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item prop="name" :label="$t('common.name')" required>
|
||||
@@ -61,6 +60,13 @@
|
||||
<el-form-item prop="sshTunnelMachineId" :label="$t('machine.sshTunnel')">
|
||||
<ssh-tunnel-select v-model="form.sshTunnelMachineId" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item prop="ciphers" :label="$t('machine.ciphers')">
|
||||
<el-input v-model="form.extra.ciphers" :placeholder="$t('machine.multiValuePlaceholder')"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="keyExchanges" :label="$t('machine.keyExchanges')">
|
||||
<el-input v-model="form.extra.keyExchanges" :placeholder="$t('machine.multiValuePlaceholder')"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
@@ -152,6 +158,7 @@ const defaultForm = {
|
||||
remark: '',
|
||||
sshTunnelMachineId: null as any,
|
||||
enableRecorder: -1,
|
||||
extra: { ciphers: '', keyExchanges: '' },
|
||||
};
|
||||
|
||||
const state = reactive({
|
||||
@@ -175,6 +182,7 @@ watchEffect(() => {
|
||||
state.form = { ...machine };
|
||||
state.form.tagCodePaths = machine.tags.map((t: any) => t.codePath);
|
||||
state.form.authCerts = machine.authCerts || [];
|
||||
state.form.extra = machine.extra || {};
|
||||
} else {
|
||||
state.form = { ...defaultForm };
|
||||
state.form.authCerts = [];
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
"
|
||||
multiple
|
||||
:select-tags="form.tagCodePaths"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
"
|
||||
multiple
|
||||
:select-tags="form.tagCodePaths"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item prop="name" :label="$t('common.name')" required>
|
||||
|
||||
@@ -67,6 +67,8 @@
|
||||
>
|
||||
<template #default="{ node, data }">
|
||||
<span class="custom-tree-node">
|
||||
<SvgIcon :name="getMenuIcon(data)" class="mb3 mr3" />
|
||||
|
||||
<span v-if="data.type == ResourceTypeEnum.Menu.value">{{ $t(node.label) }}</span>
|
||||
<span v-if="data.type == ResourceTypeEnum.Permission.value" style="color: #67c23a">{{ $t(node.label) }}</span>
|
||||
</span>
|
||||
@@ -86,6 +88,7 @@ import { TableColumn } from '@/components/pagetable';
|
||||
import { SearchItem } from '@/components/SearchForm';
|
||||
import { ResourceTypeEnum, RoleStatusEnum } from '../enums';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { getMenuIcon } from '../resource/index';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
||||
@@ -14,17 +14,9 @@
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
||||
<el-form-item class="w100" prop="code" label="path|code">
|
||||
<template #label>
|
||||
path|code
|
||||
<el-tooltip :content="$t('system.menu.menuCodeTips')" placement="top">
|
||||
<el-icon>
|
||||
<question-filled />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<FormItemTooltip class="w100" label="path|code" prop="code" :tooltip="$t('system.menu.menuCodeTips')">
|
||||
<el-input v-model.trim="form.code" :placeholder="$t('system.menu.menuCodePlaceholder')" auto-complete="off"></el-input>
|
||||
</el-form-item>
|
||||
</FormItemTooltip>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="form.type === menuTypeValue">
|
||||
<el-form-item class="w100" :label="$t('system.menu.icon')">
|
||||
@@ -32,87 +24,57 @@
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="form.type === menuTypeValue">
|
||||
<el-form-item class="w100">
|
||||
<template #label>
|
||||
{{ $t('system.menu.routerName') }}
|
||||
<el-tooltip :content="$t('system.menu.routerNameTips')" placement="top">
|
||||
<el-icon>
|
||||
<question-filled />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<FormItemTooltip class="w100" :label="$t('system.menu.routerName')" prop="meta.routeName" :tooltip="$t('system.menu.routerNameTips')">
|
||||
<el-input v-model.trim="form.meta.routeName"></el-input>
|
||||
</el-form-item>
|
||||
</FormItemTooltip>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="form.type === menuTypeValue">
|
||||
<el-form-item class="w100" prop="code">
|
||||
<template #label>
|
||||
{{ $t('system.menu.componentPath') }}
|
||||
<el-tooltip :content="$t('system.menu.componentPathTips')" placement="top">
|
||||
<el-icon>
|
||||
<question-filled />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<FormItemTooltip
|
||||
class="w100"
|
||||
:label="$t('system.menu.routerName')"
|
||||
prop="meta.component"
|
||||
:tooltip="$t('system.menu.componentPathTips')"
|
||||
>
|
||||
<el-input v-model.trim="form.meta.component"></el-input>
|
||||
</el-form-item>
|
||||
</FormItemTooltip>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="form.type === menuTypeValue">
|
||||
<el-form-item class="w100" prop="isKeepAlive">
|
||||
<template #label>
|
||||
{{ $t('system.menu.isCache') }}
|
||||
<el-tooltip :content="$t('system.menu.isCacheTips')" placement="top">
|
||||
<el-icon>
|
||||
<question-filled />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<FormItemTooltip class="w100" :label="$t('system.menu.isCache')" prop="meta.isKeepAlive" :tooltip="$t('system.menu.isCacheTips')">
|
||||
<el-select v-model="form.meta.isKeepAlive" class="w100">
|
||||
<el-option v-for="item in trueFalseOption" :key="item.value" :label="item.label" :value="item.value"> </el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</FormItemTooltip>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="form.type === menuTypeValue">
|
||||
<el-form-item class="w100">
|
||||
<template #label>
|
||||
{{ $t('system.menu.isHide') }}
|
||||
<el-tooltip :content="$t('system.menu.isHideTips')" placement="top">
|
||||
<el-icon>
|
||||
<question-filled />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<FormItemTooltip class="w100" :label="$t('system.menu.isHide')" prop="meta.isHide" :tooltip="$t('system.menu.isHideTips')">
|
||||
<el-select v-model="form.meta.isHide" class="w100">
|
||||
<el-option v-for="item in trueFalseOption" :key="item.value" :label="item.label" :value="item.value"> </el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</FormItemTooltip>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="form.type === menuTypeValue">
|
||||
<el-form-item class="w100" prop="code" :label="$t('system.menu.tagIsDelete')">
|
||||
<el-form-item class="w100" prop="meta.isAffix" :label="$t('system.menu.tagIsDelete')">
|
||||
<el-select v-model="form.meta.isAffix" class="w100">
|
||||
<el-option v-for="item in trueFalseOption" :key="item.value" :label="item.label" :value="item.value"> </el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="form.type === menuTypeValue">
|
||||
<el-form-item class="w100" prop="linkType">
|
||||
<template #label>
|
||||
{{ $t('system.menu.externalLink') }}
|
||||
<el-tooltip content="" placement="top">
|
||||
<el-icon>
|
||||
<question-filled />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<FormItemTooltip
|
||||
class="w100"
|
||||
:label="$t('system.menu.externalLink')"
|
||||
prop="meta.linkType"
|
||||
:tooltip="$t('system.menu.externalLinkTips')"
|
||||
>
|
||||
<el-select class="w100" @change="changeLinkType" v-model="form.meta.linkType">
|
||||
<el-option :key="0" :label="$t('system.menu.no')" :value="0"> </el-option>
|
||||
<el-option :key="1" :label="$t('system.menu.inline')" :value="1"> </el-option>
|
||||
<el-option :key="2" :label="$t('system.menu.externalLink')" :value="2"> </el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</FormItemTooltip>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="form.type === menuTypeValue && form.meta.linkType > 0">
|
||||
<el-form-item prop="code" :label="$t('system.menu.linkAddress')" class="w100">
|
||||
<el-form-item prop="meta.link" :label="$t('system.menu.linkAddress')" class="w100">
|
||||
<el-input v-model.trim="form.meta.link" :placeholder="$t('system.menu.linkPlaceholder')"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@@ -138,6 +100,7 @@ import { notEmpty } from '@/common/assert';
|
||||
import iconSelector from '@/components/iconSelector/index.vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import EnumSelect from '@/components/enumselect/EnumSelect.vue';
|
||||
import FormItemTooltip from '@/components/form/FormItemTooltip.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
@@ -183,6 +146,13 @@ const rules = {
|
||||
trigger: ['change', 'blur'],
|
||||
},
|
||||
],
|
||||
code: [
|
||||
{
|
||||
required: true,
|
||||
message: t('system.menu.codeRuleMsg'),
|
||||
trigger: ['change', 'blur'],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const trueFalseOption = [
|
||||
|
||||
@@ -37,6 +37,8 @@
|
||||
>
|
||||
<template #default="{ data }">
|
||||
<span class="custom-tree-node">
|
||||
<SvgIcon :name="getMenuIcon(data)" class="mb3" />
|
||||
|
||||
<span style="font-size: 13px" v-if="data.type === menuTypeValue">
|
||||
<span style="color: #3c8dbc">【</span>
|
||||
<span v-if="data.status == 1">{{ $t(data.name) }}</span>
|
||||
@@ -46,6 +48,7 @@
|
||||
{{ data.children.length }}
|
||||
</el-tag>
|
||||
</span>
|
||||
|
||||
<span style="font-size: 13px" v-if="data.type === permissionTypeValue">
|
||||
<span style="color: #3c8dbc">【</span>
|
||||
<span :style="data.status == 1 ? 'color: #67c23a;' : 'color: #f67c6c;'">
|
||||
@@ -142,7 +145,7 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, toRefs, reactive, onMounted, watch } from 'vue';
|
||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import ResourceEdit from './ResourceEdit.vue';
|
||||
import { ResourceTypeEnum, RoleStatusEnum } from '../enums';
|
||||
import { resourceApi } from '../api';
|
||||
@@ -153,6 +156,7 @@ import { Splitpanes, Pane } from 'splitpanes';
|
||||
import { isPrefixSubsequence } from '@/common/utils/string';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useI18nDeleteConfirm, useI18nDeleteSuccessMsg } from '@/hooks/useI18n';
|
||||
import { getMenuIcon } from './index';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
||||
@@ -1 +1,22 @@
|
||||
import { ResourceTypeEnum } from '../enums';
|
||||
|
||||
export { default } from './ResourceList.vue';
|
||||
|
||||
/**
|
||||
* 获取menu icon
|
||||
* @param menu menu信息
|
||||
* @returns icon name
|
||||
*/
|
||||
export function getMenuIcon(menu: any) {
|
||||
if (menu.type == ResourceTypeEnum.Permission.value) {
|
||||
return 'icon menu/permission';
|
||||
}
|
||||
if (!menu.meta) {
|
||||
return '';
|
||||
}
|
||||
const meta = JSON.parse(menu.meta);
|
||||
if (meta) {
|
||||
return meta.icon;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
>
|
||||
<template #default="{ node, data }">
|
||||
<span class="custom-tree-node">
|
||||
<SvgIcon :name="getMenuIcon(data)" class="mb3 mr3" />
|
||||
<span v-if="data.type == ResourceTypeEnum.Menu.value">{{ $t(node.label) }}</span>
|
||||
<span v-if="data.type == ResourceTypeEnum.Permission.value" style="color: #67c23a">{{ $t(node.label) }}</span>
|
||||
</span>
|
||||
@@ -39,6 +40,8 @@ import { ElMessage } from 'element-plus';
|
||||
import { roleApi } from '../api';
|
||||
import { ResourceTypeEnum } from '../enums';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import SvgIcon from '@/components/svgIcon/index.vue';
|
||||
import { getMenuIcon } from '../resource';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
<el-tree style="height: 50vh; overflow: auto" :data="resources" node-key="id" :props="defaultProps">
|
||||
<template #default="{ node, data }">
|
||||
<span class="custom-tree-node">
|
||||
<SvgIcon :name="getMenuIcon(data)" class="mb3 mr3" />
|
||||
|
||||
<span v-if="data.type == ResourceTypeEnum.Menu.value">{{ $t(node.label) }}</span>
|
||||
<span v-if="data.type == ResourceTypeEnum.Permission.value" style="color: #67c23a">{{ $t(node.label) }}</span>
|
||||
|
||||
@@ -36,6 +38,7 @@
|
||||
import { toRefs, reactive, watch } from 'vue';
|
||||
import { ResourceTypeEnum } from '../enums';
|
||||
import { formatDate } from '@/common/utils/format';
|
||||
import { getMenuIcon } from '../resource/index';
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
|
||||
Reference in New Issue
Block a user