From daae3c89e763d62f3ed0ffe1fbd91c3855919e58 Mon Sep 17 00:00:00 2001
From: lvjunzhao <967725@dms.yudean.com>
Date: Thu, 10 Apr 2025 17:12:15 +0800
Subject: [PATCH 1/6] =?UTF-8?q?feat:=E7=99=BB=E5=BD=95-=E6=96=B0=E5=A2=9E?=
=?UTF-8?q?=E7=94=A8=E6=88=B7=E8=B4=A6=E5=8F=B7=E7=99=BB=E5=BD=95=20?=
=?UTF-8?q?=E9=AA=8C=E8=AF=81=E7=A0=81=20ipBlock=201.=20=E6=96=B0=E5=A2=9E?=
=?UTF-8?q?=20=E7=99=BB=E5=BD=95=E7=9A=84=20=E5=9B=BE=E5=BD=A2=E6=A0=A1?=
=?UTF-8?q?=E9=AA=8C=E7=A0=81=202.=20=E9=81=97=E8=90=BD=E9=97=AE=E9=A2=98?=
=?UTF-8?q?=EF=BC=8C=E7=99=BB=E5=BD=95=E9=A1=B5=E7=9A=84=E6=8F=90=E4=BA=A4?=
=?UTF-8?q?=EF=BC=8C=E8=A1=A8=E5=8D=95=E5=85=A8=E9=83=A8=E7=BB=9F=E4=B8=80?=
=?UTF-8?q?=E4=BA=86=E3=80=82=E6=B2=A1=E6=9C=89=E5=8C=BA=E5=88=86=E7=B1=BB?=
=?UTF-8?q?=E5=9E=8B=EF=BC=8C=E8=80=8C=E4=B8=94=E7=B1=BB=E5=9E=8B=E7=9A=84?=
=?UTF-8?q?=E6=9E=9A=E4=B8=BE=E5=92=8C=E6=A0=A1=E9=AA=8C=E6=B2=A1=E7=9C=9F?=
=?UTF-8?q?=E6=AD=A3=E4=BD=BF=E7=94=A8=E3=80=82=E8=BF=98=E6=9C=89=E5=85=B6?=
=?UTF-8?q?=E4=BB=96=E5=8A=9F=E8=83=BD=E5=A6=82=E6=B3=A8=E5=86=8C=EF=BC=8C?=
=?UTF-8?q?=E6=94=B9=E5=AF=86=E7=A0=81=E9=83=BD=E6=B2=A1=E5=BC=80=E5=87=BA?=
=?UTF-8?q?=E6=9D=A5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/api/system/login/index.ts | 12 ++
src/api/system/login/model/index.ts | 1 +
src/views/secondDev/Login.vue | 5 +
src/views/secondDev/LoginForm.vue | 89 +++++++++++++--
src/views/sys/login/useLogin.ts | 11 ++
src/views/system/loginSetting/loginInfo.vue | 120 ++++++++++++++++++++
6 files changed, 231 insertions(+), 7 deletions(-)
diff --git a/src/api/system/login/index.ts b/src/api/system/login/index.ts
index 87320dc..506fda1 100644
--- a/src/api/system/login/index.ts
+++ b/src/api/system/login/index.ts
@@ -34,6 +34,7 @@ enum Api {
loginConfig = '/system/loginConfig',
mobileLoginCode = '/system/captcha',
mobileLoginImg = '/system/captchaImg',
+ checkAccountCaptcha = '/system/checkAccountCaptcha',
}
/**
@@ -262,3 +263,14 @@ export function sendMobileLoginCode(params, mode: ErrorMessageMode = 'modal') {
},
);
}
+export function checkAccountCaptchaApi(params, mode: ErrorMessageMode = 'modal') {
+ return defHttp.get(
+ {
+ url: Api.checkAccountCaptcha,
+ params: params,
+ },
+ {
+ errorMessageMode: mode,
+ },
+ );
+}
diff --git a/src/api/system/login/model/index.ts b/src/api/system/login/model/index.ts
index b95ba73..9eecbce 100644
--- a/src/api/system/login/model/index.ts
+++ b/src/api/system/login/model/index.ts
@@ -8,6 +8,7 @@ export interface LoginParams {
password: string;
tenantCode: string;
deviceType?: number;
+ captchaCode: string;
}
export interface RoleInfo {
diff --git a/src/views/secondDev/Login.vue b/src/views/secondDev/Login.vue
index ecef95d..7a9bf68 100644
--- a/src/views/secondDev/Login.vue
+++ b/src/views/secondDev/Login.vue
@@ -279,3 +279,8 @@
}
}
+
diff --git a/src/views/secondDev/LoginForm.vue b/src/views/secondDev/LoginForm.vue
index d712a2a..a1e3165 100644
--- a/src/views/secondDev/LoginForm.vue
+++ b/src/views/secondDev/LoginForm.vue
@@ -3,7 +3,7 @@
-
+
@@ -17,6 +17,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
@@ -43,8 +59,10 @@
+
+
+
-
@@ -64,7 +82,7 @@
@@ -118,7 +136,7 @@
import { useUserStore } from '/@/store/modules/user';
import { LoginStateEnum, useLoginState, useFormRules, useFormValid } from '/@/views/sys/login/useLogin';
- import { getMobileLoginCode, getMobileLoginImg, sendMobileLoginCode } from '/@/api/system/login';
+ import { getMobileLoginCode, getMobileLoginImg, sendMobileLoginCode, checkAccountCaptchaApi, } from '/@/api/system/login';
import { useDesign } from '/@/hooks/web/useDesign';
import { Base64 } from 'js-base64';
@@ -126,6 +144,8 @@
import { useRouter } from 'vue-router';
import { getAppEnvConfig } from '/@/utils/env';
import Icon from '/@/components/Icon/index';
+
+ import { PhoneOutlined, PictureOutlined, ReloadOutlined } from '@ant-design/icons-vue';
const ACol = Col;
const ARow = Row;
@@ -138,7 +158,7 @@
const { currentRoute } = useRouter();
- const { getLoginState } = useLoginState();
+ const { getLoginState, setLoginState } = useLoginState();
const { getFormRules } = useFormRules();
const formRef = ref();
@@ -146,6 +166,7 @@
const loading = ref(false);
const rememberMe = ref(false);
const loginType = ref('mobile')
+ const loginUseType = ref();
const countdown = ref(60)
const visible = ref(false);
@@ -153,6 +174,9 @@
const imgObj = ref({
imgBase64: ''
})
+ const captchaImage = ref({
+ imgBase64: ''
+ })
const imgCode = ref('')
const formData = reactive({
@@ -160,7 +184,8 @@
password: '',
mobile: '',
code: '',
- tenantCode: 'system'
+ tenantCode: 'system',
+ captchaCode: ''
});
const getCodeButtonName = ref('获取验证码')
const codeButtonDisabled = ref(false)
@@ -228,6 +253,24 @@
}
}
+ /**
+ * 账号失焦 请求后台获取业务状态
+ */
+ async function handleBlur() {
+ if (!formData.account) {
+ return;
+ }
+ let checkAccountCaptcha = await checkAccountCaptchaApi({username: formData.account})
+ if(checkAccountCaptcha == true) {
+ loginUseType.value = 'captcha';
+ // setLoginState(LoginStateEnum.LOGIN_WITH_CAPTCHA)
+ refreshCaptcha();
+ } else {
+ loginUseType.value = '';
+ // setLoginState(LoginStateEnum.LOGIN)
+ }
+ }
+
function refreshTodo() {
refreshLoading.value = true
onMobileLoginImg()
@@ -236,7 +279,12 @@
// 图形验证
async function onMobileLoginImg() {
- imgObj.value = await getMobileLoginImg({mobile: formData.mobile})
+ imgObj.value = await getMobileLoginImg({account: formData.mobile})
+ }
+
+ // 图形账号验证
+ async function refreshCaptcha() {
+ captchaImage.value = await getMobileLoginImg({account: formData.account})
}
async function handleOk() {
@@ -283,11 +331,22 @@
if (!data) return;
if (loginType.value == 'pw') {
try {
+ // 校验有没带图形验证码提交
+ if (loginUseType.value == 'captcha' && !data.captchaCode) {
+ createErrorModal({
+ title: t('错误提示'),
+ content: '请输入图形验证码',
+ getContainer: () => document.body.querySelector(`.${prefixCls}`) || document.body
+ });
+ return;
+ }
+
loading.value = true;
const userInfo = await userStore.login({
password: data.password,
userName: data.account,
tenantCode: data.tenantCode,
+ captchaCode: data.captchaCode,
deviceType: 0, //pc-0,app-1
mode: 'none' //不要默认的错误提示
});
@@ -309,6 +368,11 @@
}
}
} catch (error) {
+ if ((error as unknown as Error).message.includes('验证码')) {
+ loginUseType.value = 'captcha';
+ // setLoginState(LoginStateEnum.LOGIN_WITH_CAPTCHA);
+ refreshCaptcha();
+ }
createErrorModal({
title: t('错误提示'),
content: (error as unknown as Error).message || t('网络异常,请检查您的网络连接是否正常!'),
@@ -316,6 +380,7 @@
});
} finally {
loading.value = false;
+ handleBlur();
}
} else {
try {
@@ -400,4 +465,14 @@
cursor: pointer;
}
}
+ :deep(.captcha-image) {
+ cursor: pointer;
+ border: 1px solid #ddd;
+ border-radius: 4px;
+ height: 48px;
+ }
+ // :deep(.phone-outlined-class) {
+ // height: 25.99px;
+ // width: 25.99px;
+ // }
diff --git a/src/views/sys/login/useLogin.ts b/src/views/sys/login/useLogin.ts
index 4ab1179..36c8a06 100644
--- a/src/views/sys/login/useLogin.ts
+++ b/src/views/sys/login/useLogin.ts
@@ -9,6 +9,7 @@ export enum LoginStateEnum {
RESET_PASSWORD,
MOBILE,
QR_CODE,
+ LOGIN_WITH_CAPTCHA,
}
const currentState = ref(LoginStateEnum.LOGIN);
@@ -43,6 +44,7 @@ export function useFormRules(formData?: Recordable) {
const getAccountFormRule = computed(() => createRule(t('请输入账号')));
const getPasswordFormRule = computed(() => createRule(t('请输入密码')));
+ const getCaptchaCodeFormRule = computed(() => createRule(t('请输入图形验证码')));
const getSmsFormRule = computed(() => createRule(t('请输入验证码')));
const getMobileFormRule = computed(() => createRule(t('请输入手机号码')));
@@ -65,6 +67,7 @@ export function useFormRules(formData?: Recordable) {
const getFormRules = computed((): { [k: string]: ValidationRule | ValidationRule[] } => {
const accountFormRule = unref(getAccountFormRule);
const passwordFormRule = unref(getPasswordFormRule);
+ const captchaCodeFormRule = unref(getCaptchaCodeFormRule);
const smsFormRule = unref(getSmsFormRule);
const mobileFormRule = unref(getMobileFormRule);
@@ -96,6 +99,14 @@ export function useFormRules(formData?: Recordable) {
case LoginStateEnum.MOBILE:
return mobileRule;
+ // 枚举没实现,暂不适用
+ case LoginStateEnum.LOGIN_WITH_CAPTCHA:
+ return {
+ account: accountFormRule,
+ password: passwordFormRule,
+ captchaCode: captchaCodeFormRule,
+ };
+
// login form rules
default:
return {
diff --git a/src/views/system/loginSetting/loginInfo.vue b/src/views/system/loginSetting/loginInfo.vue
index 3126cc2..f1bf9f8 100644
--- a/src/views/system/loginSetting/loginInfo.vue
+++ b/src/views/system/loginSetting/loginInfo.vue
@@ -117,6 +117,100 @@
/>
+·
+
+
{{ t('密码错误超过最大次数需要填写验证码') }}
+
+
+
+
+ 验证码策略
+
+
+
+
1.登录验证码策略是指在登录过程中出现密码错误情况时的系统处理方式。
+
2.默认“密码错误超过最大次需要验证码登录”的策略状态为启用。
+
3.如果设置验证码最大次数为0 ,即每次登录都需要验证码
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ t('密码错误超过最大次数锁定') }}
+
+
+
+
+
+
+
+
1.锁定ip策略是指在登录过程中出现密码错误情况时的系统处理方式。
+
2.默认“密码错误超过最大次数锁定ip”的策略状态为启用。
+
3.当用户的ip被锁定后,需要等待配置时间恢复后才能重新登录!或者,请联系管理员。
+
+
+
+
+
+
+
+
+
+
+
+
{{ t('提交') }}
@@ -145,6 +239,11 @@
withoutLogin?: number;
strategyMaxNumber?: number | null;
passwordStrategy?: number;
+ checkErrorLoginCaptcha?: boolean;
+ checkErrorLoginCaptchaCount?: number | null;
+ checkErrorLoginBlockIp?: boolean;
+ checkErrorLoginBlockIpCount?: number | null;
+ checkErrorLoginBlockIpRestoreTime?: number | null;
}
let formState = ref({});
@@ -162,6 +261,11 @@
withoutLogin: res.withoutLogin,
strategyMaxNumber: res.strategyMaxNumber,
passwordStrategy: res.passwordStrategy,
+ checkErrorLoginCaptcha: res.checkErrorLoginCaptcha,
+ checkErrorLoginCaptchaCount: res.checkErrorLoginCaptchaCount,
+ checkErrorLoginBlockIp: res.checkErrorLoginBlockIp,
+ checkErrorLoginBlockIpCount: res.checkErrorLoginBlockIpCount,
+ checkErrorLoginBlockIpRestoreTime: res.checkErrorLoginBlockIpRestoreTime,
};
id.value = res.id;
});
@@ -198,6 +302,22 @@
}
}
+ function handleCaptchaClick() {
+ if (formState.value.checkErrorLoginCaptcha) {
+ formState.value.checkErrorLoginCaptcha = false;
+ } else {
+ formState.value.checkErrorLoginCaptcha = true;
+ }
+ }
+
+ function handleBlockIpClick() {
+ if (formState.value.checkErrorLoginBlockIp) {
+ formState.value.checkErrorLoginBlockIp = false;
+ } else {
+ formState.value.checkErrorLoginBlockIp = true;
+ }
+ }
+
function handleClick(val) {
if (proDisabled.value) return;
if (formState.value.mulLogin?.includes(val)) {
From c197cf79052854abe235be69ccf8bf70624c1366 Mon Sep 17 00:00:00 2001
From: lvjunzhao <967725@dms.yudean.com>
Date: Mon, 14 Apr 2025 16:51:22 +0800
Subject: [PATCH 2/6] =?UTF-8?q?feat:=E6=96=B0=E5=A2=9E=20=E5=85=A8?=
=?UTF-8?q?=E5=B1=80=E4=BC=9A=E7=AD=BE=20=E5=9B=9E=E8=B0=83=20=E5=92=8C=20?=
=?UTF-8?q?=E8=8A=82=E7=82=B9=E4=B8=8A=E7=9A=84=20=E4=BC=9A=E7=AD=BE?=
=?UTF-8?q?=EF=BC=8C=E9=A2=84=E5=AE=A1=EF=BC=8C=E5=90=8C=E6=84=8F=EF=BC=8C?=
=?UTF-8?q?=E9=80=80=E5=9B=9E=E7=9A=84=E5=9B=9E=E8=B0=83?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/model/workflow/workflowConfig.ts | 6 +
.../design/bpmn/components/BasicPanel.vue | 382 +++++++++++++++++-
.../design/bpmn/config/propertyConfig.ts | 6 +
.../bpmn/panel/process/globalEvent/Index.vue | 84 +++-
4 files changed, 473 insertions(+), 5 deletions(-)
diff --git a/src/model/workflow/workflowConfig.ts b/src/model/workflow/workflowConfig.ts
index d40fba5..389f10b 100644
--- a/src/model/workflow/workflowConfig.ts
+++ b/src/model/workflow/workflowConfig.ts
@@ -114,6 +114,7 @@ export interface ProcessConfig {
globalAgreeEventConfigs: NodeEventConfig[];//全局同意事件
globalSuspendedEventConfigs: NodeEventConfig[];//全局 挂起/暂停事件
globalRestoreEventConfigs: NodeEventConfig[];//全局 恢复事件
+ globalSetSignEventConfigs: NodeEventConfig[];//全局 会签事件
xmlContent: String; //xml
}
@@ -287,6 +288,11 @@ export interface BasicNodeConfig {
remark: string; //节点描述
startEventConfigs: NodeEventConfig[];
endEventConfigs: NodeEventConfig[];
+ prequalifyBeforeEventConfigs: [],//预审前
+ prequalifyAfterEventConfigs: [],//预审后
+ rejectEventConfigs: [],//全局退回事件
+ agreeEventConfigs: [],//全局同意事件
+ setSignEventConfigs: [],//全局 会签事件
}
export interface NodeEventConfig {
diff --git a/src/views/workflow/design/bpmn/components/BasicPanel.vue b/src/views/workflow/design/bpmn/components/BasicPanel.vue
index 4fe53ad..9098abd 100644
--- a/src/views/workflow/design/bpmn/components/BasicPanel.vue
+++ b/src/views/workflow/design/bpmn/components/BasicPanel.vue
@@ -51,6 +51,7 @@
{{ t('执行API') }}
{{ t('规则引擎') }}
+ {{ t('类注入') }}
@@ -76,6 +77,11 @@
:options="liteFlowOptions"
:field-names="{ label: 'chainName', value: 'id' }"
/>
+
@@ -105,6 +111,7 @@
{{ t('执行API') }}
{{ t('规则引擎') }}
+ {{ t('类注入') }}
@@ -130,6 +137,11 @@
:options="liteFlowOptions"
:field-names="{ label: 'chainName', value: 'id' }"
/>
+
@@ -137,6 +149,306 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ t('执行API') }}
+ {{ t('规则引擎') }}
+ {{ t('类注入') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ t('执行API') }}
+ {{ t('规则引擎') }}
+ {{ t('类注入') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ t('执行API') }}
+ {{ t('规则引擎') }}
+ {{ t('类注入') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ t('执行API') }}
+ {{ t('规则引擎') }}
+ {{ t('类注入') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ t('执行API') }}
+ {{ t('规则引擎') }}
+ {{ t('类注入') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -167,6 +479,9 @@
import Sortable from 'sortablejs';
import { NodeEventExType } from '/@/enums/workflowEnum';
import { NodeEventConfig } from '/@/model/workflow/workflowConfig';
+ import {
+ BpmnNodeKey,
+ } from '/@/enums/workflowEnum';
const { t } = useI18n();
const { showPanel, formInfo, nodeName } = useStateFormInfo();
const updateElementName = inject('updateElementName') as any;
@@ -222,7 +537,12 @@
() => {
if (
formInfo.value.endEventConfigs?.length > 0 ||
- formInfo.value.startEventConfigs?.length > 0
+ formInfo.value.startEventConfigs?.length > 0 ||
+ formInfo.value.setSignEventConfigs?.length > 0 ||
+ formInfo.value.prequalifyBeforeEventConfigs?.length > 0 ||
+ formInfo.value.prequalifyAfterEventConfigs?.length > 0 ||
+ formInfo.value.agreeEventConfigs?.length > 0 ||
+ formInfo.value.rejectEventConfigs?.length > 0
) {
nextTick(() => {
const tbody: any = document.querySelector('.ant-table-tbody');
@@ -246,6 +566,66 @@
const getList = async () => {
liteFlowOptions.value = (await getLiteflowList()) || [];
};
+
+ //新增会签 因为旧值中不包含,所以html 判断node节点,这里对add 可以新增空数组
+ const addSetSignEvent = () => {
+ formInfo.value.setSignEventConfigs = formInfo.value.setSignEventConfigs==null?[]:formInfo.value.setSignEventConfigs;
+ formInfo.value.setSignEventConfigs.push({
+ type: NodeEventExType.API,
+ apiConfig: {},
+ } as NodeEventConfig);
+ };
+ const deleteSetSignEvent = (index) => {
+ formInfo.value.setSignEventConfigs.splice(index, 1);
+ };
+
+ // 预审前 因为旧值中不包含,所以html 判断node节点,这里对add 可以新增空数组
+ const addPrequalifyBeforeEvent = () => {
+ formInfo.value.prequalifyBeforeEventConfigs = formInfo.value.prequalifyBeforeEventConfigs==null?[]:formInfo.value.prequalifyBeforeEventConfigs;
+ formInfo.value.prequalifyBeforeEventConfigs.push({
+ type: NodeEventExType.API,
+ apiConfig: {},
+ } as NodeEventConfig);
+ };
+ const deletePrequalifyBeforeEvent = (index) => {
+ formInfo.value.prequalifyBeforeEventConfigs.splice(index, 1);
+ };
+
+ // 预审后 因为旧值中不包含,所以html 判断node节点,这里对add 可以新增空数组
+ const addPrequalifyAfterEvent = () => {
+ formInfo.value.prequalifyAfterEventConfigs = formInfo.value.prequalifyAfterEventConfigs==null?[]:formInfo.value.prequalifyAfterEventConfigs;
+ formInfo.value.prequalifyAfterEventConfigs.push({
+ type: NodeEventExType.API,
+ apiConfig: {},
+ } as NodeEventConfig);
+ };
+ const deletePrequalifyAfterEvent = (index) => {
+ formInfo.value.prequalifyAfterEventConfigs.splice(index, 1);
+ };
+
+ // 同意 因为旧值中不包含,所以html 判断node节点,这里对add 可以新增空数组
+ const addAgreeEvent = () => {
+ formInfo.value.agreeEventConfigs = formInfo.value.agreeEventConfigs==null?[]:formInfo.value.agreeEventConfigs;
+ formInfo.value.agreeEventConfigs.push({
+ type: NodeEventExType.API,
+ apiConfig: {},
+ } as NodeEventConfig);
+ };
+ const deleteAgreeEvent = (index) => {
+ formInfo.value.agreeEventConfigs.splice(index, 1);
+ };
+
+ // 退回 因为旧值中不包含,所以html 判断node节点,这里对add 可以新增空数组
+ const addRejectEvent = () => {
+ formInfo.value.rejectEventConfigs = formInfo.value.rejectEventConfigs==null?[]:formInfo.value.rejectEventConfigs;
+ formInfo.value.rejectEventConfigs.push({
+ type: NodeEventExType.API,
+ apiConfig: {},
+ } as NodeEventConfig);
+ };
+ const deleteRejectEvent = (index) => {
+ formInfo.value.rejectEventConfigs.splice(index, 1);
+ };
\ No newline at end of file
+
diff --git a/src/views/system/group/components/Form.vue b/src/views/system/group/components/Form.vue
index 315841f..7664367 100644
--- a/src/views/system/group/components/Form.vue
+++ b/src/views/system/group/components/Form.vue
@@ -110,8 +110,8 @@
await systemFormRef.value.resetFields();
}
// 设置表单数据全部为Disabled 【查看】
- async function setDisabledForm() {
- data.formDataProps.schemas = changeSchemaDisabled(cloneDeep(data.formDataProps.schemas));
+ async function setDisabledForm(isDisabled) {
+ data.formDataProps.schemas = changeSchemaDisabled(cloneDeep(data.formDataProps.schemas), isDisabled);
}
// 获取行键值
function getRowKey() {
diff --git a/src/views/workflow/task/ProcessMonitor.vue b/src/views/workflow/task/ProcessMonitor.vue
index a70baec..53b3dda 100644
--- a/src/views/workflow/task/ProcessMonitor.vue
+++ b/src/views/workflow/task/ProcessMonitor.vue
@@ -57,7 +57,11 @@
-
+
{{ t('关闭') }}
-
+
@@ -22,20 +22,20 @@
import { onActivated, onMounted, ref } from 'vue';
import { useI18n } from '/@/hooks/web/useI18n';
const { t } = useI18n();
- const props = defineProps({
- processId: {
- type: String,
- default: ''
- },
- taskId: {
- type: String,
- default: ''
- },
- visible: {
- type: Boolean,
- default: false
- },
- })
+ const props = withDefaults(
+ defineProps<{
+ processId: string;
+ taskId: string;
+ schemaId: string;
+ visible?: boolean;
+ }>(),
+ {
+ processId: '',
+ taskId: '',
+ schemaId: '',
+ visible: false,
+ },
+);
let emits = defineEmits(['close']);
let visible = ref(false);
let showLoading = ref(false);
diff --git a/src/views/workflow/task/components/WorkflowApprovalProcess.vue b/src/views/workflow/task/components/WorkflowApprovalProcess.vue
index 1c03108..3f2f50b 100644
--- a/src/views/workflow/task/components/WorkflowApprovalProcess.vue
+++ b/src/views/workflow/task/components/WorkflowApprovalProcess.vue
@@ -10,6 +10,7 @@
:taskRecords="data.taskRecords"
:predecessorTasks="selectedPredecessorTasks"
:processId="props.processId"
+ :schemaId="props.schemaId"
position="top"
>
-
{{ item.formName }}
+
+
+
{{ item.formName }}
@@ -38,25 +39,11 @@
-
-
-
-
+
+
@@ -383,7 +370,7 @@
};
}
- function handleCancel() {
+function handleCancel() {
itemRefs.value[activeIndex.value].setDisabledForm(true);
forms.modes[activeIndex.value] = 'view';
itemRefs.value[activeIndex.value].setFieldsValue(forms.formModels[activeIndex.value]);
diff --git a/src/views/workflow/task/components/flow/LookTask.vue b/src/views/workflow/task/components/flow/LookTask.vue
index b38ecd7..cfc735e 100644
--- a/src/views/workflow/task/components/flow/LookTask.vue
+++ b/src/views/workflow/task/components/flow/LookTask.vue
@@ -1,5 +1,5 @@
-
+ :currentTaskInfo="data.currentTaskInfo"
+ :currentTaskAssigneeNames="data.currentTaskAssigneeNames"
+ :currentTaskAssignees="data.currentTaskAssignees"
+ :schemaId="props.schemaId"
+ :formDataId="data.formInfos[0].formData.id"
+ :formInfos="data.formInfos">
{
@@ -32,6 +37,7 @@
let res = await getApprovalProcess(props.taskId, props.processId);
initProcessData(res);
visible.value = true;
+ console.error('555555', data)
} catch (error) {}
});
From 08b7f35d2af1b14eb22a872afa3cc7d3be7d4ed9 Mon Sep 17 00:00:00 2001
From: lvjunzhao <967725@dms.yudean.com>
Date: Fri, 18 Apr 2025 16:53:12 +0800
Subject: [PATCH 6/6] =?UTF-8?q?fixbug:=E6=9D=83=E9=99=90=E4=BF=AE=E6=94=B9?=
=?UTF-8?q?=E7=9A=84bug=EF=BC=8C=E5=85=A8=E9=87=8F=E6=8F=90=E4=BA=A4?=
=?UTF-8?q?=E6=B2=A1=E7=82=B9=E5=87=BB=E6=97=B6=E5=80=99=E4=B8=A2=E5=A4=B1?=
=?UTF-8?q?=E5=AD=90=E8=8A=82=E7=82=B9=E7=9A=84=E6=8C=89=E9=92=AE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../system/role/components/RoleAuthModal.vue | 36 +++++++++++++------
1 file changed, 26 insertions(+), 10 deletions(-)
diff --git a/src/views/system/role/components/RoleAuthModal.vue b/src/views/system/role/components/RoleAuthModal.vue
index 1818896..b11739d 100644
--- a/src/views/system/role/components/RoleAuthModal.vue
+++ b/src/views/system/role/components/RoleAuthModal.vue
@@ -186,7 +186,7 @@
});
findMenuTree(buttonSelectData.value, treeData.value, btnCheckedKey, 'button');
}
- btnKeys.value = btnCheckedKey;
+ btnKeys.value = Array.from(new Set([...btnKeys.value, ...btnCheckedKey]));
let lostColKey = [];
colKeys.value.forEach((o) => {
@@ -205,7 +205,7 @@
});
findMenuTree(columnSelectData.value, treeData.value, colCheckedKey, 'column');
}
- colKeys.value = colCheckedKey;
+ colKeys.value = Array.from(new Set([...colKeys.value, ...colCheckedKey]));
let lostFieldKey = [];
fieldKeys.value.forEach((o) => {
@@ -224,7 +224,7 @@
});
findMenuTree(fieldSelectData.value, treeData.value, fieldCheckedKey, 'field');
}
- fieldKeys.value = fieldCheckedKey;
+ fieldKeys.value = Array.from(new Set([...fieldKeys.value, ...fieldCheckedKey]));
nextTick(() => {
getTree(unref(ButtonRef))?.setCheckedKeys(authList.buttonIds);
@@ -289,6 +289,11 @@
// colKeys.value = getTree(unref(ColumnRef)).getCheckedKeys();
// fieldKeys.value = getTree(unref(FieldRef)).getCheckedKeys();
+ // 过滤无效的权限 ID
+ btnKeys.value = btnKeys.value.filter((o) => btnFilterKeys.value.includes(o));
+ colKeys.value = colKeys.value.filter((o) => colFilterKeys.value.includes(o));
+ fieldKeys.value = fieldKeys.value.filter((o) => fieldFilterKeys.value.includes(o));
+
// btnKeys.value = btnKeys.value.filter((o) => {
// return btnFilterKeys.value.includes(o);
// });
@@ -299,6 +304,7 @@
// return fieldFilterKeys.value.includes(o);
// });
+ // 提交更新后的权限数据
await RoleSetAuth({
id: rowId.value,
type: typeKey.value == 4?NaN:typeKey.value,
@@ -307,6 +313,7 @@
columnIds: colKeys.value,
formIds: fieldKeys.value,
});
+
notification.success({
message: t('提示'),
description: t('功能授权更新成功'),
@@ -362,14 +369,23 @@
colFilterKeys.value = [];
fieldFilterKeys.value = [];
- findMenuTree(buttonSelectData.value, treeData.value, addMenuSelect, 'button');
- findMenuTree(columnSelectData.value, treeData.value, addMenuSelect, 'column');
- findMenuTree(fieldSelectData.value, treeData.value, addMenuSelect, 'field');
+ // 使用 Set 合并已选中和新增选中的菜单,避免重复
+ const allMenuKeys = new Set([...menuKeys.value, ...addMenuSelect]);
- let newBtnSelect = [...new Set([...btnKeys.value, ...addMenuSelect])];
- getTree(unref(ButtonRef))?.setExpandedKeys(newBtnSelect);
- getTree(unref(ColumnRef))?.setExpandedKeys([...new Set([...colKeys.value, ...addMenuSelect])]);
- getTree(unref(FieldRef))?.setExpandedKeys([...new Set([...fieldKeys.value, ...addMenuSelect])]);
+ // 确保未选中菜单的子节点不会丢失
+ findMenuTree(buttonSelectData.value, treeData.value, Array.from(allMenuKeys), 'button');
+ findMenuTree(columnSelectData.value, treeData.value, Array.from(allMenuKeys), 'column');
+ findMenuTree(fieldSelectData.value, treeData.value, Array.from(allMenuKeys), 'field');
+
+ // 更新按钮、字段、表单的选中状态
+ btnKeys.value = Array.from(new Set([...btnKeys.value, ...addMenuSelect]));
+ colKeys.value = Array.from(new Set([...colKeys.value, ...addMenuSelect]));
+ fieldKeys.value = Array.from(new Set([...fieldKeys.value, ...addMenuSelect]));
+
+ // 扩展树的展开状态
+ getTree(unref(ButtonRef))?.setExpandedKeys(Array.from(allMenuKeys));
+ getTree(unref(ColumnRef))?.setExpandedKeys(Array.from(allMenuKeys));
+ getTree(unref(FieldRef))?.setExpandedKeys(Array.from(allMenuKeys));
}
function getParentKeys(checkedKey, arr, keys) {
for (let i = 0; i < arr.length; i++) {