refactor: form rules refactor

This commit is contained in:
meilin.huang
2025-03-05 12:47:52 +08:00
parent 547e31eae6
commit c7c3fd7f7e
32 changed files with 183 additions and 573 deletions

View File

@@ -1,11 +0,0 @@
import { i18n } from '@/i18n';
export const AccountUsernamePattern = {
pattern: /^[a-zA-Z0-9_]{5,16}$/g,
message: i18n.global.t('system.account.usernamePatternErrMsg'),
};
export const ResourceCodePattern = {
pattern: /^[a-zA-Z0-9_\-.:]{1,32}$/g,
message: i18n.global.t('system.menu.resourceCodePatternErrMsg'),
};

View File

@@ -0,0 +1,41 @@
import { useI18nPleaseInput, useI18nPleaseSelect } from '@/hooks/useI18n';
import { i18n } from '@/i18n';
/**
* 表单验证规则
* label: 支持 i18n key
*/
export const Rules = {
requiredInput: (label: string = '', trigger: string[] = ['change', 'blur']) => {
return {
required: true,
message: useI18nPleaseInput(label),
trigger: trigger,
};
},
requiredSelect: (label: string = '', trigger: string[] = ['change', 'blur']) => {
return {
required: true,
message: useI18nPleaseSelect(label),
trigger: trigger,
};
},
accountUsername: {
pattern: /^[a-zA-Z0-9_]{5,16}$/g,
message: i18n.global.t('system.account.usernamePatternErrMsg'),
trigger: 'blur',
},
accountPassword: {
pattern: /^(?=.*[A-Za-z])(?=.*\d)(?=.*[`~!@#$%^&*()_+<>?:"{},.\/\\;'[\]])[A-Za-z\d`~!@#$%^&*()_+<>?:"{},.\/\\;'[\]]{8,}$/,
message: i18n.global.t('login.passwordRuleTip'),
trigger: 'blur',
},
resourceCode: {
pattern: /^[a-zA-Z0-9_\-.:]{1,32}$/g,
message: i18n.global.t('system.menu.resourceCodePatternErrMsg'),
trigger: 'blur',
},
};

View File

@@ -79,16 +79,29 @@ export function useI18nDetailTitle(i18nKey: string) {
}
export function useI18nOperateSuccessMsg() {
const t = i18n.global.t;
ElMessage.success(t('common.operateSuccess'));
MsgSuccess('common.operateSuccess');
}
export function useI18nSaveSuccessMsg() {
const t = i18n.global.t;
ElMessage.success(t('common.saveSuccess'));
MsgSuccess('common.saveSuccess');
}
export function useI18nDeleteSuccessMsg() {
const t = i18n.global.t;
ElMessage.success(t('common.deleteSuccess'));
MsgSuccess('common.deleteSuccess');
}
/**
* error msg
* @param msg msg(支持i8n msgkey)
*/
export function MsgError(msg: string) {
ElMessage.error(i18n.global.t(msg));
}
/**
* success msg
* @param msg msg(支持i8n msgkey)
*/
export function MsgSuccess(msg: string) {
ElMessage.success(i18n.global.t(msg));
}

View File

@@ -23,6 +23,7 @@ export default {
time: 'Time',
account: 'Account',
password: 'Password',
captcha: 'Captcha',
createTime: 'Create Time',
creator: 'Creator',
updateTime: 'Update Time',
@@ -338,25 +339,19 @@ export default {
accountPasswordLogin: 'Account Password Login',
thirdPartyLogin: 'Third Party login',
ldapLogin: 'LDAP Login',
inputUsernamePlaceholder: 'Please enter your username',
inputPasswordPlaceholder: 'Please enter your password',
inputCaptchaPlaceholder: 'Please enter the verification code',
login: 'Login',
loginFailTip: 'Tip: If you fail to log in more than {loginFailCount} times, you will not be allowed to log in again for {loginFailMin} minutes',
loginSuccessTip: 'welcome back!',
changePassword: 'Change Password',
oldPassword: 'Old Password',
newPassword: 'New Password',
inputNewPasswordPlaceholder: 'Please enter a new password',
passwordRuleTip: 'Must be at least 8 characters long and contain upper/lower case + number + special symbol',
passwordChangeSuccessTip: 'The password has been changed successfully, and the new password has been filled in the login password box',
otpValidation: 'OTP validation',
qrCode: 'QR code',
enterOtpCodeTip: 'Enter the authorization code shown in the Token APP',
inputOtpCodePlaceholder: 'Please enter the OTP authorization code',
updateBasicInfo: 'Modifying basic information',
name: 'Name',
inputNamePlaceholder: 'Please enter your name',
},
components: {
df: {

View File

@@ -34,8 +34,6 @@ export default {
inline: 'Embedded',
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',

View File

@@ -23,6 +23,7 @@ export default {
time: '时间',
account: '账号',
password: '密码',
captcha: '验证码',
createTime: '创建时间',
creator: '创建者',
updateTime: '更新时间',
@@ -348,9 +349,6 @@ export default {
accountPasswordLogin: '账号密码登录',
thirdPartyLogin: '第三方登录',
ldapLogin: 'LDAP 登录',
inputUsernamePlaceholder: '请输入用户名',
inputPasswordPlaceholder: '请输入密码',
inputCaptchaPlaceholder: '请输入验证码',
login: '登 录',
loginFailTip: '提示:登录失败超过{loginFailCount}次后将被限制{loginFailMin}分钟内不可再次登录',
loginSuccessTip: '欢迎回来!',
@@ -364,7 +362,6 @@ export default {
enterOtpCodeTip: '请输入令牌APP中显示的授权码',
updateBasicInfo: '修改基本信息',
name: '姓名',
inputNamePlaceholder: '请输入姓名',
},
components: {
df: {

View File

@@ -33,8 +33,6 @@ export default {
inline: '内嵌',
linkAddress: '链接地址',
linkPlaceholder: '外链/内嵌的链接地址http://xxx.com',
menuNameRuleMsg: '请输入资源名称',
codeRuleMsg: '请输入code',
routeNameNotEmpty: '路由名不能为空',
resourceCodePatternErrMsg: '只允许输入1-32位大小写字母、数字、_-.:',
assignedRole: '已分配角色',

View File

@@ -53,8 +53,8 @@ import { FlowBizType } from './enums';
import EnumSelect from '@/components/enumselect/EnumSelect.vue';
import ProcdefTasks from './components/ProcdefTasks.vue';
import RedisRunCmdFlowBizForm from './flowbiz/redis/RedisRunCmdFlowBizForm.vue';
import { useI18nPleaseInput, useI18nPleaseSelect } from '@/hooks/useI18n';
import { useI18n } from 'vue-i18n';
import { Rules } from '@/common/rule';
const DbSqlExecFlowBizForm = defineAsyncComponent(() => import('./flowbiz/dbms/DbSqlExecFlowBizForm.vue'));
@@ -81,20 +81,8 @@ const bizComponents: any = shallowReactive({
});
const rules = {
bizType: [
{
required: true,
message: useI18nPleaseSelect('flow.bizType'),
trigger: ['change', 'blur'],
},
],
remark: [
{
required: true,
message: useI18nPleaseInput('common.remark'),
trigger: ['change', 'blur'],
},
],
bizType: [Rules.requiredSelect('flow.bizType')],
remark: [Rules.requiredInput('common.remark')],
};
const defaultForm = {

View File

@@ -91,9 +91,10 @@ import { ProcdefStatus } from './enums';
import TagTreeCheck from '../ops/component/TagTreeCheck.vue';
import { TagResourceTypeEnum, TagResourceTypePath } from '@/common/commonEnum';
import EnumSelect from '@/components/enumselect/EnumSelect.vue';
import { useI18nFormValidate, useI18nPleaseInput, useI18nSaveSuccessMsg } from '@/hooks/useI18n';
import { useI18nFormValidate, useI18nSaveSuccessMsg } from '@/hooks/useI18n';
import { useI18n } from 'vue-i18n';
import FormItemTooltip from '@/components/form/FormItemTooltip.vue';
import { Rules } from '@/common/rule';
const { t } = useI18n();
@@ -115,20 +116,8 @@ const formRef: any = ref(null);
const taskTableRef: any = ref(null);
const rules = {
name: [
{
required: true,
message: useI18nPleaseInput('common.name'),
trigger: ['change', 'blur'],
},
],
defKey: [
{
required: true,
message: useI18nPleaseInput('Key'),
trigger: ['change', 'blur'],
},
],
name: [Rules.requiredInput('common.name')],
defKey: [Rules.requiredInput('key')],
};
const state = reactive({

View File

@@ -24,26 +24,11 @@ import DbSelectTree from '@/views/ops/db/component/DbSelectTree.vue';
import MonacoEditor from '@/components/monaco/MonacoEditor.vue';
import { registerDbCompletionItemProvider } from '@/views/ops/db/db';
import { TagResourceTypeEnum } from '@/common/commonEnum';
import { useI18n } from 'vue-i18n';
import { useI18nPleaseInput } from '@/hooks/useI18n';
const { t } = useI18n();
import { Rules } from '@/common/rule';
const rules = {
dbId: [
{
required: true,
message: t('flow.selectDbPlaceholder'),
trigger: ['change', 'blur'],
},
],
sql: [
{
required: true,
message: useI18nPleaseInput('flow.runSql'),
trigger: ['change', 'blur'],
},
],
dbId: [Rules.requiredSelect('db.db')],
sql: [Rules.requiredInput('flow.runSql')],
};
const emit = defineEmits(['changeResourceCode']);

View File

@@ -26,7 +26,7 @@ import { NodeType, TagTreeNode } from '@/views/ops/component/tag';
import { redisApi } from '@/views/ops/redis/api';
import { sleep } from '@/common/utils/loading';
import { useI18n } from 'vue-i18n';
import { useI18nPleaseInput } from '@/hooks/useI18n';
import { Rules } from '@/common/rule';
const { t } = useI18n();
@@ -38,13 +38,7 @@ const rules = {
trigger: ['change', 'blur'],
},
],
cmd: [
{
required: true,
message: useI18nPleaseInput('flow.runCmd'),
trigger: ['change', 'blur'],
},
],
cmd: [Rules.requiredInput('flow.runCmd')],
};
// tagpath 节点类型

View File

@@ -2,20 +2,14 @@
<div>
<el-form ref="loginFormRef" :model="loginForm" :rules="rules" class="login-content-form" size="large">
<el-form-item prop="username">
<el-input
type="text"
:placeholder="$t('login.inputUsernamePlaceholder')"
prefix-icon="user"
v-model="loginForm.username"
clearable
autocomplete="off"
>
<el-input type="text" :placeholder="$t('common.username')" prefix-icon="user" v-model="loginForm.username" clearable autocomplete="off">
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
type="password"
:placeholder="$t('login.inputPasswordPlaceholder')"
:placeholder="$t('common.password')"
prefix-icon="lock"
v-model="loginForm.password"
autocomplete="off"
@@ -24,13 +18,14 @@
>
</el-input>
</el-form-item>
<el-form-item v-if="accountLoginSecurity.useCaptcha" prop="captcha">
<el-row :gutter="15">
<el-col :span="16">
<el-input
type="text"
maxlength="6"
:placeholder="$t('login.inputCaptchaPlaceholder')"
:placeholder="$t('common.captcha')"
prefix-icon="position"
v-model="loginForm.captcha"
clearable
@@ -45,9 +40,11 @@
</el-col>
</el-row>
</el-form-item>
<el-form-item v-if="ldapEnabled" prop="ldapLogin">
<el-checkbox v-model="loginForm.ldapLogin" :label="$t('login.ldapLogin')" size="small" />
</el-form-item>
<span v-if="showLoginFailTips" style="color: #f56c6c; font-size: 12px">
{{
$t('login.loginFailTip', {
@@ -56,6 +53,7 @@
})
}}
</span>
<el-form-item>
<el-button type="primary" class="login-content-submit" round @click="login" :loading="loading.signIn">
<span>{{ $t('login.login') }}</span>
@@ -147,12 +145,11 @@
</template>
<script lang="ts" setup>
import { nextTick, onMounted, ref, toRefs, reactive, computed } from 'vue';
import { nextTick, onMounted, ref, toRefs, reactive } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { ElMessage } from 'element-plus';
import { initRouter } from '@/router/index';
import { getRefreshToken, saveRefreshToken, saveToken, saveUser } from '@/common/utils/storage';
import { formatAxis } from '@/common/utils/format';
import openApi from '@/common/openApi';
import { RsaEncrypt } from '@/common/rsa';
import { getAccountLoginSecurity, getLdapEnabled } from '@/common/sysconfig';
@@ -160,18 +157,18 @@ import { letterAvatar } from '@/common/utils/string';
import { useUserInfo } from '@/store/userInfo';
import QrcodeVue from 'qrcode.vue';
import { personApi } from '@/views/personal/api';
import { AccountUsernamePattern } from '@/common/pattern';
import { getToken } from '@/common/utils/storage';
import { useThemeConfig } from '@/store/themeConfig';
import { getFileUrl } from '@/common/request';
import { useI18n } from 'vue-i18n';
import { Rules } from '@/common/rule';
const { t } = useI18n();
const rules = {
username: [{ required: true, message: t('login.inputUsernamePlaceholder'), trigger: 'blur' }],
password: [{ required: true, message: t('login.inputPasswordPlaceholder'), trigger: 'blur' }],
captcha: [{ required: true, message: t('login.inputCaptchaPlaceholder'), trigger: 'blur' }],
username: [Rules.requiredInput('common.username')],
password: [Rules.requiredInput('common.password')],
captcha: [Rules.requiredInput('common.captcha')],
};
// 定义变量内容
@@ -210,14 +207,7 @@ const state = reactive({
newPassword: '',
},
rules: {
newPassword: [
{ required: true, message: t('login.inputNewPasswordPlaceholder'), trigger: 'blur' },
{
pattern: /^(?=.*[A-Za-z])(?=.*\d)(?=.*[`~!@#$%^&*()_+<>?:"{},.\/\\;'[\]])[A-Za-z\d`~!@#$%^&*()_+<>?:"{},.\/\\;'[\]]{8,}$/,
message: t('login.passwordRuleTip'),
trigger: 'blur',
},
],
newPassword: [Rules.requiredInput('login.newPassword'), Rules.accountPassword],
},
},
otpDialog: {
@@ -228,7 +218,7 @@ const state = reactive({
otpToken: '',
},
rules: {
code: [{ required: true, message: t('login.inputOtpCodePlaceholder'), trigger: 'blur' }],
code: [Rules.requiredInput('OTP')],
},
},
baseInfoDialog: {
@@ -238,15 +228,8 @@ const state = reactive({
name: '',
},
rules: {
username: [
{ required: true, message: t('login.inputUsernamePlaceholder'), trigger: 'blur' },
{
pattern: AccountUsernamePattern.pattern,
message: AccountUsernamePattern.message,
trigger: ['blur'],
},
],
name: [{ required: true, message: t('login.inputNamePlaceholder'), trigger: 'blur' }],
username: [Rules.requiredInput('common.username'), Rules.accountUsername],
name: [Rules.requiredInput('common.name')],
},
},
loading: {
@@ -285,11 +268,6 @@ const getCaptcha = async () => {
state.loginForm.cid = res.cid;
};
// 时间获取
const currentTime = computed(() => {
return formatAxis(new Date());
});
// 校验登录表单并登录
const login = () => {
loginFormRef.value.validate((valid: boolean) => {
@@ -436,8 +414,6 @@ const signInSuccess = async (accessToken: string = '', refreshToken = '') => {
};
const toIndex = async () => {
// 初始化登录成功时间问候语
let currentTimeInfo = currentTime.value;
// 登录成功,跳到转首页
// 添加完动态路由,再进行 router 跳转,否则可能报错 No match found for location with path "/"
// 如果是复制粘贴的路径,非首页/登录页,那么登录成功后重定向到对应的路径中

View File

@@ -212,7 +212,6 @@ const oauth2Login = () => {
border: 1px solid var(--el-color-primary-light-3);
border-radius: 3px;
width: 500px;
height: 500px;
position: relative;
overflow: hidden;
background-color: var(--bg-main-color);

View File

@@ -125,11 +125,8 @@ import { reactive, ref, toRefs, computed, watch } from 'vue';
import { AuthCertTypeEnum, AuthCertCiphertextTypeEnum } from '../tag/enums';
import EnumTag from '@/components/enumtag/EnumTag.vue';
import { resourceAuthCertApi } from '../tag/api';
import { ResourceCodePattern } from '@/common/pattern';
import { TagResourceTypeEnum } from '@/common/commonEnum';
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
import { Rules } from '@/common/rule';
const props = defineProps({
title: {
@@ -166,25 +163,8 @@ const DefaultForm = {
};
const rules = {
name: [
{
required: true,
message: t('common.pleaseInput', { label: t('common.name') }),
trigger: ['change', 'blur'],
},
{
pattern: ResourceCodePattern.pattern,
message: ResourceCodePattern.message,
trigger: ['blur'],
},
],
resourceCode: [
{
required: true,
message: t('common.pleaseInput', { label: t('ac.resourceCode') }),
trigger: ['change', 'blur'],
},
],
name: [Rules.requiredInput('common.name'), Rules.resourceCode],
resourceCode: [Rules.requiredInput('ac.resourceCode')],
};
const emit = defineEmits(['confirm', 'cancel']);

View File

@@ -86,7 +86,8 @@ import { resourceAuthCertApi } from '../tag/api';
import { TagResourceTypeEnum } from '@/common/commonEnum';
import { DbGetDbNamesMode } from './enums';
import EnumSelect from '@/components/enumselect/EnumSelect.vue';
import { useI18nFormValidate, useI18nPleaseInput, useI18nPleaseSelect } from '@/hooks/useI18n';
import { useI18nFormValidate } from '@/hooks/useI18n';
import { Rules } from '@/common/rule';
const props = defineProps({
visible: {
@@ -107,34 +108,10 @@ const props = defineProps({
const emit = defineEmits(['update:visible', 'cancel', 'val-change', 'confirm']);
const rules = {
instanceId: [
{
required: true,
message: useI18nPleaseSelect('db.dbInst'),
trigger: ['change', 'blur'],
},
],
name: [
{
required: true,
message: useI18nPleaseInput('common.name'),
trigger: ['change', 'blur'],
},
],
authCertName: [
{
required: true,
message: useI18nPleaseSelect('db.acName'),
trigger: ['change', 'blur'],
},
],
getDatabaseMode: [
{
required: true,
message: useI18nPleaseSelect('db.getDbMode'),
trigger: ['change', 'blur'],
},
],
instanceId: [Rules.requiredSelect('db.dbInst')],
name: [Rules.requiredInput('common.name')],
authCertName: [Rules.requiredSelect('db.acName')],
getDatabaseMode: [Rules.requiredSelect('db.getDbMode')],
};
const checkAllDbNames = ref(false);

View File

@@ -159,8 +159,9 @@ import { getDbDialect, getDbDialectMap } from '@/views/ops/db/dialect';
import SvgIcon from '@/components/svgIcon/index.vue';
import _ from 'lodash';
import DrawerHeader from '@/components/drawer-header/DrawerHeader.vue';
import { useI18nFormValidate, useI18nPleaseInput, useI18nPleaseSelect, useI18nSaveSuccessMsg } from '@/hooks/useI18n';
import { useI18nFormValidate, useI18nSaveSuccessMsg } from '@/hooks/useI18n';
import { useI18n } from 'vue-i18n';
import { Rules } from '@/common/rule';
const { t } = useI18n();
@@ -179,41 +180,11 @@ const emit = defineEmits(['update:visible', 'cancel', 'val-change']);
const dialogVisible = defineModel<boolean>('visible', { default: false });
const rules = {
taskName: [
{
required: true,
message: useI18nPleaseInput('db.taskName'),
trigger: ['change', 'blur'],
},
],
srcDbId: [
{
required: true,
message: useI18nPleaseSelect('db.srcDb'),
trigger: ['change', 'blur'],
},
],
targetDbId: [
{
required: true,
message: useI18nPleaseSelect('db.targetDb'),
trigger: ['change', 'blur'],
},
],
targetFileDbType: [
{
required: true,
message: useI18nPleaseSelect('db.dbFileType'),
trigger: ['change', 'blur'],
},
],
cron: [
{
required: true,
message: useI18nPleaseSelect('cron'),
trigger: ['change', 'blur'],
},
],
taskName: [Rules.requiredInput('db.taskName')],
srcDbId: [Rules.requiredSelect('db.srcDb')],
targetDbId: [Rules.requiredSelect('db.targetDb')],
targetFileDbType: [Rules.requiredSelect('db.dbFileType')],
cron: [Rules.requiredSelect('cron')],
};
const dbForm: any = ref(null);

View File

@@ -92,8 +92,9 @@ import DbSelectTree from '@/views/ops/db/component/DbSelectTree.vue';
import { getClientId } from '@/common/utils/storage';
import FileInfo from '@/components/file/FileInfo.vue';
import { DbTransferFileStatusEnum } from './enums';
import { useI18nDeleteConfirm, useI18nDeleteSuccessMsg, useI18nFormValidate, useI18nOperateSuccessMsg, useI18nPleaseSelect } from '@/hooks/useI18n';
import { useI18nDeleteConfirm, useI18nDeleteSuccessMsg, useI18nFormValidate, useI18nOperateSuccessMsg } from '@/hooks/useI18n';
import { useI18n } from 'vue-i18n';
import { Rules } from '@/common/rule';
const { t } = useI18n();
@@ -154,13 +155,7 @@ const state = reactive({
visible: false,
data: null as any,
formRules: {
targetDbId: [
{
required: true,
message: useI18nPleaseSelect('db.targetDb'),
trigger: ['change', 'blur'],
},
],
targetDbId: [Rules.requiredSelect('db.targetDb')],
},
runForm: {
id: 0,

View File

@@ -125,9 +125,10 @@ import { TagResourceTypeEnum } from '@/common/commonEnum';
import ResourceAuthCertTableEdit from '../component/ResourceAuthCertTableEdit.vue';
import { AuthCertCiphertextTypeEnum } from '../tag/enums';
import TagTreeSelect from '../component/TagTreeSelect.vue';
import { useI18nFormValidate, useI18nPleaseInput, useI18nPleaseSelect, useI18nSaveSuccessMsg } from '@/hooks/useI18n';
import { useI18nFormValidate, useI18nSaveSuccessMsg } from '@/hooks/useI18n';
import { useI18n } from 'vue-i18n';
import { notBlankI18n } from '@/common/assert';
import { Rules } from '@/common/rule';
const { t } = useI18n();
@@ -147,41 +148,10 @@ const props = defineProps({
const emit = defineEmits(['update:visible', 'cancel', 'val-change']);
const rules = {
tagCodePaths: [
{
required: true,
message: useI18nPleaseSelect('tag.relateTag'),
trigger: ['change'],
},
],
name: [
{
required: true,
message: useI18nPleaseInput('common.name'),
trigger: ['change', 'blur'],
},
],
type: [
{
required: true,
message: useI18nPleaseSelect('common.type'),
trigger: ['change', 'blur'],
},
],
host: [
{
required: true,
message: useI18nPleaseInput('Host:Port'),
trigger: ['blur'],
},
],
sid: [
{
required: true,
message: useI18nPleaseInput('SID'),
trigger: ['change', 'blur'],
},
],
tagCodePaths: [Rules.requiredSelect('tag.relateTag')],
name: [Rules.requiredInput('common.name')],
type: [Rules.requiredSelect('common.type')],
host: [Rules.requiredInput('Host:Port')],
};
const dbForm: any = ref(null);

View File

@@ -204,9 +204,10 @@ import CrontabInput from '@/components/crontab/CrontabInput.vue';
import DrawerHeader from '@/components/drawer-header/DrawerHeader.vue';
import EnumSelect from '@/components/enumselect/EnumSelect.vue';
import { DbDataSyncDuplicateStrategyEnum } from './enums';
import { useI18nFormValidate, useI18nPleaseInput, useI18nSaveSuccessMsg } from '@/hooks/useI18n';
import { useI18nFormValidate, useI18nSaveSuccessMsg } from '@/hooks/useI18n';
import { useI18n } from 'vue-i18n';
import FormItemTooltip from '@/components/form/FormItemTooltip.vue';
import { Rules } from '@/common/rule';
const { t } = useI18n();
@@ -225,20 +226,8 @@ const emit = defineEmits(['update:visible', 'cancel', 'val-change']);
const dialogVisible = defineModel<boolean>('visible', { default: false });
const rules = {
taskName: [
{
required: true,
message: useI18nPleaseInput('db.taskName'),
trigger: ['change', 'blur'],
},
],
taskCron: [
{
required: true,
message: useI18nPleaseInput('cron'),
trigger: ['change', 'blur'],
},
],
taskName: [Rules.requiredInput('db.taskName')],
taskCron: [Rules.requiredInput('cron')],
};
const dbForm: any = ref(null);

View File

@@ -89,8 +89,9 @@ import SshTunnelSelect from '../component/SshTunnelSelect.vue';
import { MachineProtocolEnum } from './enums';
import DrawerHeader from '@/components/drawer-header/DrawerHeader.vue';
import { TagResourceTypeEnum } from '@/common/commonEnum';
import { useI18nFormValidate, useI18nPleaseInput, useI18nPleaseSelect, useI18nSaveSuccessMsg } from '@/hooks/useI18n';
import { useI18nFormValidate, useI18nSaveSuccessMsg } from '@/hooks/useI18n';
import { useI18n } from 'vue-i18n';
import { Rules } from '@/common/rule';
const { t } = useI18n();
@@ -112,34 +113,10 @@ const emit = defineEmits(['cancel', 'val-change']);
const dialogVisible = defineModel<boolean>('visible', { default: false });
const rules = {
tagCodePaths: [
{
required: true,
message: useI18nPleaseSelect('tag.relateTag'),
trigger: ['change'],
},
],
name: [
{
required: true,
message: useI18nPleaseInput('common.name'),
trigger: ['change', 'blur'],
},
],
protocol: [
{
required: true,
message: useI18nPleaseSelect('machine.protocol'),
trigger: ['change', 'blur'],
},
],
ip: [
{
required: true,
message: useI18nPleaseInput('machine.ipAndPort'),
trigger: ['blur'],
},
],
tagCodePaths: [Rules.requiredSelect('tag.relateTag')],
name: [Rules.requiredInput('common.name')],
protocol: [Rules.requiredSelect('machine.protocol')],
ip: [Rules.requiredInput('machine.ipAndPort')],
};
const machineForm: any = ref(null);

View File

@@ -62,7 +62,8 @@ import MonacoEditor from '@/components/monaco/MonacoEditor.vue';
import { DynamicFormEdit } from '@/components/dynamic-form';
import SvgIcon from '@/components/svgIcon/index.vue';
import EnumSelect from '@/components/enumselect/EnumSelect.vue';
import { useI18nFormValidate, useI18nPleaseInput, useI18nPleaseSelect, useI18nSaveSuccessMsg } from '@/hooks/useI18n';
import { useI18nFormValidate, useI18nSaveSuccessMsg } from '@/hooks/useI18n';
import { Rules } from '@/common/rule';
const props = defineProps({
visible: {
@@ -85,34 +86,10 @@ const props = defineProps({
const emit = defineEmits(['update:visible', 'cancel', 'submitSuccess']);
const rules = {
name: [
{
required: true,
message: useI18nPleaseInput('common.name'),
trigger: ['change', 'blur'],
},
],
description: [
{
required: true,
message: useI18nPleaseInput('common.remark'),
trigger: ['blur', 'change'],
},
],
type: [
{
required: true,
message: useI18nPleaseSelect('common.type'),
trigger: ['change', 'blur'],
},
],
script: [
{
required: true,
message: useI18nPleaseInput('machine.script'),
trigger: ['blur', 'change'],
},
],
name: [Rules.requiredInput('common.name')],
description: [Rules.requiredInput('common.remark')],
type: [Rules.requiredSelect('common.type')],
script: [Rules.requiredInput('machine.script')],
};
const { isCommon, machineId } = toRefs(props);

View File

@@ -39,11 +39,7 @@
/></el-form-item>
<el-form-item ref="tagSelectRef" prop="codePaths" :label="$t('machine.relateMachine')">
<tag-tree-check
height="200px"
:tag-type="`${TagResourceTypeEnum.Machine.value}/${TagResourceTypeEnum.AuthCert.value}`"
v-model="form.codePaths"
/>
<tag-tree-check height="200px" :tag-type="`${TagResourceTypeEnum.Machine.value}`" v-model="form.codePaths" />
</el-form-item>
</el-form>
@@ -61,7 +57,6 @@
<script lang="ts" setup>
import { ref, toRefs, reactive, watch, onMounted } from 'vue';
import { ElMessage } from 'element-plus';
import { cronJobApi, machineApi } from '../api';
import { CronJobStatusEnum, CronJobSaveExecResTypeEnum } from '../enums';
import MonacoEditor from '@/components/monaco/MonacoEditor.vue';
@@ -70,10 +65,8 @@ import DrawerHeader from '@/components/drawer-header/DrawerHeader.vue';
import TagTreeCheck from '../../component/TagTreeCheck.vue';
import { TagResourceTypeEnum } from '@/common/commonEnum';
import EnumSelect from '@/components/enumselect/EnumSelect.vue';
import { useI18n } from 'vue-i18n';
import { useI18nFormValidate, useI18nPleaseInput, useI18nPleaseSelect, useI18nSaveSuccessMsg } from '@/hooks/useI18n';
const { t } = useI18n();
import { useI18nFormValidate, useI18nSaveSuccessMsg } from '@/hooks/useI18n';
import { Rules } from '@/common/rule';
const props = defineProps({
visible: {
@@ -92,41 +85,11 @@ const emit = defineEmits(['update:visible', 'cancel', 'submitSuccess']);
const formRef: any = ref(null);
const rules = {
name: [
{
required: true,
message: useI18nPleaseInput('common.name'),
trigger: ['change', 'blur'],
},
],
cron: [
{
required: true,
message: useI18nPleaseInput('machine.cronExpression'),
trigger: ['change', 'blur'],
},
],
status: [
{
required: true,
message: useI18nPleaseSelect('common.status'),
trigger: ['change', 'blur'],
},
],
saveExecResType: [
{
required: true,
message: useI18nPleaseSelect('machine.execResRecordType'),
trigger: ['change', 'blur'],
},
],
script: [
{
required: true,
message: useI18nPleaseInput('machine.script'),
trigger: ['change', 'blur'],
},
],
name: [Rules.requiredInput('common.name')],
cron: [Rules.requiredInput('machine.cronExpression')],
status: [Rules.requiredSelect('common.status')],
saveExecResType: [Rules.requiredSelect('machine.execResRecordType')],
script: [Rules.requiredInput('machine.script')],
};
const state = reactive({

View File

@@ -103,30 +103,13 @@ import { cmdConfApi } from '../api';
import DrawerHeader from '@/components/drawer-header/DrawerHeader.vue';
import TagCodePath from '../../component/TagCodePath.vue';
import _ from 'lodash';
import { useI18nDeleteConfirm, useI18nDeleteSuccessMsg, useI18nFormValidate, useI18nPleaseInput, useI18nSaveSuccessMsg } from '@/hooks/useI18n';
import { useI18nDeleteConfirm, useI18nDeleteSuccessMsg, useI18nFormValidate, useI18nSaveSuccessMsg } from '@/hooks/useI18n';
import { Rules } from '@/common/rule';
const rules = {
tags: [
{
required: true,
message: useI18nPleaseInput('machine.relateMachine'),
trigger: ['change'],
},
],
cmds: [
{
required: true,
message: useI18nPleaseInput('machine.cmd'),
trigger: ['change', 'blur'],
},
],
name: [
{
required: true,
message: useI18nPleaseInput('common.name'),
trigger: ['change', 'blur'],
},
],
tags: [Rules.requiredInput('machine.relateMachine')],
cmds: [Rules.requiredInput('machine.cmd')],
name: [Rules.requiredInput('common.name')],
};
const tagSelectRef: any = ref(null);

View File

@@ -56,8 +56,9 @@ import { mongoApi } from './api';
import { ElMessage } from 'element-plus';
import TagTreeSelect from '../component/TagTreeSelect.vue';
import SshTunnelSelect from '../component/SshTunnelSelect.vue';
import { useI18nFormValidate, useI18nPleaseInput, useI18nPleaseSelect, useI18nSaveSuccessMsg } from '@/hooks/useI18n';
import { useI18nFormValidate, useI18nSaveSuccessMsg } from '@/hooks/useI18n';
import { useI18n } from 'vue-i18n';
import { Rules } from '@/common/rule';
const { t } = useI18n();
@@ -77,27 +78,9 @@ const props = defineProps({
const emit = defineEmits(['update:visible', 'cancel', 'val-change']);
const rules = {
tagCodePaths: [
{
required: true,
message: useI18nPleaseSelect('tag.relateTag'),
trigger: ['change', 'blur'],
},
],
name: [
{
required: true,
message: useI18nPleaseInput('common.name'),
trigger: ['change', 'blur'],
},
],
uri: [
{
required: true,
message: useI18nPleaseInput('mongo.connUrl'),
trigger: ['change', 'blur'],
},
],
tagCodePaths: [Rules.requiredSelect('tag.relateTag')],
name: [Rules.requiredInput('common.name')],
uri: [Rules.requiredInput('mongo.connUrl')],
};
const mongoForm: any = ref(null);

View File

@@ -202,20 +202,15 @@ import { RedisInst } from './redis';
import { useAutoOpenResource } from '@/store/autoOpenResource';
import { storeToRefs } from 'pinia';
import { useI18n } from 'vue-i18n';
import { useI18nDeleteConfirm, useI18nDeleteSuccessMsg, useI18nFormValidate, useI18nOperateSuccessMsg, useI18nPleaseInput } from '@/hooks/useI18n';
import { useI18nDeleteConfirm, useI18nDeleteSuccessMsg, useI18nFormValidate, useI18nOperateSuccessMsg } from '@/hooks/useI18n';
import { Rules } from '@/common/rule';
const KeyDetail = defineAsyncComponent(() => import('./KeyDetail.vue'));
const { t } = useI18n();
const keyFormRules = {
key: [
{
required: true,
message: useI18nPleaseInput('Key'),
trigger: ['change', 'blur'],
},
],
key: [Rules.requiredInput('Key')],
};
const cmCopyKey = new ContextmenuItem('copyValue', 'Copy')

View File

@@ -86,8 +86,9 @@ import { ElMessage } from 'element-plus';
import TagTreeSelect from '../component/TagTreeSelect.vue';
import SshTunnelSelect from '../component/SshTunnelSelect.vue';
import DrawerHeader from '@/components/drawer-header/DrawerHeader.vue';
import { useI18nFormValidate, useI18nPleaseInput, useI18nPleaseSelect, useI18nSaveSuccessMsg } from '@/hooks/useI18n';
import { useI18nFormValidate, useI18nSaveSuccessMsg } from '@/hooks/useI18n';
import { useI18n } from 'vue-i18n';
import { Rules } from '@/common/rule';
const { t } = useI18n();
@@ -106,41 +107,11 @@ const props = defineProps({
const emit = defineEmits(['update:visible', 'val-change', 'cancel']);
const rules = {
tagCodePaths: [
{
required: true,
message: useI18nPleaseSelect('tag.relateTag'),
trigger: ['blur', 'change'],
},
],
name: [
{
required: true,
message: useI18nPleaseInput('common.name'),
trigger: ['change', 'blur'],
},
],
host: [
{
required: true,
message: useI18nPleaseInput('ip:port'),
trigger: ['change', 'blur'],
},
],
db: [
{
required: true,
message: useI18nPleaseSelect('DB'),
trigger: ['change', 'blur'],
},
],
mode: [
{
required: true,
message: useI18nPleaseSelect('mode'),
trigger: ['change', 'blur'],
},
],
tagCodePaths: [Rules.requiredSelect('tag.relateTag')],
name: [Rules.requiredInput('common.name')],
host: [Rules.requiredInput('ip:port')],
db: [Rules.requiredSelect('DB')],
mode: [Rules.requiredSelect('mode')],
};
const redisForm: any = ref(null);

View File

@@ -169,9 +169,9 @@ import {
useI18nDeleteSuccessMsg,
useI18nEditTitle,
useI18nFormValidate,
useI18nPleaseInput,
useI18nSaveSuccessMsg,
} from '@/hooks/useI18n';
import { Rules } from '@/common/rule';
const MachineList = defineAsyncComponent(() => import('../machine/MachineList.vue'));
const InstanceList = defineAsyncComponent(() => import('../db/InstanceList.vue'));
@@ -263,8 +263,8 @@ const props = {
};
const rules = {
code: [{ required: true, message: useI18nPleaseInput('tag.code'), trigger: 'blur' }],
name: [{ required: true, message: useI18nPleaseInput('common.name'), trigger: 'blur' }],
code: [Rules.requiredInput('tag.code')],
name: [Rules.requiredInput('common.name')],
};
onMounted(() => {

View File

@@ -111,7 +111,6 @@
<script lang="ts" setup>
import { ref, toRefs, reactive, onMounted, Ref } from 'vue';
import { tagApi } from './api';
import { ElMessage, ElMessageBox } from 'element-plus';
import { notBlank } from '@/common/assert';
import PageTable from '@/components/pagetable/PageTable.vue';
import { TableColumn } from '@/components/pagetable';
@@ -129,10 +128,9 @@ import {
useI18nEditTitle,
useI18nFormValidate,
useI18nOperateSuccessMsg,
useI18nPleaseInput,
useI18nPleaseSelect,
useI18nSaveSuccessMsg,
} from '@/hooks/useI18n';
import { Rules } from '@/common/rule';
const { t } = useI18n();
@@ -141,20 +139,8 @@ const pageTableRef: Ref<any> = ref(null);
const showMemPageTableRef: Ref<any> = ref(null);
const teamFormRules = {
name: [
{
required: true,
message: useI18nPleaseInput('common.name'),
trigger: ['change', 'blur'],
},
],
validityDate: [
{
required: true,
message: useI18nPleaseSelect('team.validity'),
trigger: ['change', 'blur'],
},
],
name: [Rules.requiredInput('common.name')],
validityDate: [Rules.requiredSelect('team.validity')],
};
const searchItems = [SearchItem.input('name', 'common.name')];

View File

@@ -46,13 +46,9 @@
<script lang="ts" setup>
import { toRefs, reactive, watch, ref, watchEffect } from 'vue';
import { accountApi } from '../api';
import { ElMessage } from 'element-plus';
import { AccountUsernamePattern } from '@/common/pattern';
import { randomPassword } from '@/common/utils/string';
import { useI18n } from 'vue-i18n';
import { useI18nFormValidate, useI18nPleaseInput, useI18nSaveSuccessMsg } from '@/hooks/useI18n';
const { t } = useI18n();
import { useI18nFormValidate, useI18nSaveSuccessMsg } from '@/hooks/useI18n';
import { Rules } from '@/common/rule';
const props = defineProps({
visible: {
@@ -72,32 +68,9 @@ const emit = defineEmits(['update:visible', 'cancel', 'val-change']);
const accountForm: any = ref(null);
const rules = {
name: [
{
required: true,
message: useI18nPleaseInput('system.account.name'),
trigger: ['change', 'blur'],
},
],
username: [
{
required: true,
message: useI18nPleaseInput('common.username'),
trigger: ['change', 'blur'],
},
{
pattern: AccountUsernamePattern.pattern,
message: AccountUsernamePattern.message,
trigger: ['blur'],
},
],
password: [
{
required: true,
message: useI18nPleaseInput('common.password'),
trigger: ['change', 'blur'],
},
],
name: [Rules.requiredInput('system.account.name')],
username: [Rules.requiredInput('common.username'), Rules.accountUsername],
password: [Rules.requiredInput('common.password')],
};
const state = reactive({

View File

@@ -49,23 +49,12 @@ import { ref, toRefs, reactive, watch } from 'vue';
import { configApi, accountApi } from '../api';
import { DynamicFormEdit } from '@/components/dynamic-form';
import DrawerHeader from '@/components/drawer-header/DrawerHeader.vue';
import { useI18nFormValidate, useI18nPleaseInput } from '@/hooks/useI18n';
import { useI18nFormValidate } from '@/hooks/useI18n';
import { Rules } from '@/common/rule';
const rules = {
name: [
{
required: true,
message: useI18nPleaseInput('system.sysconf.confItem'),
trigger: ['change', 'blur'],
},
],
key: [
{
required: true,
message: useI18nPleaseInput('system.sysconf.confKey'),
trigger: ['change', 'blur'],
},
],
name: [Rules.requiredInput('system.sysconf.confItem')],
key: [Rules.requiredInput('system.sysconf.confKey')],
};
const props = defineProps({

View File

@@ -101,6 +101,7 @@ 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';
import { Rules } from '@/common/rule';
const { t } = useI18n();
@@ -139,20 +140,8 @@ const defaultMeta = {
};
const rules = {
name: [
{
required: true,
message: t('system.menu.menuNameRuleMsg'),
trigger: ['change', 'blur'],
},
],
code: [
{
required: true,
message: t('system.menu.codeRuleMsg'),
trigger: ['change', 'blur'],
},
],
name: [Rules.requiredInput('common.name')],
code: [Rules.requiredInput('code')],
};
const trueFalseOption = [

View File

@@ -34,34 +34,14 @@
import { ref, toRefs, reactive, watchEffect } from 'vue';
import { roleApi } from '../api';
import { RoleStatusEnum } from '../enums';
import { useI18n } from 'vue-i18n';
import EnumSelect from '@/components/enumselect/EnumSelect.vue';
import { useI18nFormValidate, useI18nPleaseInput, useI18nPleaseSelect } from '@/hooks/useI18n';
const { t } = useI18n();
import { useI18nFormValidate } from '@/hooks/useI18n';
import { Rules } from '@/common/rule';
const rules = {
name: [
{
required: true,
message: useI18nPleaseInput('system.role.roleName'),
trigger: ['change', 'blur'],
},
],
code: [
{
required: true,
message: useI18nPleaseInput('system.role.roleCode'),
trigger: ['change', 'blur'],
},
],
status: [
{
required: true,
message: useI18nPleaseSelect('common.status'),
trigger: ['change', 'blur'],
},
],
name: [Rules.requiredInput('system.role.roleName')],
code: [Rules.requiredInput('system.role.roleCode')],
status: [Rules.requiredSelect('common.status')],
};
const props = defineProps({