From 3cac94ef8ce5688b46e7b297165b96125ac7a334 Mon Sep 17 00:00:00 2001 From: panda <1565636758@qq.com> Date: Mon, 24 Mar 2025 15:47:48 +0800 Subject: [PATCH 001/161] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=A4=B4=E9=83=A8?= =?UTF-8?q?=E4=B8=BB=E9=A2=98=E6=B7=B1=E8=89=B2=E6=A8=A1=E5=BC=8F=E4=B8=8B?= =?UTF-8?q?=EF=BC=8C=E9=A1=B6=E9=83=A8=E5=B7=A5=E5=85=B7=E6=A0=8F=E7=9A=84?= =?UTF-8?q?=E6=90=9C=E7=B4=A2=E3=80=81=E6=B6=88=E6=81=AF=E6=B2=A1=E6=9C=89?= =?UTF-8?q?=E4=BC=A0=E4=B8=BB=E9=A2=98=E8=89=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/RouterSearch/index.vue | 6 ++++-- src/layout/components/Message/src/Message.vue | 7 ++++++- src/layout/components/ToolHeader.vue | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/components/RouterSearch/index.vue b/src/components/RouterSearch/index.vue index 42a41744d..52425ec99 100644 --- a/src/components/RouterSearch/index.vue +++ b/src/components/RouterSearch/index.vue @@ -18,7 +18,7 @@
- + \ No newline at end of file diff --git a/src/components/Verifition/src/Verify/index.ts b/src/components/Verifition/src/Verify/index.ts index 0daa63a56..e027ab3fd 100644 --- a/src/components/Verifition/src/Verify/index.ts +++ b/src/components/Verifition/src/Verify/index.ts @@ -1,4 +1,5 @@ import VerifySlide from './VerifySlide.vue' import VerifyPoints from './VerifyPoints.vue' +import VerifyPictureWord from './VerifyPictureWord.vue' -export { VerifySlide, VerifyPoints } +export { VerifySlide, VerifyPoints, VerifyPictureWord } \ No newline at end of file diff --git a/src/locales/en.ts b/src/locales/en.ts index 505cfd80d..bd4c0b42c 100644 --- a/src/locales/en.ts +++ b/src/locales/en.ts @@ -146,9 +146,11 @@ export default { invalidTenantName:"Invalid Tenant Name" }, captcha: { + verify: 'Verify', verification: 'Please complete security verification', slide: 'Swipe right to complete verification', point: 'Please click', + code: 'Please enter the verification code', success: 'Verification succeeded', fail: 'verification failed' }, @@ -457,4 +459,4 @@ export default { btn_zoom_out: 'Zoom out', preview: 'Preivew' } -} +} \ No newline at end of file diff --git a/src/locales/zh-CN.ts b/src/locales/zh-CN.ts index 768b5879a..3b6c2e904 100644 --- a/src/locales/zh-CN.ts +++ b/src/locales/zh-CN.ts @@ -147,9 +147,11 @@ export default { invalidTenantName: '无效的租户名称' }, captcha: { + verify: '验证', verification: '请完成安全验证', slide: '向右滑动完成验证', point: '请依次点击', + code: '请输入验证码', success: '验证成功', fail: '验证失败' }, @@ -453,4 +455,4 @@ export default { preview: '预览' }, 'OAuth 2.0': 'OAuth 2.0' // 避免菜单名是 OAuth 2.0 时,一直 warn 报错 -} +} \ No newline at end of file From dd5bfbc8591813fdcf10821545e998c997509d3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B1=B1=E9=87=8E=E7=BE=A1=E6=B0=91?= Date: Mon, 28 Jul 2025 07:15:32 +0000 Subject: [PATCH 005/161] =?UTF-8?q?fix:=20=E6=B3=A8=E5=86=8C=E8=A1=A8?= =?UTF-8?q?=E5=8D=95=E6=A0=A1=E9=AA=8C=E6=9C=AA=E5=A4=B1=E6=95=88=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 山野羡民 --- src/views/Login/components/RegisterForm.vue | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/views/Login/components/RegisterForm.vue b/src/views/Login/components/RegisterForm.vue index 0636a1c82..6a77cfbfc 100644 --- a/src/views/Login/components/RegisterForm.vue +++ b/src/views/Login/components/RegisterForm.vue @@ -38,7 +38,7 @@ - + { loading.value = true @@ -183,6 +185,11 @@ const handleRegister = async (params: any) => { registerData.registerForm.captchaVerification = params.captchaVerification } + const data = await validForm() + if (!data) { + return + } + const res = await LoginApi.register(registerData.registerForm) if (!res) { return @@ -242,7 +249,6 @@ const getTenantByWebsite = async () => { } } } -const loading = ref() // ElLoading.service 返回的实例 watch( () => currentRoute.value, From a164509565a72d310520bc8bcb2b3c435a439a53 Mon Sep 17 00:00:00 2001 From: LesanOuO <1960681385@qq.com> Date: Sat, 2 Aug 2025 14:15:34 +0800 Subject: [PATCH 006/161] =?UTF-8?q?feat:=20=E5=B7=A5=E4=BD=9C=E6=B5=81?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=AE=A1=E6=89=B9=E4=BA=BA=E6=92=A4=E5=9B=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/bpm/task/index.ts | 5 ++++ src/views/bpm/model/form/ExtraSettings.vue | 29 ++++++++++++++++------ src/views/bpm/model/form/index.vue | 10 +++++--- src/views/bpm/task/done/index.vue | 12 ++++++++- 4 files changed, 43 insertions(+), 13 deletions(-) diff --git a/src/api/bpm/task/index.ts b/src/api/bpm/task/index.ts index a818ae5aa..713400fc4 100644 --- a/src/api/bpm/task/index.ts +++ b/src/api/bpm/task/index.ts @@ -106,6 +106,11 @@ export const copyTask = async (data: any) => { return await request.put({ url: '/bpm/task/copy', data }) } +// 撤回 +export const withdrawTask = async (taskId: string) => { + return await request.put({ url: '/bpm/task/withdraw', params: { taskId } }) +} + // 获取我的待办任务 export const myTodoTask = async (processInstanceId: string) => { return await request.get({ url: '/bpm/task/my-todo?processInstanceId=' + processInstanceId }) diff --git a/src/views/bpm/model/form/ExtraSettings.vue b/src/views/bpm/model/form/ExtraSettings.vue index 9c5beaf60..b6536d16d 100644 --- a/src/views/bpm/model/form/ExtraSettings.vue +++ b/src/views/bpm/model/form/ExtraSettings.vue @@ -11,6 +11,17 @@
+ + +
+ +
+ 审批人可撤回正在审批节点的前一节点 +
+
+
@@ -48,7 +48,7 @@ * */ import { resetSize } from '../utils/util'; import { aesEncrypt } from '../utils/ase'; -import { getCode, reqCheck } from 'src/api/login'; +import { getCode, reqCheck } from '@/api/login'; import { getCurrentInstance, nextTick, onMounted, reactive, ref, toRefs } from 'vue'; const props = defineProps({ diff --git a/src/views/Login/components/LoginForm.vue b/src/views/Login/components/LoginForm.vue index 3c4e1d1a9..cb4dd429a 100644 --- a/src/views/Login/components/LoginForm.vue +++ b/src/views/Login/components/LoginForm.vue @@ -177,7 +177,8 @@ const permissionStore = usePermissionStore() const redirect = ref('') const loginLoading = ref(false) const verify = ref() -const captchaType = ref('blockPuzzle') // blockPuzzle 滑块 clickWord 点击文字 +const captchaType = ref('pictureWord') // blockPuzzle 滑块 clickWord 点击文字 pictureWord 文字验证码 +// const captchaType = ref('blockPuzzle') // blockPuzzle 滑块 clickWord 点击文字 pictureWord 文字验证码 const getShow = computed(() => unref(getLoginState) === LoginStateEnum.LOGIN) @@ -360,4 +361,4 @@ onMounted(() => { cursor: pointer; } } - + \ No newline at end of file From ca17d5ac219ada85c89eaf2b561a3a643c51dd50 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 2 Aug 2025 22:08:32 +0800 Subject: [PATCH 008/161] =?UTF-8?q?feat=EF=BC=9A=E3=80=90bpm=20=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C=E6=B5=81=E3=80=91=E5=AE=A1=E6=89=B9=E4=BA=BA=E8=87=AA?= =?UTF-8?q?=E9=80=89=E6=97=B6=EF=BC=8C=E7=9B=B8=E5=90=8C=E8=8A=82=E7=82=B9?= =?UTF-8?q?=E5=85=B1=E4=BA=AB=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../detail/ProcessInstanceOperationButton.vue | 23 ++++++++++++ .../detail/ProcessInstanceTimeline.vue | 35 ++++++++++++++----- 2 files changed, 49 insertions(+), 9 deletions(-) diff --git a/src/views/bpm/processInstance/detail/ProcessInstanceOperationButton.vue b/src/views/bpm/processInstance/detail/ProcessInstanceOperationButton.vue index 7a5559386..1b7d5c73d 100644 --- a/src/views/bpm/processInstance/detail/ProcessInstanceOperationButton.vue +++ b/src/views/bpm/processInstance/detail/ProcessInstanceOperationButton.vue @@ -51,8 +51,10 @@ >
@@ -571,6 +573,7 @@ const approveFormRef = ref() const signRef = ref() const approveSignFormRef = ref() const nextAssigneesActivityNode = ref([]) // 下一个审批节点信息 +const nextAssigneesTimelineRef = ref() // 下一个节点审批人时间线组件的引用 const approveReasonForm = reactive({ reason: '', signPicUrl: '', @@ -717,6 +720,10 @@ const closePopover = (type: string, formRef: FormInstance | undefined) => { } popOverVisible.value[type] = false nextAssigneesActivityNode.value = [] + // 清理 Timeline 组件中的自定义审批人数据 + if (nextAssigneesTimelineRef.value) { + nextAssigneesTimelineRef.value.batchSetCustomApproveUsers({}) + } } /** 流程通过时,根据表单变量查询新的流程节点,判断下一个节点类型是否为自选审批人 */ @@ -729,6 +736,7 @@ const initNextAssigneesFormField = async () => { processVariablesStr: JSON.stringify(variables) }) if (data && data.length > 0) { + const customApproveUsersData: Record = {} // 用于收集需要设置到 Timeline 组件的自定义审批人数据 data.forEach((node: any) => { if ( // 情况一:当前节点没有审批人,并且是发起人自选 @@ -740,7 +748,18 @@ const initNextAssigneesFormField = async () => { ) { nextAssigneesActivityNode.value.push(node) } + + // 如果节点有 candidateUsers,设置到 customApproveUsers 中 + if (node.candidateUsers && node.candidateUsers.length > 0) { + customApproveUsersData[node.id] = node.candidateUsers + } }) + + // 将 candidateUsers 设置到 Timeline 组件中 + await nextTick() // 等待下一个 tick,确保 Timeline 组件已经渲染 + if (nextAssigneesTimelineRef.value && Object.keys(customApproveUsersData).length > 0) { + nextAssigneesTimelineRef.value.batchSetCustomApproveUsers(customApproveUsersData) + } } } @@ -803,6 +822,10 @@ const handleAudit = async (pass: boolean, formRef: FormInstance | undefined) => await TaskApi.approveTask(data) popOverVisible.value.approve = false nextAssigneesActivityNode.value = [] + // 清理 Timeline 组件中的自定义审批人数据 + if (nextAssigneesTimelineRef.value) { + nextAssigneesTimelineRef.value.batchSetCustomApproveUsers({}) + } message.success('审批通过成功') } else { // 审批不通过数据 diff --git a/src/views/bpm/processInstance/detail/ProcessInstanceTimeline.vue b/src/views/bpm/processInstance/detail/ProcessInstanceTimeline.vue index 8f55c6c4b..91f333e8e 100644 --- a/src/views/bpm/processInstance/detail/ProcessInstanceTimeline.vue +++ b/src/views/bpm/processInstance/detail/ProcessInstanceTimeline.vue @@ -15,7 +15,7 @@ >
@@ -55,13 +55,13 @@ class="flex flex-wrap gap2 items-center" v-if=" isEmpty(activity.tasks) && - isEmpty(activity.candidateUsers) && - (CandidateStrategy.START_USER_SELECT === activity.candidateStrategy || - CandidateStrategy.APPROVE_USER_SELECT === activity.candidateStrategy) + ((CandidateStrategy.START_USER_SELECT === activity.candidateStrategy && + isEmpty(activity.candidateUsers)) || + (props.enableApproveUserSelect && + CandidateStrategy.APPROVE_USER_SELECT === activity.candidateStrategy)) " > -
@@ -165,7 +165,7 @@
@@ -198,13 +198,15 @@ import transactorSvg from '@/assets/svgs/bpm/transactor.svg' import childProcessSvg from '@/assets/svgs/bpm/child-process.svg' defineOptions({ name: 'BpmProcessInstanceTimeline' }) -withDefaults( +const props = withDefaults( defineProps<{ activityNodes: ProcessInstanceApi.ApprovalNodeInfo[] // 审批节点信息 showStatusIcon?: boolean // 是否显示头像右下角状态图标 + enableApproveUserSelect?: boolean // 是否开启审批人自选功能 }>(), { - showStatusIcon: true // 默认值为 true + showStatusIcon: true, // 默认值为 true + enableApproveUserSelect: false // 默认值为 false } ) const { push } = useRouter() // 路由 @@ -341,4 +343,19 @@ const handleChildProcess = (activity: any) => { } }) } + +/** 设置自定义审批人 */ +const setCustomApproveUsers = (activityId: string, users: any[]) => { + customApproveUsers.value[activityId] = users || [] +} + +/** 批量设置多个节点的自定义审批人 */ +const batchSetCustomApproveUsers = (data: Record) => { + Object.keys(data).forEach((activityId) => { + customApproveUsers.value[activityId] = data[activityId] || [] + }) +} + +// 暴露方法给父组件 +defineExpose({ setCustomApproveUsers, batchSetCustomApproveUsers }) From dd6c7481f8a16d71cece00f6679eb3722ec752d0 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 3 Aug 2025 15:29:04 +0800 Subject: [PATCH 009/161] =?UTF-8?q?fix=EF=BC=9A=E3=80=90mall=20=E5=95=86?= =?UTF-8?q?=E5=9F=8E=E3=80=91=E5=BA=97=E9=93=BA=E8=A3=85=E4=BF=AE=E6=97=B6?= =?UTF-8?q?=EF=BC=8Cforce-fallback=20=E6=8B=96=E6=8B=BD=E9=97=AE=E9=A2=98?= =?UTF-8?q?=EF=BC=8Chttps://t.zsxq.com/ue8Qv?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/DiyEditor/components/ComponentLibrary.vue | 2 +- src/components/DiyEditor/index.vue | 2 +- src/components/Draggable/index.vue | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/DiyEditor/components/ComponentLibrary.vue b/src/components/DiyEditor/components/ComponentLibrary.vue index fdb0b1de3..06f231285 100644 --- a/src/components/DiyEditor/components/ComponentLibrary.vue +++ b/src/components/DiyEditor/components/ComponentLibrary.vue @@ -17,7 +17,7 @@ :group="{ name: 'component', pull: 'clone', put: false }" :clone="handleCloneComponent" :animation="200" - :force-fallback="true" + :force-fallback="false" > @@ -46,13 +50,13 @@ * VerifyPictureWord * @description 输入文字 * */ -import { resetSize } from '../utils/util'; -import { aesEncrypt } from '../utils/ase'; -import { getCode, reqCheck } from '@/api/login'; -import { getCurrentInstance, nextTick, onMounted, reactive, ref, toRefs } from 'vue'; +import { resetSize } from '../utils/util' +import { aesEncrypt } from '../utils/ase' +import { getCode, reqCheck } from '@/api/login' +import { getCurrentInstance, nextTick, onMounted, reactive, ref, toRefs } from 'vue' const props = defineProps({ - //弹出式pop,固定fixed + // 弹出式 pop,固定 fixed mode: { type: String, default: 'fixed' @@ -60,7 +64,7 @@ const props = defineProps({ captchaType: { type: String }, - //间隔 + // 间隔 vSpace: { type: Number, default: 5 @@ -71,7 +75,7 @@ const props = defineProps({ return { width: '310px', height: '155px' - }; + } } }, barSize: { @@ -80,20 +84,18 @@ const props = defineProps({ return { width: '310px', height: '40px' - }; + } } } -}); - -const { t } = useI18n(); -const { mode, captchaType } = toRefs(props); -const { proxy } = getCurrentInstance(); -let secretKey = ref(''), //后端返回的ase加密秘钥 +}) +const { t } = useI18n() +const { mode, captchaType } = toRefs(props) +const { proxy } = getCurrentInstance() +let secretKey = ref(''), // 后端返回的ase加密秘钥 userCode = ref(''), // 用户输入的验证码 暂存至pointJson,无需加密 - - verificationCodeImg = ref(''), //后端获取到的背景图片 - backToken = ref(''), //后端返回的token值 + verificationCodeImg = ref(''), // 后端获取到的背景图片 + backToken = ref(''), // 后端返回的token值 setSize = reactive({ imgHeight: 0, imgWidth: 0, @@ -104,91 +106,91 @@ let secretKey = ref(''), //后端返回的ase加密秘钥 barAreaColor = ref('#000'), barAreaBorderColor = ref('#ddd'), showRefresh = ref(true), -// bindingClick = ref(true) - checking = ref(false); + // bindingClick = ref(true) + checking = ref(false) const init = () => { - //加载页面 - getPicture(); + // 加载页面 + getPicture() nextTick(() => { - let { imgHeight, imgWidth, barHeight, barWidth } = resetSize(proxy); - setSize.imgHeight = imgHeight; - setSize.imgWidth = imgWidth; - setSize.barHeight = barHeight; - setSize.barWidth = barWidth; - proxy.$parent.$emit('ready', proxy); - }); -}; + let { imgHeight, imgWidth, barHeight, barWidth } = resetSize(proxy) + setSize.imgHeight = imgHeight + setSize.imgWidth = imgWidth + setSize.barHeight = barHeight + setSize.barWidth = barWidth + proxy.$parent.$emit('ready', proxy) + }) +} onMounted(() => { // 禁止拖拽 - init(); - proxy.$el.onselectstart = function() { - return false; - }; -}); -const canvas = ref(null); + init() + proxy.$el.onselectstart = function () { + return false + } +}) +const canvas = ref(null) const submit = () => { - checking.value = true; - //发送后端请求 - var captchaVerification = secretKey.value + checking.value = true + // 发送后端请求 + const captchaVerification = secretKey.value ? aesEncrypt(backToken.value + '---' + userCode.value, secretKey.value) - : backToken.value + '---' + userCode.value; + : backToken.value + '---' + userCode.value let data = { captchaType: captchaType.value, pointJson: userCode.value, token: backToken.value - }; + } reqCheck(data).then((res) => { - if (res.repCode == '0000') { - barAreaColor.value = '#4cae4c'; - barAreaBorderColor.value = '#5cb85c'; - text.value = t('captcha.success'); + if (res.repCode === '0000') { + barAreaColor.value = '#4cae4c' + barAreaBorderColor.value = '#5cb85c' + text.value = t('captcha.success') // bindingClick.value = false - if (mode.value == 'pop') { + if (mode.value === 'pop') { setTimeout(() => { - proxy.$parent.clickShow = false; - refresh(); - }, 1500); + proxy.$parent.clickShow = false + refresh() + }, 1500) } - proxy.$parent.$emit('success', { captchaVerification }); + proxy.$parent.$emit('success', { captchaVerification }) } else { - proxy.$parent.$emit('error', proxy); - barAreaColor.value = '#d9534f'; - barAreaBorderColor.value = '#d9534f'; - text.value = t('captcha.fail'); + proxy.$parent.$emit('error', proxy) + barAreaColor.value = '#d9534f' + barAreaBorderColor.value = '#d9534f' + text.value = t('captcha.fail') setTimeout(() => { - refresh(); - }, 700); + refresh() + }, 700) } - checking.value = false; - }); -}; + checking.value = false + }) +} -const refresh = async function() { - barAreaColor.value = '#000'; - barAreaBorderColor.value = '#ddd'; - checking.value = false; +const refresh = async function () { + barAreaColor.value = '#000' + barAreaBorderColor.value = '#ddd' + checking.value = false - userCode.value = ''; + userCode.value = '' - await getPicture(); - showRefresh.value = true; -}; + await getPicture() + showRefresh.value = true +} // 请求背景图片和验证图片 const getPicture = async () => { let data = { captchaType: captchaType.value - }; - const res = await getCode(data); - if (res.repCode == '0000') { - verificationCodeImg.value = res.repData.originalImageBase64; - backToken.value = res.repData.token; - secretKey.value = res.repData.secretKey; - text.value = t('captcha.code'); - } else { - text.value = res.repMsg; } -}; - \ No newline at end of file + const res = await getCode(data) + if (res.repCode === '0000') { + verificationCodeImg.value = res.repData.originalImageBase64 + backToken.value = res.repData.token + secretKey.value = res.repData.secretKey + text.value = t('captcha.code') + } else { + text.value = res.repMsg + } +} + diff --git a/src/views/Login/SocialLogin.vue b/src/views/Login/SocialLogin.vue index e0caace83..961f4ddb1 100644 --- a/src/views/Login/SocialLogin.vue +++ b/src/views/Login/SocialLogin.vue @@ -185,7 +185,7 @@ const { push } = useRouter() const permissionStore = usePermissionStore() const loginLoading = ref(false) const verify = ref() -const captchaType = ref('blockPuzzle') // blockPuzzle 滑块 clickWord 点击文字 +const captchaType = ref('blockPuzzle') // blockPuzzle 滑块 clickWord 点击文字 pictureWord 文字验证码 const getShow = computed(() => unref(getLoginState) === LoginStateEnum.LOGIN) diff --git a/src/views/Login/components/ForgetPasswordForm.vue b/src/views/Login/components/ForgetPasswordForm.vue index 0c3b2e04f..f47b2299a 100644 --- a/src/views/Login/components/ForgetPasswordForm.vue +++ b/src/views/Login/components/ForgetPasswordForm.vue @@ -143,7 +143,7 @@ const iconCircleCheck = useIcon({ icon: 'ep:circle-check' }) const { validForm } = useFormValid(formSmsResetPassword) const { handleBackLogin, getLoginState, setLoginState } = useLoginState() const getShow = computed(() => unref(getLoginState) === LoginStateEnum.RESET_PASSWORD) -const captchaType = ref('blockPuzzle') // blockPuzzle 滑块 clickWord 点击文字 +const captchaType = ref('blockPuzzle') // blockPuzzle 滑块 clickWord 点击文字 pictureWord 文字验证码 const validatePass2 = (_rule, value, callback) => { if (value === '') { diff --git a/src/views/Login/components/LoginForm.vue b/src/views/Login/components/LoginForm.vue index cb4dd429a..1bb5173d8 100644 --- a/src/views/Login/components/LoginForm.vue +++ b/src/views/Login/components/LoginForm.vue @@ -47,10 +47,7 @@ /> - + @@ -177,8 +174,7 @@ const permissionStore = usePermissionStore() const redirect = ref('') const loginLoading = ref(false) const verify = ref() -const captchaType = ref('pictureWord') // blockPuzzle 滑块 clickWord 点击文字 pictureWord 文字验证码 -// const captchaType = ref('blockPuzzle') // blockPuzzle 滑块 clickWord 点击文字 pictureWord 文字验证码 +const captchaType = ref('blockPuzzle') // blockPuzzle 滑块 clickWord 点击文字 pictureWord 文字验证码 const getShow = computed(() => unref(getLoginState) === LoginStateEnum.LOGIN) @@ -361,4 +357,4 @@ onMounted(() => { cursor: pointer; } } - \ No newline at end of file + diff --git a/src/views/Login/components/RegisterForm.vue b/src/views/Login/components/RegisterForm.vue index 0636a1c82..eb1f75b69 100644 --- a/src/views/Login/components/RegisterForm.vue +++ b/src/views/Login/components/RegisterForm.vue @@ -119,7 +119,7 @@ const permissionStore = usePermissionStore() const redirect = ref('') const loginLoading = ref(false) const verify = ref() -const captchaType = ref('blockPuzzle') // blockPuzzle 滑块 clickWord 点击文字 +const captchaType = ref('blockPuzzle') // blockPuzzle 滑块 clickWord 点击文字 pictureWord 文字验证码 const getShow = computed(() => unref(getLoginState) === LoginStateEnum.REGISTER) From ff7beb6db2ce31dcccb0cdff4b508d679d63ec58 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Tue, 5 Aug 2025 21:12:33 +0800 Subject: [PATCH 011/161] =?UTF-8?q?feat=EF=BC=9A=E3=80=90system=20?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E5=8A=9F=E8=83=BD=E3=80=91=E9=82=AE=E7=AE=B1?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=8A=84=E9=80=81=E3=80=81=E5=AF=86=E9=80=81?= =?UTF-8?q?=EF=BC=8C=E6=94=AF=E6=8C=81=E5=A4=9A=E4=B8=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/system/mail/log/index.ts | 4 +- src/api/system/mail/template/index.ts | 9 +++- src/views/system/mail/log/MailLogDetail.vue | 28 +++++++++++-- src/views/system/mail/log/index.vue | 42 +++++++++++++++---- .../mail/template/MailTemplateSendForm.vue | 31 +++++++++++--- 5 files changed, 94 insertions(+), 20 deletions(-) diff --git a/src/api/system/mail/log/index.ts b/src/api/system/mail/log/index.ts index d891db07c..409ced631 100644 --- a/src/api/system/mail/log/index.ts +++ b/src/api/system/mail/log/index.ts @@ -4,7 +4,9 @@ export interface MailLogVO { id: number userId: number userType: number - toMail: string + toMails: string[] + ccMails?: string[] + bccMails?: string[] accountId: number fromMail: string templateId: number diff --git a/src/api/system/mail/template/index.ts b/src/api/system/mail/template/index.ts index c6dae688a..6e1d083f2 100644 --- a/src/api/system/mail/template/index.ts +++ b/src/api/system/mail/template/index.ts @@ -14,7 +14,9 @@ export interface MailTemplateVO { } export interface MailSendReqVO { - mail: string + toMails: string[] + ccMails?: string[] + bccMails?: string[] templateCode: string templateParams: Map } @@ -46,7 +48,10 @@ export const deleteMailTemplate = async (id: number) => { // 批量删除邮件模版 export const deleteMailTemplateList = async (ids: number[]) => { - return await request.delete({ url: '/system/mail-template/delete-list', params: { ids: ids.join(',') } }) + return await request.delete({ + url: '/system/mail-template/delete-list', + params: { ids: ids.join(',') } + }) } // 发送邮件 diff --git a/src/views/system/mail/log/MailLogDetail.vue b/src/views/system/mail/log/MailLogDetail.vue index a7ec449bb..37d757a3d 100644 --- a/src/views/system/mail/log/MailLogDetail.vue +++ b/src/views/system/mail/log/MailLogDetail.vue @@ -13,12 +13,34 @@ {{ detailData.templateNickname }} - - {{ detailData.toMail }} + ({{ detailData.userId }}) + + + +
+
+ 收件: + + {{ mail }} + +
+
+ 抄送: + + {{ mail }} + +
+
+ 密送: + + {{ mail }} + +
+
{{ detailData.templateTitle }} @@ -58,7 +80,7 @@ defineOptions({ name: 'SystemMailLogDetail' }) const dialogVisible = ref(false) // 弹窗的是否展示 const detailLoading = ref(false) // 表单的加载中 const detailData = ref() // 详情数据 -const accountList = ref([]) // 邮箱账号列表 +const accountList = ref([]) // 邮箱账号列表 /** 打开弹窗 */ const open = async (data: MailLogApi.MailLogVO) => { diff --git a/src/views/system/mail/log/index.vue b/src/views/system/mail/log/index.vue index dd915e52f..1bd794f59 100644 --- a/src/views/system/mail/log/index.vue +++ b/src/views/system/mail/log/index.vue @@ -119,12 +119,36 @@ width="180" :formatter="dateFormatter" /> - + + + + @@ -185,15 +209,15 @@ const queryParams = reactive({ pageNo: 1, pageSize: 10, toMail: '', - accountId: null, - templateId: null, - sendStatus: null, - userId: null, - userType: null, + accountId: undefined, + templateId: undefined, + sendStatus: undefined, + userId: undefined, + userType: undefined, sendTime: [] }) const exportLoading = ref(false) // 导出的加载中 -const accountList = ref([]) // 邮箱账号列表 +const accountList = ref([]) // 邮箱账号列表 /** 查询列表 */ const getList = async () => { diff --git a/src/views/system/mail/template/MailTemplateSendForm.vue b/src/views/system/mail/template/MailTemplateSendForm.vue index 6e4c918e6..3decb448c 100644 --- a/src/views/system/mail/template/MailTemplateSendForm.vue +++ b/src/views/system/mail/template/MailTemplateSendForm.vue @@ -10,8 +10,26 @@ - - + + + + + + + + { formData.value = { content: '', params: {}, - mail: '', + toMails: [], + ccMails: [], + bccMails: [], templateCode: '', templateParams: new Map() } From 47863e8d22d6a8193089d10cb18cb6f99dbc504f Mon Sep 17 00:00:00 2001 From: LesanOuO <1960681385@qq.com> Date: Wed, 6 Aug 2025 19:25:12 +0800 Subject: [PATCH 012/161] =?UTF-8?q?fix:=20=E4=BD=BF=E7=94=A8form-create?= =?UTF-8?q?=E5=86=85=E7=BD=AE=E6=96=B9=E6=B3=95=E4=BF=AE=E5=A4=8D=E5=87=BD?= =?UTF-8?q?=E6=95=B0=E6=96=B9=E6=B3=95JSON=E8=A7=A3=E6=9E=90=E5=A4=B1?= =?UTF-8?q?=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/formCreate.ts | 153 ++-------------------------------------- 1 file changed, 5 insertions(+), 148 deletions(-) diff --git a/src/utils/formCreate.ts b/src/utils/formCreate.ts index 19862f571..f3f005ea9 100644 --- a/src/utils/formCreate.ts +++ b/src/utils/formCreate.ts @@ -2,6 +2,7 @@ * 针对 https://github.com/xaboy/form-create-designer 封装的工具类 */ import { isRef } from 'vue' +import formCreate from '@form-create/element-ui' // 编码表单 Conf export const encodeConf = (designerRef: object) => { @@ -24,7 +25,7 @@ export const encodeFields = (designerRef: object) => { export const decodeFields = (fields: string[]) => { const rule: object[] = [] fields.forEach((item) => { - rule.push(JSON.parse(item)) + rule.push(formCreate.parseJson(item)) }) return rule } @@ -32,7 +33,7 @@ export const decodeFields = (fields: string[]) => { // 设置表单的 Conf 和 Fields,适用 FcDesigner 场景 export const setConfAndFields = (designerRef: object, conf: string, fields: string) => { // @ts-ignore - designerRef.value.setOption(JSON.parse(conf)) + designerRef.value.setOption(formCreate.parseJson(conf)) // @ts-ignore designerRef.value.setRule(decodeFields(fields)) } @@ -49,154 +50,10 @@ export const setConfAndFields2 = ( detailPreview = detailPreview.value } - // 修复所有函数类型(解决设计器保存后函数变成字符串的问题)。例如说: - // https://t.zsxq.com/rADff - // https://t.zsxq.com/ZfbGt - // https://t.zsxq.com/mHOoj - // https://t.zsxq.com/BSylB - const option = JSON.parse(conf) - const rule = decodeFields(fields) - // 🔧 修复所有函数类型 - 解决设计器保存后函数变成字符串的问题 - const fixFunctions = (obj: any) => { - if (obj && typeof obj === 'object') { - Object.keys(obj).forEach((key) => { - // 检查是否是函数相关的属性 - if (isFunctionProperty(key)) { - // 如果不是函数类型,重新构建为函数 - if (typeof obj[key] !== 'function') { - obj[key] = createDefaultFunction(key) - } - } else if (typeof obj[key] === 'object' && obj[key] !== null) { - // 递归处理嵌套对象 - fixFunctions(obj[key]) - } - }) - } - } - // 判断是否是函数属性 - const isFunctionProperty = (key: string): boolean => { - const functionKeys = [ - 'beforeFetch', // 请求前处理 - 'afterFetch', // 请求后处理 - 'onSubmit', // 表单提交 - 'onReset', // 表单重置 - 'onChange', // 值变化 - 'onInput', // 输入事件 - 'onClick', // 点击事件 - 'onFocus', // 获取焦点 - 'onBlur', // 失去焦点 - 'onMounted', // 组件挂载 - 'onCreated', // 组件创建 - 'onReload', // 重新加载 - 'remoteMethod', // 远程搜索方法 - 'parseFunc', // 解析函数 - 'validator', // 验证器 - 'asyncValidator', // 异步验证器 - 'formatter', // 格式化函数 - 'parser', // 解析函数 - 'beforeUpload', // 上传前处理 - 'onSuccess', // 成功回调 - 'onError', // 错误回调 - 'onProgress', // 进度回调 - 'onPreview', // 预览回调 - 'onRemove', // 移除回调 - 'onExceed', // 超出限制回调 - 'filterMethod', // 过滤方法 - 'sortMethod', // 排序方法 - 'loadData', // 加载数据 - 'renderContent', // 渲染内容 - 'render' // 渲染函数 - ] - // 检查是否以函数相关前缀开头 - const functionPrefixes = ['on', 'before', 'after', 'handle'] - return functionKeys.includes(key) || functionPrefixes.some((prefix) => key.startsWith(prefix)) - } - // 根据函数名创建默认函数 - const createDefaultFunction = (key: string): Function => { - switch (key) { - case 'beforeFetch': - return (config: any) => { - // 添加 Token 认证头。例如说: - // https://t.zsxq.com/hK3FO - const token = localStorage.getItem('token') - if (token) { - config.headers = { - ...config.headers, - Authorization: 'Bearer ' + token - } - } - // 添加通用请求头 - config.headers = { - ...config.headers, - 'Content-Type': 'application/json', - 'X-Requested-With': 'XMLHttpRequest' - } - // 添加时间戳防止缓存 - config.params = { - ...config.params, - _t: Date.now() - } - return config - } - case 'afterFetch': - return (data: any) => { - return data - } - case 'onSubmit': - return (_formData: any) => { - return true - } - case 'onReset': - return () => { - return true - } - case 'onChange': - return (_value: any, _oldValue: any) => {} - case 'remoteMethod': - return (query: string) => { - console.log('remoteMethod被调用:', query) - } - case 'parseFunc': - return (data: any) => { - // 默认解析逻辑:如果是数组直接返回,否则尝试获取list属性 - if (Array.isArray(data)) { - return data - } - return data?.list || data?.data || [] - } - case 'validator': - return (_rule: any, _value: any, callback: Function) => { - callback() - } - case 'beforeUpload': - return (_file: any) => { - return true - } - default: - // 通用默认函数 - return (...args: any[]) => { - // 对于事件处理函数,返回true表示继续执行 - if (key.startsWith('on') || key.startsWith('handle')) { - return true - } - // 对于其他函数,返回第一个参数(通常是数据传递) - return args[0] - } - } - } - // 修复 option 中的所有函数 - fixFunctions(option) - // 修复 rule 中的所有函数(包括组件的 props) - if (Array.isArray(rule)) { - rule.forEach((item: any) => { - fixFunctions(item) - }) - } - // @ts-ignore - detailPreview.option = option + detailPreview.option = formCreate.parseJson(conf) // @ts-ignore - detailPreview.rule = rule + detailPreview.rule = decodeFields(fields) if (value) { // @ts-ignore From 9908adbed9a277c3b3de22cdfc8f998e58dbd02e Mon Sep 17 00:00:00 2001 From: wuKong Date: Sat, 9 Aug 2025 00:45:13 +0800 Subject: [PATCH 013/161] =?UTF-8?q?fix(mp):=20=E4=BF=AE=E5=A4=8D=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E5=A4=B4=E5=83=8F=E6=98=BE=E7=A4=BA=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将用户头像获取逻辑从 avatar 字段改为 headImageUrl 字段 -确保在获取到的用户信息中,如果有头像图片链接,则使用该链接 - 如果没有头像图片链接,则保留原有的头像 --- src/views/mp/components/wx-msg/main.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/mp/components/wx-msg/main.vue b/src/views/mp/components/wx-msg/main.vue index 8b7cc3a2b..333541076 100644 --- a/src/views/mp/components/wx-msg/main.vue +++ b/src/views/mp/components/wx-msg/main.vue @@ -82,7 +82,7 @@ const msgDivRef = ref(null) // 消息显示窗口ref, onMounted(async () => { const data = await getUser(props.userId) user.nickname = data.nickname?.length > 0 ? data.nickname : user.nickname - user.avatar = user.avatar?.length > 0 ? data.avatar : user.avatar + user.avatar = data.headImageUrl?.length > 0 ? data.headImageUrl : user.avatar accountId.value = data.accountId reply.value.accountId = data.accountId From 72d6fb587606fc838582f8c6e3a0d45677c63fc5 Mon Sep 17 00:00:00 2001 From: wuKong Date: Sat, 9 Aug 2025 00:47:59 +0800 Subject: [PATCH 014/161] =?UTF-8?q?feat(mp):=20=E6=B7=BB=E5=8A=A0=E6=89=AB?= =?UTF-8?q?=E7=A0=81=E4=BA=8B=E4=BB=B6=E5=A4=84=E7=90=86-=20=E5=9C=A8=20Me?= =?UTF-8?q?ssageTable=20=E7=BB=84=E4=BB=B6=E4=B8=AD=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E4=BA=86=E5=AF=B9=E6=89=AB=E7=A0=81=E4=BA=8B=E4=BB=B6=E7=9A=84?= =?UTF-8?q?=E5=A4=84=E7=90=86=20-=20=E5=BD=93=E6=B6=88=E6=81=AF=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E4=B8=BA=20Event=20=E4=B8=94=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E4=B8=BA=20SCAN=20=E6=97=B6=EF=BC=8C?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E7=BB=BF=E8=89=B2=E7=9A=84"=E6=89=AB?= =?UTF-8?q?=E7=A0=81"=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/mp/message/MessageTable.vue | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/views/mp/message/MessageTable.vue b/src/views/mp/message/MessageTable.vue index ebc3d749e..185bdec58 100644 --- a/src/views/mp/message/MessageTable.vue +++ b/src/views/mp/message/MessageTable.vue @@ -59,6 +59,9 @@ > 选择地理位置
+
+ 扫码 +
未知事件类型
From 5745cb6f331cd9699cc39c1e8fac1f8bb69c7259 Mon Sep 17 00:00:00 2001 From: wuKong Date: Sat, 9 Aug 2025 00:48:50 +0800 Subject: [PATCH 015/161] =?UTF-8?q?feat(mp/user):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E5=A4=B4=E5=83=8F=E5=88=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在用户列表中增加用户头像列 - 使用 el-avatar 组件显示用户头像- 调整表格列的宽度以适应新内容 --- src/views/mp/user/index.vue | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/views/mp/user/index.vue b/src/views/mp/user/index.vue index 6147351aa..c70761f2c 100644 --- a/src/views/mp/user/index.vue +++ b/src/views/mp/user/index.vue @@ -52,6 +52,11 @@ + + + From 544fc8127d86e9b56891da6a15b023907408a2c0 Mon Sep 17 00:00:00 2001 From: wuKong Date: Sat, 9 Aug 2025 00:49:37 +0800 Subject: [PATCH 016/161] =?UTF-8?q?feat(mp):=20=E6=B7=BB=E5=8A=A0=20SCAN?= =?UTF-8?q?=20=E4=BA=8B=E4=BB=B6=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 MsgEvent 组件中增加了对 SCAN 事件的处理- 添加了显示"扫码"标签的功能 --- src/views/mp/components/wx-msg/components/MsgEvent.vue | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/views/mp/components/wx-msg/components/MsgEvent.vue b/src/views/mp/components/wx-msg/components/MsgEvent.vue index 77beda48a..32eaa09f3 100644 --- a/src/views/mp/components/wx-msg/components/MsgEvent.vue +++ b/src/views/mp/components/wx-msg/components/MsgEvent.vue @@ -34,6 +34,9 @@
选择地理位置
+
+ 扫码 +
未知事件类型
From 8deb5b417f4ce33e7efd4e9cf8267f5820678f8c Mon Sep 17 00:00:00 2001 From: wuKong Date: Sat, 9 Aug 2025 00:50:47 +0800 Subject: [PATCH 017/161] =?UTF-8?q?fix(mp):=20=E4=BF=AE=E5=A4=8D=E5=BE=AE?= =?UTF-8?q?=E4=BF=A1=E5=9B=BE=E6=96=87=E6=B6=88=E6=81=AF=E5=9B=BE=E7=89=87?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 wx-news 组件中,为 el-image 和 img 标签添加了备用图片属性 - 使用 article.thumbUrl作为 article.picUrl 的备用值,确保在 picUrl 为空时仍能显示图片 --- src/views/mp/components/wx-news/main.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/views/mp/components/wx-news/main.vue b/src/views/mp/components/wx-news/main.vue index 154291b3d..53b99bb18 100644 --- a/src/views/mp/components/wx-news/main.vue +++ b/src/views/mp/components/wx-news/main.vue @@ -13,7 +13,7 @@
@@ -29,7 +29,7 @@
{{ article.title }}
- +
From 3f43475c34f5b58d4242ce3a1ad1a5d91531a38d Mon Sep 17 00:00:00 2001 From: puhui999 Date: Sat, 9 Aug 2025 12:43:45 +0800 Subject: [PATCH 018/161] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=89=B9?= =?UTF-8?q?=E9=87=8F=E5=88=A0=E9=99=A4=E5=90=8E=20checkedIds=20=E6=9C=AA?= =?UTF-8?q?=E9=87=8D=E7=BD=AE=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/infra/codegen/index.vue | 1 + src/views/infra/config/index.vue | 1 + src/views/infra/dataSourceConfig/index.vue | 1 + src/views/infra/demo/demo01/index.vue | 3 ++- .../infra/demo/demo03/erp/components/Demo03CourseList.vue | 3 ++- src/views/infra/demo/demo03/erp/components/Demo03GradeList.vue | 3 ++- src/views/infra/demo/demo03/erp/index.vue | 3 ++- src/views/infra/demo/demo03/inner/index.vue | 1 + src/views/infra/demo/demo03/normal/index.vue | 3 ++- src/views/infra/file/index.vue | 1 + src/views/infra/fileConfig/index.vue | 1 + src/views/infra/job/index.vue | 1 + src/views/system/dept/index.vue | 1 + src/views/system/dict/data/index.vue | 1 + src/views/system/dict/index.vue | 1 + src/views/system/mail/account/index.vue | 1 + src/views/system/mail/template/index.vue | 1 + src/views/system/notice/index.vue | 1 + src/views/system/notify/template/index.vue | 1 + src/views/system/oauth2/client/index.vue | 1 + src/views/system/post/index.vue | 1 + src/views/system/role/index.vue | 1 + src/views/system/sms/channel/index.vue | 1 + src/views/system/sms/template/index.vue | 1 + src/views/system/tenant/index.vue | 1 + src/views/system/tenantPackage/index.vue | 1 + src/views/system/user/index.vue | 1 + 27 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/views/infra/codegen/index.vue b/src/views/infra/codegen/index.vue index ca68c457a..893eba969 100644 --- a/src/views/infra/codegen/index.vue +++ b/src/views/infra/codegen/index.vue @@ -254,6 +254,7 @@ const handleDeleteBatch = async () => { await message.delConfirm() // 发起批量删除 await CodegenApi.deleteCodegenTableList(checkedIds.value) + checkedIds.value = [] message.success(t('common.delSuccess')) // 刷新列表 await getList() diff --git a/src/views/infra/config/index.vue b/src/views/infra/config/index.vue index de0deb897..eecc94790 100644 --- a/src/views/infra/config/index.vue +++ b/src/views/infra/config/index.vue @@ -228,6 +228,7 @@ const handleDeleteBatch = async () => { await message.delConfirm() // 发起批量删除 await ConfigApi.deleteConfigList(checkedIds.value) + checkedIds.value = [] message.success(t('common.delSuccess')) // 刷新列表 await getList() diff --git a/src/views/infra/dataSourceConfig/index.vue b/src/views/infra/dataSourceConfig/index.vue index 9bde09e5f..2076d6376 100644 --- a/src/views/infra/dataSourceConfig/index.vue +++ b/src/views/infra/dataSourceConfig/index.vue @@ -122,6 +122,7 @@ const handleDeleteBatch = async () => { await message.delConfirm() // 发起批量删除 await DataSourceConfigApi.deleteDataSourceConfigList(checkedIds.value) + checkedIds.value = [] message.success(t('common.delSuccess')) // 刷新列表 await getList() diff --git a/src/views/infra/demo/demo01/index.vue b/src/views/infra/demo/demo01/index.vue index fc0122320..82adc2843 100644 --- a/src/views/infra/demo/demo01/index.vue +++ b/src/views/infra/demo/demo01/index.vue @@ -219,7 +219,8 @@ const handleDeleteBatch = async () => { try { // 删除的二次确认 await message.delConfirm() - await Demo01ContactApi.deleteDemo01ContactList(checkedIds.value); + await Demo01ContactApi.deleteDemo01ContactList(checkedIds.value) + checkedIds.value = []; message.success(t('common.delSuccess')) await getList(); } catch {} diff --git a/src/views/infra/demo/demo03/erp/components/Demo03CourseList.vue b/src/views/infra/demo/demo03/erp/components/Demo03CourseList.vue index d0c6b66f4..4d45bac9f 100644 --- a/src/views/infra/demo/demo03/erp/components/Demo03CourseList.vue +++ b/src/views/infra/demo/demo03/erp/components/Demo03CourseList.vue @@ -149,7 +149,8 @@ const handleDeleteBatch = async () => { try { // 删除的二次确认 await message.delConfirm() - await Demo03StudentApi.deleteDemo03CourseList(checkedIds.value); + await Demo03StudentApi.deleteDemo03CourseList(checkedIds.value) + checkedIds.value = []; message.success(t('common.delSuccess')) await getList(); } catch {} diff --git a/src/views/infra/demo/demo03/erp/components/Demo03GradeList.vue b/src/views/infra/demo/demo03/erp/components/Demo03GradeList.vue index 3fed91f15..cb516f43a 100644 --- a/src/views/infra/demo/demo03/erp/components/Demo03GradeList.vue +++ b/src/views/infra/demo/demo03/erp/components/Demo03GradeList.vue @@ -149,7 +149,8 @@ const handleDeleteBatch = async () => { try { // 删除的二次确认 await message.delConfirm() - await Demo03StudentApi.deleteDemo03GradeList(checkedIds.value); + await Demo03StudentApi.deleteDemo03GradeList(checkedIds.value) + checkedIds.value = []; message.success(t('common.delSuccess')) await getList(); } catch {} diff --git a/src/views/infra/demo/demo03/erp/index.vue b/src/views/infra/demo/demo03/erp/index.vue index 77dff0925..e5649d0a3 100644 --- a/src/views/infra/demo/demo03/erp/index.vue +++ b/src/views/infra/demo/demo03/erp/index.vue @@ -234,7 +234,8 @@ const handleDeleteBatch = async () => { try { // 删除的二次确认 await message.delConfirm() - await Demo03StudentApi.deleteDemo03StudentList(checkedIds.value); + await Demo03StudentApi.deleteDemo03StudentList(checkedIds.value) + checkedIds.value = []; message.success(t('common.delSuccess')) await getList(); } catch {} diff --git a/src/views/infra/demo/demo03/inner/index.vue b/src/views/infra/demo/demo03/inner/index.vue index c58ec39d4..30ddc764f 100644 --- a/src/views/infra/demo/demo03/inner/index.vue +++ b/src/views/infra/demo/demo03/inner/index.vue @@ -230,6 +230,7 @@ const handleDeleteBatch = async () => { // 删除的二次确认 await message.delConfirm() await Demo03StudentApi.deleteDemo03StudentList(checkedIds.value) + checkedIds.value = [] message.success(t('common.delSuccess')) await getList() } catch {} diff --git a/src/views/infra/demo/demo03/normal/index.vue b/src/views/infra/demo/demo03/normal/index.vue index 5c3ebf4da..f64e21ca3 100644 --- a/src/views/infra/demo/demo03/normal/index.vue +++ b/src/views/infra/demo/demo03/normal/index.vue @@ -219,7 +219,8 @@ const handleDeleteBatch = async () => { try { // 删除的二次确认 await message.delConfirm() - await Demo03StudentApi.deleteDemo03StudentList(checkedIds.value); + await Demo03StudentApi.deleteDemo03StudentList(checkedIds.value) + checkedIds.value = []; message.success(t('common.delSuccess')) await getList(); } catch {} diff --git a/src/views/infra/file/index.vue b/src/views/infra/file/index.vue index 20c2fed5d..901139180 100644 --- a/src/views/infra/file/index.vue +++ b/src/views/infra/file/index.vue @@ -217,6 +217,7 @@ const handleDeleteBatch = async () => { await message.delConfirm() // 发起批量删除 await FileApi.deleteFileList(checkedIds.value) + checkedIds.value = [] message.success(t('common.delSuccess')) // 刷新列表 await getList() diff --git a/src/views/infra/fileConfig/index.vue b/src/views/infra/fileConfig/index.vue index 056b41f99..ab9979067 100644 --- a/src/views/infra/fileConfig/index.vue +++ b/src/views/infra/fileConfig/index.vue @@ -214,6 +214,7 @@ const handleDeleteBatch = async () => { await message.delConfirm() // 发起批量删除 await FileConfigApi.deleteFileConfigList(checkedIds.value) + checkedIds.value = [] message.success(t('common.delSuccess')) // 刷新列表 await getList() diff --git a/src/views/infra/job/index.vue b/src/views/infra/job/index.vue index 9eaedc651..2090b9d83 100644 --- a/src/views/infra/job/index.vue +++ b/src/views/infra/job/index.vue @@ -273,6 +273,7 @@ const handleDeleteBatch = async () => { await message.delConfirm() // 发起批量删除 await JobApi.deleteJobList(checkedIds.value) + checkedIds.value = [] message.success(t('common.delSuccess')) // 刷新列表 await getList() diff --git a/src/views/system/dept/index.vue b/src/views/system/dept/index.vue index c09fb85e4..3dc2ec580 100644 --- a/src/views/system/dept/index.vue +++ b/src/views/system/dept/index.vue @@ -204,6 +204,7 @@ const handleDeleteBatch = async () => { await message.delConfirm() // 发起批量删除 await DeptApi.deleteDeptList(checkedIds.value) + checkedIds.value = [] message.success(t('common.delSuccess')) // 刷新列表 await getList() diff --git a/src/views/system/dict/data/index.vue b/src/views/system/dict/data/index.vue index 13c2af082..e84636f7d 100644 --- a/src/views/system/dict/data/index.vue +++ b/src/views/system/dict/data/index.vue @@ -208,6 +208,7 @@ const handleDeleteBatch = async () => { await message.delConfirm() // 发起批量删除 await DictDataApi.deleteDictDataList(checkedIds.value) + checkedIds.value = [] message.success(t('common.delSuccess')) // 刷新列表 await getList() diff --git a/src/views/system/dict/index.vue b/src/views/system/dict/index.vue index ab0bd77bf..c66a1a8af 100644 --- a/src/views/system/dict/index.vue +++ b/src/views/system/dict/index.vue @@ -232,6 +232,7 @@ const handleDeleteBatch = async () => { await message.delConfirm() // 发起批量删除 await DictTypeApi.deleteDictTypeList(checkedIds.value) + checkedIds.value = [] message.success(t('common.delSuccess')) // 刷新列表 await getList() diff --git a/src/views/system/mail/account/index.vue b/src/views/system/mail/account/index.vue index d03c270f6..51c07ed72 100644 --- a/src/views/system/mail/account/index.vue +++ b/src/views/system/mail/account/index.vue @@ -199,6 +199,7 @@ const handleDeleteBatch = async () => { await message.delConfirm() // 发起批量删除 await MailAccountApi.deleteMailAccountList(checkedIds.value) + checkedIds.value = [] message.success(t('common.delSuccess')) // 刷新列表 await getList() diff --git a/src/views/system/mail/template/index.vue b/src/views/system/mail/template/index.vue index 71bed39c1..03ea34ede 100644 --- a/src/views/system/mail/template/index.vue +++ b/src/views/system/mail/template/index.vue @@ -281,6 +281,7 @@ const handleDeleteBatch = async () => { await message.delConfirm() // 发起批量删除 await MailTemplateApi.deleteMailTemplateList(checkedIds.value) + checkedIds.value = [] message.success(t('common.delSuccess')) // 刷新列表 await getList() diff --git a/src/views/system/notice/index.vue b/src/views/system/notice/index.vue index 9c298dbaf..5fecbbd6e 100644 --- a/src/views/system/notice/index.vue +++ b/src/views/system/notice/index.vue @@ -193,6 +193,7 @@ const handleDeleteBatch = async () => { await message.delConfirm() // 发起批量删除 await NoticeApi.deleteNoticeList(checkedIds.value) + checkedIds.value = [] message.success(t('common.delSuccess')) // 刷新列表 await getList() diff --git a/src/views/system/notify/template/index.vue b/src/views/system/notify/template/index.vue index 375ad14a3..086be9c95 100644 --- a/src/views/system/notify/template/index.vue +++ b/src/views/system/notify/template/index.vue @@ -245,6 +245,7 @@ const handleDeleteBatch = async () => { await message.delConfirm() // 发起批量删除 await NotifyTemplateApi.deleteNotifyTemplateList(checkedIds.value) + checkedIds.value = [] message.success(t('common.delSuccess')) // 刷新列表 await getList() diff --git a/src/views/system/oauth2/client/index.vue b/src/views/system/oauth2/client/index.vue index 0e7168ef1..c75475b25 100644 --- a/src/views/system/oauth2/client/index.vue +++ b/src/views/system/oauth2/client/index.vue @@ -206,6 +206,7 @@ const handleDeleteBatch = async () => { await message.delConfirm() // 发起批量删除 await ClientApi.deleteOAuth2ClientList(checkedIds.value) + checkedIds.value = [] message.success(t('common.delSuccess')) // 刷新列表 await getList() diff --git a/src/views/system/post/index.vue b/src/views/system/post/index.vue index 8ca41ab44..291d21eff 100644 --- a/src/views/system/post/index.vue +++ b/src/views/system/post/index.vue @@ -203,6 +203,7 @@ const handleDeleteBatch = async () => { await message.delConfirm() // 发起批量删除 await PostApi.deletePostList(checkedIds.value) + checkedIds.value = [] message.success(t('common.delSuccess')) // 刷新列表 await getList() diff --git a/src/views/system/role/index.vue b/src/views/system/role/index.vue index 07ada23b1..91c68e3b1 100644 --- a/src/views/system/role/index.vue +++ b/src/views/system/role/index.vue @@ -270,6 +270,7 @@ const handleDeleteBatch = async () => { await message.delConfirm() // 发起批量删除 await RoleApi.deleteRoleList(checkedIds.value) + checkedIds.value = [] message.success(t('common.delSuccess')) // 刷新列表 await getList() diff --git a/src/views/system/sms/channel/index.vue b/src/views/system/sms/channel/index.vue index a59b1a77e..929c3a7ce 100644 --- a/src/views/system/sms/channel/index.vue +++ b/src/views/system/sms/channel/index.vue @@ -224,6 +224,7 @@ const handleDeleteBatch = async () => { await message.delConfirm() // 发起批量删除 await SmsChannelApi.deleteSmsChannelList(checkedIds.value) + checkedIds.value = [] message.success(t('common.delSuccess')) // 刷新列表 await getList() diff --git a/src/views/system/sms/template/index.vue b/src/views/system/sms/template/index.vue index 5f9928178..b582ed8dd 100644 --- a/src/views/system/sms/template/index.vue +++ b/src/views/system/sms/template/index.vue @@ -314,6 +314,7 @@ const handleDeleteBatch = async () => { await message.delConfirm() // 发起批量删除 await SmsTemplateApi.deleteSmsTemplateList(checkedIds.value) + checkedIds.value = [] message.success(t('common.delSuccess')) // 刷新列表 await getList() diff --git a/src/views/system/tenant/index.vue b/src/views/system/tenant/index.vue index 8a3b86b02..295b68640 100644 --- a/src/views/system/tenant/index.vue +++ b/src/views/system/tenant/index.vue @@ -266,6 +266,7 @@ const handleDeleteBatch = async () => { await message.delConfirm() // 发起批量删除 await TenantApi.deleteTenantList(checkedIds.value) + checkedIds.value = [] message.success(t('common.delSuccess')) // 刷新列表 await getList() diff --git a/src/views/system/tenantPackage/index.vue b/src/views/system/tenantPackage/index.vue index a031e4fea..5691bd346 100644 --- a/src/views/system/tenantPackage/index.vue +++ b/src/views/system/tenantPackage/index.vue @@ -196,6 +196,7 @@ const handleDeleteBatch = async () => { await message.delConfirm() // 发起批量删除 await TenantPackageApi.deleteTenantPackageList(checkedIds.value) + checkedIds.value = [] message.success(t('common.delSuccess')) // 刷新列表 await getList() diff --git a/src/views/system/user/index.vue b/src/views/system/user/index.vue index d594f253b..566451728 100644 --- a/src/views/system/user/index.vue +++ b/src/views/system/user/index.vue @@ -362,6 +362,7 @@ const handleDeleteBatch = async () => { await message.delConfirm() // 发起批量删除 await UserApi.deleteUserList(checkedIds.value) + checkedIds.value = [] message.success(t('common.delSuccess')) // 刷新列表 await getList() From 2b48d60735cb6de837b90888ec362b831f54019f Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Sun, 10 Aug 2025 22:26:35 +0800 Subject: [PATCH 019/161] =?UTF-8?q?fix:=20[BPM=20=E5=B7=A5=E4=BD=9C?= =?UTF-8?q?=E6=B5=81]=20=E8=A7=A6=E5=8F=91=E5=99=A8=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/nodes-config/TriggerNodeConfig.vue | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/components/SimpleProcessDesignerV2/src/nodes-config/TriggerNodeConfig.vue b/src/components/SimpleProcessDesignerV2/src/nodes-config/TriggerNodeConfig.vue index 2baac8d2e..c4fa63ccc 100644 --- a/src/components/SimpleProcessDesignerV2/src/nodes-config/TriggerNodeConfig.vue +++ b/src/components/SimpleProcessDesignerV2/src/nodes-config/TriggerNodeConfig.vue @@ -236,7 +236,7 @@
确 定 - 取 消 + 取 消
@@ -467,6 +467,13 @@ const saveConfig = async () => { return true } +/** 取消配置 */ +const cancelConfig = () => { + // 恢复原来的配置 + currentNode.value.triggerSetting = originalSetting + closeDrawer() +} + /** 获取节点展示内容 */ const getShowText = (): string => { let showText = '' @@ -498,7 +505,7 @@ const getShowText = (): string => { /** 显示触发器节点配置, 由父组件传过来 */ const showTriggerNodeConfig = (node: SimpleFlowNode) => { nodeName.value = node.name - originalSetting = node.triggerSetting ? JSON.parse(JSON.stringify(node.triggerSetting)) : {} + originalSetting = cloneDeep(node.triggerSetting) if (node.triggerSetting) { configForm.value = { type: node.triggerSetting.type, From e1151738f5adfe22093e0eb6a90aa7481c4a396a Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Sun, 10 Aug 2025 22:47:47 +0800 Subject: [PATCH 020/161] =?UTF-8?q?perf:=20=20[BPM=20=E5=B7=A5=E4=BD=9C?= =?UTF-8?q?=E6=B5=81]=20=E6=9B=B4=E5=A4=9A=E8=AE=BE=E7=BD=AE=EF=BC=8C?= =?UTF-8?q?=E7=9B=91=E5=90=AC=E6=B5=81=E7=A8=8B=E8=A1=A8=E5=8D=95=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/bpm/model/form/ExtraSettings.vue | 47 ++++++---------------- src/views/bpm/model/form/index.vue | 5 +-- 2 files changed, 14 insertions(+), 38 deletions(-) diff --git a/src/views/bpm/model/form/ExtraSettings.vue b/src/views/bpm/model/form/ExtraSettings.vue index 9c5beaf60..0f40ad66b 100644 --- a/src/views/bpm/model/form/ExtraSettings.vue +++ b/src/views/bpm/model/form/ExtraSettings.vue @@ -232,34 +232,6 @@ import { ProcessVariableEnum } from '@/components/SimpleProcessDesignerV2/src/co import HttpRequestSetting from '@/components/SimpleProcessDesignerV2/src/nodes-config/components/HttpRequestSetting.vue' const modelData = defineModel() -const formFields = ref([]) - -const props = defineProps({ - // 流程表单 ID - modelFormId: { - type: Number, - required: false, - default: undefined, - } -}) - - -// 监听 modelFormId 变化 -watch( - () => props.modelFormId, - async (newVal) => { - if (newVal) { - const form = await FormApi.getForm(newVal); - formFields.value = form?.fields; - } else { - // 如果 modelFormId 为空,清空表单字段 - formFields.value = []; - } - }, - { immediate: true }, -); -// 暴露给子组件使用 -provide('formFields', formFields) /** 自定义 ID 流程编码 */ const timeOptions = ref([ @@ -374,10 +346,10 @@ const handleTaskAfterTriggerEnableChange = (val: boolean | string | number) => { } } -/** 表单选项 */ -const formField = ref>([]) +/** 已解析表单字段 */ +const formFields = ref>([]) const formFieldOptions4Title = computed(() => { - let cloneFormField = formField.value.map((item) => { + let cloneFormField = formFields.value.map((item) => { return { label: item.title, value: item.field @@ -399,7 +371,7 @@ const formFieldOptions4Title = computed(() => { return cloneFormField }) const formFieldOptions4Summary = computed(() => { - return formField.value.map((item) => { + return formFields.value.map((item) => { return { label: item.title, value: item.field @@ -407,6 +379,11 @@ const formFieldOptions4Summary = computed(() => { }) }) +/** 未解析的表单字段 */ +const unParsedFormFields = ref([]) +/** 暴露给子组件 HttpRequestSetting 使用 */ +provide('formFields', unParsedFormFields) + /** 兼容以前未配置更多设置的流程 */ const initData = () => { if (!modelData.value.processIdRule) { @@ -456,13 +433,15 @@ watch( const data = await FormApi.getForm(newFormId) const result: Array<{ field: string; title: string }> = [] if (data.fields) { + unParsedFormFields.value = data.fields data.fields.forEach((fieldStr: string) => { parseFormFields(JSON.parse(fieldStr), result) }) } - formField.value = result + formFields.value = result } else { - formField.value = [] + formFields.value = [] + unParsedFormFields.value = [] } }, { immediate: true } diff --git a/src/views/bpm/model/form/index.vue b/src/views/bpm/model/form/index.vue index 341d95684..ec8efa287 100644 --- a/src/views/bpm/model/form/index.vue +++ b/src/views/bpm/model/form/index.vue @@ -77,10 +77,7 @@
- +
From 2e796b8fc730d17d11bb780979917ba33c03a5c1 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 16 Aug 2025 15:54:23 +0800 Subject: [PATCH 021/161] =?UTF-8?q?feat=EF=BC=9A=E3=80=90framework=20?= =?UTF-8?q?=E6=A1=86=E6=9E=B6=E3=80=91=E5=A2=9E=E5=8A=A0=20api=20=E5=8A=A0?= =?UTF-8?q?=E8=A7=A3=E5=AF=86=E8=83=BD=E5=8A=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env | 9 ++ src/api/login/index.ts | 8 +- src/config/axios/service.ts | 31 +++++ src/utils/encrypt.ts | 231 ++++++++++++++++++++++++++++++++++++ types/env.d.ts | 6 + 5 files changed, 284 insertions(+), 1 deletion(-) create mode 100644 src/utils/encrypt.ts diff --git a/.env b/.env index 4b0f5bf6a..791102202 100644 --- a/.env +++ b/.env @@ -23,3 +23,12 @@ VITE_APP_BAIDU_CODE = a1ff8825baa73c3a78eb96aa40325abc VITE_APP_DEFAULT_LOGIN_TENANT = 芋道源码 VITE_APP_DEFAULT_LOGIN_USERNAME = admin VITE_APP_DEFAULT_LOGIN_PASSWORD = admin123 + +# API 加解密 +VITE_APP_API_ENCRYPT_ENABLE = true +VITE_APP_API_ENCRYPT_HEADER = X-Api-Encrypt +VITE_APP_API_ENCRYPT_ALGORITHM = AES +VITE_APP_API_ENCRYPT_REQUEST_KEY = 52549111389893486934626385991395 +VITE_APP_API_ENCRYPT_RESPONSE_KEY = 96103715984234343991809655248883 +# VITE_APP_API_ENCRYPT_REQUEST_KEY = MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCls2rIpnGdYnLFgz1XU13GbNQ5DloyPpvW00FPGjqn5Z6JpK+kDtVlnkhwR87iRrE5Vf2WNqRX6vzbLSgveIQY8e8oqGCb829myjf1MuI+ZzN4ghf/7tEYhZJGPI9AbfxFqBUzm+kR3/HByAI22GLT96WM26QiMK8n3tIP/yiLswIDAQAB +# VITE_APP_API_ENCRYPT_RESPONSE_KEY = MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAOH8IfIFxL/MR9XIg1UDv5z1fGXQI93E8wrU4iPFovL/sEt9uSgSkjyidC2O7N+m7EKtoN6b1u7cEwXSkwf3kfK0jdWLSQaNpX5YshqXCBzbDfugDaxuyYrNA4/tIMs7mzZAk0APuRXB35Dmupou7Yw7TFW/7QhQmGfzeEKULQvnAgMBAAECgYAw8LqlQGyQoPv5p3gRxEMOCfgL0JzD3XBJKztiRd35RDh40Nx1ejgjW4dPioFwGiVWd2W8cAGHLzALdcQT2KDJh+T/tsd4SPmI6uSBBK6Ff2DkO+kFFcuYvfclQQKqxma5CaZOSqhgenacmgTMFeg2eKlY3symV6JlFNu/IKU42QJBAOhxAK/Eq3e61aYQV2JSguhMR3b8NXJJRroRs/QHEanksJtl+M+2qhkC9nQVXBmBkndnkU/l2tYcHfSBlAyFySMCQQD445tgm/J2b6qMQmuUGQAYDN8FIkHjeKmha+l/fv0igWm8NDlBAem91lNDIPBUzHL1X1+pcts5bjmq99YdOnhtAkAg2J8dN3B3idpZDiQbC8fd5bGPmdI/pSUudAP27uzLEjr2qrE/QPPGdwm2m7IZFJtK7kK1hKio6u48t/bg0iL7AkEAuUUs94h+v702Fnym+jJ2CHEkXvz2US8UDs52nWrZYiM1o1y4tfSHm8H8bv8JCAa9GHyriEawfBraILOmllFdLQJAQSRZy4wmlaG48MhVXodB85X+VZ9krGXZ2TLhz7kz9iuToy53l9jTkESt6L5BfBDCVdIwcXLYgK+8KFdHN5W7HQ== \ No newline at end of file diff --git a/src/api/login/index.ts b/src/api/login/index.ts index 7d7d407b4..cd5986a0f 100644 --- a/src/api/login/index.ts +++ b/src/api/login/index.ts @@ -13,7 +13,13 @@ export interface SmsLoginVO { // 登录 export const login = (data: UserLoginVO) => { - return request.post({ url: '/system/auth/login', data }) + return request.post({ + url: '/system/auth/login', + data, + headers: { + isEncrypt: true + } + }) } // 注册 diff --git a/src/config/axios/service.ts b/src/config/axios/service.ts index 74280a925..9214bf8ea 100644 --- a/src/config/axios/service.ts +++ b/src/config/axios/service.ts @@ -15,6 +15,7 @@ import errorCode from './errorCode' import { resetRouter } from '@/router' import { deleteUserCache } from '@/hooks/web/useCache' +import { ApiEncrypt } from '@/utils/encrypt' const tenantEnable = import.meta.env.VITE_APP_TENANT_ENABLE const { result_code, base_url, request_timeout } = config @@ -83,6 +84,20 @@ service.interceptors.request.use( } } } + // 是否 API 加密 + if ((config!.headers || {}).isEncrypt) { + try { + // 加密请求数据 + if (config.data) { + config.data = ApiEncrypt.encryptRequest(config.data) + // 设置加密标识头 + config.headers[ApiEncrypt.getEncryptHeader()] = 'true' + } + } catch (error) { + console.error('请求数据加密失败:', error) + throw error + } + } return config }, (error: AxiosError) => { @@ -101,6 +116,22 @@ service.interceptors.response.use( // 返回“[HTTP]请求没有返回值”; throw new Error() } + + // 检查是否需要解密响应数据 + const encryptHeader = ApiEncrypt.getEncryptHeader() + const isEncryptResponse = + response.headers[encryptHeader] === 'true' || + response.headers[encryptHeader.toLowerCase()] === 'true' + if (isEncryptResponse && typeof data === 'string') { + try { + // 解密响应数据 + data = ApiEncrypt.decryptResponse(data) + } catch (error) { + console.error('响应数据解密失败:', error) + throw new Error('响应数据解密失败: ' + (error as Error).message) + } + } + const { t } = useI18n() // 未设置状态码则默认成功状态 // 二进制数据则直接返回,例如说 Excel 导出 diff --git a/src/utils/encrypt.ts b/src/utils/encrypt.ts new file mode 100644 index 000000000..aee289e30 --- /dev/null +++ b/src/utils/encrypt.ts @@ -0,0 +1,231 @@ +import CryptoJS from 'crypto-js' +import { JSEncrypt } from 'jsencrypt' + +/** + * API 加解密工具类 + * 支持 AES 和 RSA 加密算法 + */ + +// 从环境变量获取配置 +const API_ENCRYPT_ENABLE = import.meta.env.VITE_APP_API_ENCRYPT_ENABLE === 'true' +const API_ENCRYPT_HEADER = import.meta.env.VITE_APP_API_ENCRYPT_HEADER || 'X-Api-Encrypt' +const API_ENCRYPT_ALGORITHM = import.meta.env.VITE_APP_API_ENCRYPT_ALGORITHM || 'AES' +const API_ENCRYPT_REQUEST_KEY = import.meta.env.VITE_APP_API_ENCRYPT_REQUEST_KEY || '' // AES密钥 或 RSA公钥 +const API_ENCRYPT_RESPONSE_KEY = import.meta.env.VITE_APP_API_ENCRYPT_RESPONSE_KEY || '' // AES密钥 或 RSA私钥 + +/** + * AES 加密工具类 + */ +export class AES { + /** + * AES 加密 + * @param data 要加密的数据 + * @param key 加密密钥 + * @returns 加密后的字符串 + */ + static encrypt(data: string, key: string): string { + try { + if (!key) { + throw new Error('AES 加密密钥不能为空') + } + if (key.length !== 32) { + throw new Error(`AES 加密密钥长度必须为 32 位,当前长度: ${key.length}`) + } + + const keyUtf8 = CryptoJS.enc.Utf8.parse(key) + const encrypted = CryptoJS.AES.encrypt(data, keyUtf8, { + mode: CryptoJS.mode.ECB, + padding: CryptoJS.pad.Pkcs7 + }) + return encrypted.toString() + } catch (error) { + console.error('AES 加密失败:', error) + throw error + } + } + + /** + * AES 解密 + * @param encryptedData 加密的数据 + * @param key 解密密钥 + * @returns 解密后的字符串 + */ + static decrypt(encryptedData: string, key: string): string { + try { + if (!key) { + throw new Error('AES 解密密钥不能为空') + } + if (key.length !== 32) { + throw new Error(`AES 解密密钥长度必须为 32 位,当前长度: ${key.length}`) + } + if (!encryptedData) { + throw new Error('AES 解密数据不能为空') + } + + const keyUtf8 = CryptoJS.enc.Utf8.parse(key) + const decrypted = CryptoJS.AES.decrypt(encryptedData, keyUtf8, { + mode: CryptoJS.mode.ECB, + padding: CryptoJS.pad.Pkcs7 + }) + const result = decrypted.toString(CryptoJS.enc.Utf8) + if (!result) { + throw new Error('AES 解密结果为空,可能是密钥错误或数据损坏') + } + return result + } catch (error) { + console.error('AES 解密失败:', error) + throw error + } + } +} + +/** + * RSA 加密工具类 + */ +export class RSA { + /** + * RSA 加密 + * @param data 要加密的数据 + * @param publicKey 公钥(必需) + * @returns 加密后的字符串 + */ + static encrypt(data: string, publicKey: string): string | false { + try { + if (!publicKey) { + throw new Error('RSA 公钥不能为空') + } + + const encryptor = new JSEncrypt() + encryptor.setPublicKey(publicKey) + const result = encryptor.encrypt(data) + if (result === false) { + throw new Error('RSA 加密失败,可能是公钥格式错误或数据过长') + } + return result + } catch (error) { + console.error('RSA 加密失败:', error) + throw error + } + } + + /** + * RSA 解密 + * @param encryptedData 加密的数据 + * @param privateKey 私钥(必需) + * @returns 解密后的字符串 + */ + static decrypt(encryptedData: string, privateKey: string): string | false { + try { + if (!privateKey) { + throw new Error('RSA 私钥不能为空') + } + if (!encryptedData) { + throw new Error('RSA 解密数据不能为空') + } + + const encryptor = new JSEncrypt() + encryptor.setPrivateKey(privateKey) + const result = encryptor.decrypt(encryptedData) + if (result === false) { + throw new Error('RSA 解密失败,可能是私钥错误或数据损坏') + } + return result + } catch (error) { + console.error('RSA 解密失败:', error) + throw error + } + } +} + +/** + * API 加解密主类 + */ +export class ApiEncrypt { + /** + * 获取加密头名称 + */ + static getEncryptHeader(): string { + return API_ENCRYPT_HEADER + } + + /** + * 加密请求数据 + * @param data 要加密的数据 + * @returns 加密后的数据 + */ + static encryptRequest(data: any): string { + if (!API_ENCRYPT_ENABLE) { + return data + } + + try { + const jsonData = typeof data === 'string' ? data : JSON.stringify(data) + + if (API_ENCRYPT_ALGORITHM.toUpperCase() === 'AES') { + if (!API_ENCRYPT_REQUEST_KEY) { + throw new Error('AES 请求加密密钥未配置') + } + return AES.encrypt(jsonData, API_ENCRYPT_REQUEST_KEY) + } else if (API_ENCRYPT_ALGORITHM.toUpperCase() === 'RSA') { + if (!API_ENCRYPT_REQUEST_KEY) { + throw new Error('RSA 公钥未配置') + } + const result = RSA.encrypt(jsonData, API_ENCRYPT_REQUEST_KEY) + if (result === false) { + throw new Error('RSA 加密失败') + } + return result + } else { + throw new Error(`不支持的加密算法: ${API_ENCRYPT_ALGORITHM}`) + } + } catch (error) { + console.error('请求数据加密失败:', error) + throw error + } + } + + /** + * 解密响应数据 + * @param encryptedData 加密的响应数据 + * @returns 解密后的数据 + */ + static decryptResponse(encryptedData: string): any { + if (!API_ENCRYPT_ENABLE) { + return encryptedData + } + + try { + let decryptedData: string | false = '' + if (API_ENCRYPT_ALGORITHM.toUpperCase() === 'AES') { + if (!API_ENCRYPT_RESPONSE_KEY) { + throw new Error('AES 响应解密密钥未配置') + } + decryptedData = AES.decrypt(encryptedData, API_ENCRYPT_RESPONSE_KEY) + } else if (API_ENCRYPT_ALGORITHM.toUpperCase() === 'RSA') { + if (!API_ENCRYPT_RESPONSE_KEY) { + throw new Error('RSA 私钥未配置') + } + decryptedData = RSA.decrypt(encryptedData, API_ENCRYPT_RESPONSE_KEY) + if (decryptedData === false) { + throw new Error('RSA 解密失败') + } + } else { + throw new Error(`不支持的解密算法: ${API_ENCRYPT_ALGORITHM}`) + } + + if (!decryptedData) { + throw new Error('解密结果为空') + } + + // 尝试解析为 JSON,如果失败则返回原字符串 + try { + return JSON.parse(decryptedData) + } catch { + return decryptedData + } + } catch (error) { + console.error('响应数据解密失败:', error) + throw error + } + } +} diff --git a/types/env.d.ts b/types/env.d.ts index 124dd5656..17535eafc 100644 --- a/types/env.d.ts +++ b/types/env.d.ts @@ -26,6 +26,12 @@ interface ImportMetaEnv { readonly VITE_SOURCEMAP: string readonly VITE_OUT_DIR: string readonly VITE_GOVIEW_URL: string + // API 加解密相关配置 + readonly VITE_APP_API_ENCRYPT_ENABLE: string + readonly VITE_APP_API_ENCRYPT_HEADER: string + readonly VITE_APP_API_ENCRYPT_ALGORITHM: string + readonly VITE_APP_API_ENCRYPT_REQUEST_KEY: string + readonly VITE_APP_API_ENCRYPT_RESPONSE_KEY: string } declare global { From e9d59f41f97fc8ab87c2efb63d26514e98529cd7 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 16 Aug 2025 17:08:09 +0800 Subject: [PATCH 022/161] =?UTF-8?q?feat=EF=BC=9A=E3=80=90framework=20?= =?UTF-8?q?=E6=A1=86=E6=9E=B6=E3=80=91=E5=A2=9E=E5=8A=A0=20api=20=E5=8A=A0?= =?UTF-8?q?=E8=A7=A3=E5=AF=86=E8=83=BD=E5=8A=9B=EF=BC=88=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E5=85=88=E4=B8=8D=E5=8A=A0=E5=AF=86=EF=BC=8C?= =?UTF-8?q?=E9=81=BF=E5=85=8D=E5=A4=A7=E5=AE=B6=E4=B8=8D=E7=90=86=E8=A7=A3?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/login/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/login/index.ts b/src/api/login/index.ts index cd5986a0f..37eb49112 100644 --- a/src/api/login/index.ts +++ b/src/api/login/index.ts @@ -17,7 +17,7 @@ export const login = (data: UserLoginVO) => { url: '/system/auth/login', data, headers: { - isEncrypt: true + isEncrypt: false } }) } From 6ef3360e1c18fcb2966cdb1f2c2069af9b41211e Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 17 Aug 2025 23:57:56 +0800 Subject: [PATCH 023/161] =?UTF-8?q?feat=EF=BC=9A=E3=80=90infra=20=E5=9F=BA?= =?UTF-8?q?=E7=A1=80=E8=AE=BE=E6=96=BD=E3=80=91=E6=96=87=E4=BB=B6=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E6=97=B6=EF=BC=8C=E5=A2=9E=E5=8A=A0=E2=80=9C=E5=85=AC?= =?UTF-8?q?=E5=BC=80=E8=AE=BF=E9=97=AE=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/infra/fileConfig/index.ts | 1 + src/views/infra/fileConfig/FileConfigForm.vue | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/src/api/infra/fileConfig/index.ts b/src/api/infra/fileConfig/index.ts index 6a69a47ed..e88f825f1 100644 --- a/src/api/infra/fileConfig/index.ts +++ b/src/api/infra/fileConfig/index.ts @@ -12,6 +12,7 @@ export interface FileClientConfig { accessKey?: string accessSecret?: string enablePathStyleAccess?: boolean + enablePublicAccess?: boolean domain: string } diff --git a/src/views/infra/fileConfig/FileConfigForm.vue b/src/views/infra/fileConfig/FileConfigForm.vue index 4f1cc2371..1b774ca65 100644 --- a/src/views/infra/fileConfig/FileConfigForm.vue +++ b/src/views/infra/fileConfig/FileConfigForm.vue @@ -93,6 +93,16 @@ 禁用 + + + 公开 + 私有 + + @@ -146,6 +156,7 @@ const formRules = reactive({ enablePathStyleAccess: [ { required: true, message: '是否 PathStyle 访问不能为空', trigger: 'change' } ], + enablePublicAccess: [{ required: true, message: '公开访问设置不能为空', trigger: 'change' }], domain: [{ required: true, message: '自定义域名不能为空', trigger: 'blur' }] } as FormRules }) From 1a92b97797d048fc1d4fd33b14fa842c3af6e38a Mon Sep 17 00:00:00 2001 From: YunaiV Date: Tue, 19 Aug 2025 00:07:43 +0800 Subject: [PATCH 024/161] =?UTF-8?q?feat=EF=BC=9A=E3=80=90system=20?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E7=AE=A1=E7=90=86=E3=80=91=E7=A7=9F=E6=88=B7?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E6=97=B6=EF=BC=8C=E6=94=AF=E6=8C=81=E5=A1=AB?= =?UTF-8?q?=E5=86=99=E5=A4=9A=E4=B8=AA=E5=9F=9F=E5=90=8D=20websites?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/system/tenant/index.ts | 1 + src/views/system/tenant/TenantForm.vue | 15 +++++++++------ src/views/system/tenant/index.vue | 9 ++++++++- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/api/system/tenant/index.ts b/src/api/system/tenant/index.ts index c51ec7ee0..cd6e5db33 100644 --- a/src/api/system/tenant/index.ts +++ b/src/api/system/tenant/index.ts @@ -12,6 +12,7 @@ export interface TenantVO { password: string expireTime: Date accountCount: number + websites: string[] createTime: Date } diff --git a/src/views/system/tenant/TenantForm.vue b/src/views/system/tenant/TenantForm.vue index 205a2cf0f..e37ab7155 100644 --- a/src/views/system/tenant/TenantForm.vue +++ b/src/views/system/tenant/TenantForm.vue @@ -54,8 +54,12 @@ value-format="x" /> - - + + @@ -97,7 +101,7 @@ const formData = ref({ contactMobile: undefined, accountCount: undefined, expireTime: undefined, - website: undefined, + websites: [], status: CommonStatusEnum.ENABLE, // 新增专属 username: undefined, @@ -105,12 +109,11 @@ const formData = ref({ }) const formRules = reactive({ name: [{ required: true, message: '租户名不能为空', trigger: 'blur' }], - packageId: [{ required: true, message: '租户套餐不能为空', trigger: 'blur' }], + packageId: [{ required: true, message: '租户套���不能为空', trigger: 'blur' }], contactName: [{ required: true, message: '联系人不能为空', trigger: 'blur' }], status: [{ required: true, message: '租户状态不能为空', trigger: 'blur' }], accountCount: [{ required: true, message: '账号额度不能为空', trigger: 'blur' }], expireTime: [{ required: true, message: '过期时间不能为空', trigger: 'blur' }], - website: [{ required: true, message: '绑定域名不能为空', trigger: 'blur' }], username: [{ required: true, message: '用户名称不能为空', trigger: 'blur' }], password: [{ required: true, message: '用户密码不能为空', trigger: 'blur' }] }) @@ -173,7 +176,7 @@ const resetForm = () => { contactMobile: undefined, accountCount: undefined, expireTime: undefined, - website: undefined, + websites: [], status: CommonStatusEnum.ENABLE, username: undefined, password: undefined diff --git a/src/views/system/tenant/index.vue b/src/views/system/tenant/index.vue index 295b68640..59b38670b 100644 --- a/src/views/system/tenant/index.vue +++ b/src/views/system/tenant/index.vue @@ -136,7 +136,14 @@ width="180" :formatter="dateFormatter" /> - + + + + + + + diff --git a/src/views/ai/chat/index/index.vue b/src/views/ai/chat/index/index.vue index fdc466617..42126f115 100644 --- a/src/views/ai/chat/index/index.vue +++ b/src/views/ai/chat/index/index.vue @@ -2,7 +2,7 @@ { return [ { id: 0, + conversationId: activeConversation.value.id || 0, type: 'system', - content: activeConversation.value.systemMessage - } + userId: '', + roleId: '', + model: 0, + modelId: 0, + content: activeConversation.value.systemMessage, + tokens: 0, + createTime: new Date(), + roleAvatar: '', + userAvatar: '' + } as ChatMessageVO ] } return [] @@ -427,6 +436,7 @@ const doSendMessageStream = async (userMessage: ChatMessageVO) => { conversationId: activeConversationId.value, type: 'assistant', content: '思考中...', + reasoningContent: '', createTime: new Date() } as ChatMessageVO) // 1.2 滚动到最下面 @@ -450,9 +460,10 @@ const doSendMessageStream = async (userMessage: ChatMessageVO) => { } // 如果内容为空,就不处理。 - if (data.receive.content === '') { + if (data.receive.content === '' && !data.receive.reasoningContent) { return } + // 首次返回需要添加一个 message 到页面,后面的都是更新 if (isFirstChunk) { isFirstChunk = false @@ -463,12 +474,22 @@ const doSendMessageStream = async (userMessage: ChatMessageVO) => { activeMessageList.value.push(data.send) activeMessageList.value.push(data.receive) } - // debugger - receiveMessageFullText.value = receiveMessageFullText.value + data.receive.content + + // 处理 reasoningContent + if (data.receive.reasoningContent) { + const lastMessage = activeMessageList.value[activeMessageList.value.length - 1] + lastMessage.reasoningContent = + lastMessage.reasoningContent + data.receive.reasoningContent + } + + // 处理正常内容 + if (data.receive.content !== '') { + receiveMessageFullText.value = receiveMessageFullText.value + data.receive.content + } // 滚动到最下面 await scrollToBottom() }, - (error) => { + (error: any) => { message.alert(`对话异常! ${error}`) stopStream() // 需要抛出异常,禁止重试 From 84deeacd4d127ca6b009d51d0d802903167b8416 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 24 Aug 2025 21:30:39 +0800 Subject: [PATCH 030/161] =?UTF-8?q?feat=EF=BC=9A=E3=80=90ai=20=E5=A4=A7?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B=E3=80=91=E5=AF=B9=E8=AF=9D=E5=88=97=E8=A1=A8?= =?UTF-8?q?=EF=BC=8C=E5=A2=9E=E5=8A=A0=20attachment-urls=20=E9=99=84?= =?UTF-8?q?=E4=BB=B6=E7=9A=84=E5=B1=95=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/ai/chat/message/index.ts | 7 +- src/utils/file.ts | 19 ++ src/utils/index.ts | 1 - .../index/components/message/MessageFiles.vue | 165 ++++++++++++++++++ .../index/components/message/MessageList.vue | 8 + 5 files changed, 197 insertions(+), 3 deletions(-) create mode 100644 src/utils/file.ts create mode 100644 src/views/ai/chat/index/components/message/MessageFiles.vue diff --git a/src/api/ai/chat/message/index.ts b/src/api/ai/chat/message/index.ts index 023333665..193e87b79 100644 --- a/src/api/ai/chat/message/index.ts +++ b/src/api/ai/chat/message/index.ts @@ -14,6 +14,7 @@ export interface ChatMessageVO { modelId: number // 模型编号 content: string // 聊天内容 reasoningContent?: string // 推理内容 + attachmentUrls?: string[] // 附件 URL 数组 tokens: number // 消耗 Token 数量 segmentIds?: number[] // 段落编号 segments?: { @@ -45,7 +46,8 @@ export const ChatMessageApi = { enableContext: boolean, onMessage, onError, - onClose + onClose, + attachmentUrls?: string[] ) => { const token = getAccessToken() return fetchEventSource(`${config.base_url}/ai/chat/message/send-stream`, { @@ -58,7 +60,8 @@ export const ChatMessageApi = { body: JSON.stringify({ conversationId, content, - useContext: enableContext + useContext: enableContext, + attachmentUrls: attachmentUrls || [] }), onmessage: onMessage, onerror: onError, diff --git a/src/utils/file.ts b/src/utils/file.ts new file mode 100644 index 000000000..c8bccbd30 --- /dev/null +++ b/src/utils/file.ts @@ -0,0 +1,19 @@ +/** 从 URL 中提取文件名 */ +export const getFileNameFromUrl = (url: string): string => { + try { + const urlObj = new URL(url) + const pathname = urlObj.pathname + const fileName = pathname.split('/').pop() || 'unknown' + return decodeURIComponent(fileName) + } catch { + // 如果 URL 解析失败,尝试从字符串中提取 + const parts = url.split('/') + return parts[parts.length - 1] || 'unknown' + } +} + +/** 判断是否为图片 */ +export const isImage = (filename: string): boolean => { + const ext = filename.split('.').pop()?.toLowerCase() || '' + return ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg'].includes(ext) +} diff --git a/src/utils/index.ts b/src/utils/index.ts index f0b4faaef..0bcedb438 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -529,7 +529,6 @@ export function jsonParse(str: string) { * @param start 开始位置 * @param end 结束位置 */ - export const subString = (str: string, start: number, end: number) => { if (str.length > end) { return str.slice(start, end) diff --git a/src/views/ai/chat/index/components/message/MessageFiles.vue b/src/views/ai/chat/index/components/message/MessageFiles.vue new file mode 100644 index 000000000..9362c994b --- /dev/null +++ b/src/views/ai/chat/index/components/message/MessageFiles.vue @@ -0,0 +1,165 @@ + + + + + diff --git a/src/views/ai/chat/index/components/message/MessageList.vue b/src/views/ai/chat/index/components/message/MessageList.vue index 5efd39c5f..12ce67101 100644 --- a/src/views/ai/chat/index/components/message/MessageList.vue +++ b/src/views/ai/chat/index/components/message/MessageList.vue @@ -22,6 +22,7 @@ class="text-[var(--el-text-color-primary)] text-[0.95rem]" :content="item.content" /> +
@@ -52,8 +53,14 @@
{{ formatDate(item.createTime) }}
+ +
+ +
+
{{ item.content }} @@ -104,6 +111,7 @@ import { formatDate } from '@/utils/formatTime' import MarkdownView from '@/components/MarkdownView/index.vue' import MessageKnowledge from './MessageKnowledge.vue' import MessageReasoning from './MessageReasoning.vue' +import MessageFiles from './MessageFiles.vue' import { useClipboard } from '@vueuse/core' import { ArrowDownBold, Edit, RefreshRight } from '@element-plus/icons-vue' import { ChatMessageApi, ChatMessageVO } from '@/api/ai/chat/message' From 61dad44cd98ea10a0f045bfd677266a71d1aaf65 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 24 Aug 2025 22:00:54 +0800 Subject: [PATCH 031/161] =?UTF-8?q?feat=EF=BC=9A=E3=80=90ai=20=E5=A4=A7?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B=E3=80=91=E5=AF=B9=E8=AF=9D=E5=88=97=E8=A1=A8?= =?UTF-8?q?=EF=BC=8C=E5=A2=9E=E5=8A=A0=20attachment-urls=20=E5=8F=91?= =?UTF-8?q?=E9=80=81=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/message/MessageFileUpload.vue | 424 ++++++++++++++++++ 1 file changed, 424 insertions(+) create mode 100644 src/views/ai/chat/index/components/message/MessageFileUpload.vue diff --git a/src/views/ai/chat/index/components/message/MessageFileUpload.vue b/src/views/ai/chat/index/components/message/MessageFileUpload.vue new file mode 100644 index 000000000..732529779 --- /dev/null +++ b/src/views/ai/chat/index/components/message/MessageFileUpload.vue @@ -0,0 +1,424 @@ + + + + + From b880ec22f200103e345e37f399f592da2738eef6 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 24 Aug 2025 22:00:58 +0800 Subject: [PATCH 032/161] =?UTF-8?q?feat=EF=BC=9A=E3=80=90ai=20=E5=A4=A7?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B=E3=80=91=E5=AF=B9=E8=AF=9D=E5=88=97=E8=A1=A8?= =?UTF-8?q?=EF=BC=8C=E5=A2=9E=E5=8A=A0=20attachment-urls=20=E5=8F=91?= =?UTF-8?q?=E9=80=81=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/file.ts | 18 +++++++++++++ .../index/components/message/MessageFiles.vue | 11 +------- .../index/components/message/MessageList.vue | 5 +++- src/views/ai/chat/index/index.vue | 27 +++++++++++++++---- 4 files changed, 45 insertions(+), 16 deletions(-) diff --git a/src/utils/file.ts b/src/utils/file.ts index c8bccbd30..e40651932 100644 --- a/src/utils/file.ts +++ b/src/utils/file.ts @@ -17,3 +17,21 @@ export const isImage = (filename: string): boolean => { const ext = filename.split('.').pop()?.toLowerCase() || '' return ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg'].includes(ext) } + +/** 格式化文件大小 */ +export const formatFileSize = (bytes: number): string => { + if (bytes === 0) return '0 B' + const k = 1024 + const sizes = ['B', 'KB', 'MB', 'GB'] + const i = Math.floor(Math.log(bytes) / Math.log(k)) + return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i] +} + +/** 获取文件图标 */ +export const getFileIcon = (filename: string): string => { + const ext = filename.split('.').pop()?.toLowerCase() || '' + if (isImage(ext)) { + return 'ep:picture' + } + return 'ep:document' +} diff --git a/src/views/ai/chat/index/components/message/MessageFiles.vue b/src/views/ai/chat/index/components/message/MessageFiles.vue index 9362c994b..3a9982430 100644 --- a/src/views/ai/chat/index/components/message/MessageFiles.vue +++ b/src/views/ai/chat/index/components/message/MessageFiles.vue @@ -23,7 +23,7 @@ - - diff --git a/src/views/ai/chat/index/index.vue b/src/views/ai/chat/index/index.vue index 4bcc24056..2b96010f8 100644 --- a/src/views/ai/chat/index/index.vue +++ b/src/views/ai/chat/index/index.vue @@ -488,6 +488,7 @@ const doSendMessageStream = async (userMessage: ChatMessageVO) => { activeMessageList.value.pop() // 更新返回的数据 activeMessageList.value.push(data.send) + data.send.attachmentUrls = userMessage.attachmentUrls activeMessageList.value.push(data.receive) } From b8a1fbcb140053d35672ebf52cc036a1f1ca792c Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 24 Aug 2025 22:27:39 +0800 Subject: [PATCH 034/161] =?UTF-8?q?feat=EF=BC=9A=E3=80=90ai=20=E5=A4=A7?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B=E3=80=91=E5=AF=B9=E8=AF=9D=E5=88=97=E8=A1=A8?= =?UTF-8?q?=EF=BC=8C=E5=A2=9E=E5=8A=A0=20attachment-urls=20=E5=8F=91?= =?UTF-8?q?=E9=80=81=E9=80=BB=E8=BE=91=EF=BC=88unocss=20=E6=A0=B7=E5=BC=8F?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/message/MessageFileUpload.vue | 188 ++++++++---------- 1 file changed, 79 insertions(+), 109 deletions(-) diff --git a/src/views/ai/chat/index/components/message/MessageFileUpload.vue b/src/views/ai/chat/index/components/message/MessageFileUpload.vue index 732529779..8d7dc0f3a 100644 --- a/src/views/ai/chat/index/components/message/MessageFileUpload.vue +++ b/src/views/ai/chat/index/components/message/MessageFileUpload.vue @@ -1,22 +1,27 @@ diff --git a/src/views/bpm/model/form/PrintTemplate/Index.vue b/src/views/bpm/model/form/PrintTemplate/Index.vue new file mode 100644 index 000000000..ddb4383ca --- /dev/null +++ b/src/views/bpm/model/form/PrintTemplate/Index.vue @@ -0,0 +1,107 @@ + + + + + diff --git a/src/views/bpm/model/form/PrintTemplate/MentionModal.vue b/src/views/bpm/model/form/PrintTemplate/MentionModal.vue new file mode 100644 index 000000000..c990ea0e6 --- /dev/null +++ b/src/views/bpm/model/form/PrintTemplate/MentionModal.vue @@ -0,0 +1,99 @@ + + + + + diff --git a/src/views/bpm/model/form/PrintTemplate/index.ts b/src/views/bpm/model/form/PrintTemplate/index.ts new file mode 100644 index 000000000..1f5298e39 --- /dev/null +++ b/src/views/bpm/model/form/PrintTemplate/index.ts @@ -0,0 +1,9 @@ +import {Boot} from '@wangeditor/editor' +import processRecordModule from "./module"; +import mentionModule from "@wangeditor/plugin-mention"; + +// 注册。要在创建编辑器之前注册,且只能注册一次,不可重复注册。 +export const setupWangeditorPlugin = () => { + Boot.registerModule(processRecordModule) + Boot.registerModule(mentionModule) +} diff --git a/src/views/bpm/model/form/PrintTemplate/module/elem-to-html.ts b/src/views/bpm/model/form/PrintTemplate/module/elem-to-html.ts new file mode 100644 index 000000000..3b688c357 --- /dev/null +++ b/src/views/bpm/model/form/PrintTemplate/module/elem-to-html.ts @@ -0,0 +1,12 @@ +import { SlateElement } from '@wangeditor/editor' + +function processRecordToHtml(elem: SlateElement, childrenHtml: string): string { + return `流程记录` +} + +const conf = { + type: 'process-record', + elemToHtml: processRecordToHtml, +} + +export default conf diff --git a/src/views/bpm/model/form/PrintTemplate/module/index.ts b/src/views/bpm/model/form/PrintTemplate/module/index.ts new file mode 100644 index 000000000..813b8ebf5 --- /dev/null +++ b/src/views/bpm/model/form/PrintTemplate/module/index.ts @@ -0,0 +1,16 @@ +import {IModuleConf} from '@wangeditor/editor' +import withProcessRecord from './plugin' +import renderElemConf from './render-elem' +import elemToHtmlConf from './elem-to-html' +import parseHtmlConf from './parse-elem-html' +import processRecordMenu from "./menu/ProcessRecordMenu" + +const module: Partial = { + editorPlugin: withProcessRecord, + renderElems: [renderElemConf], + elemsToHtml: [elemToHtmlConf], + parseElemsHtml: [parseHtmlConf], + menus: [processRecordMenu], +} + +export default module diff --git a/src/views/bpm/model/form/PrintTemplate/module/menu/ProcessRecordMenu.ts b/src/views/bpm/model/form/PrintTemplate/module/menu/ProcessRecordMenu.ts new file mode 100644 index 000000000..076ec0e65 --- /dev/null +++ b/src/views/bpm/model/form/PrintTemplate/module/menu/ProcessRecordMenu.ts @@ -0,0 +1,42 @@ +import { IButtonMenu, IDomEditor } from '@wangeditor/editor' + +class ProcessRecordMenu implements IButtonMenu { + readonly tag: string; + readonly title: string; + + constructor() { + this.title = '流程记录' + this.tag = 'button' + } + + getValue(editor: IDomEditor): string { + return '' + } + + isActive(editor: IDomEditor): boolean { + return false + } + + isDisabled(editor: IDomEditor): boolean { + return false + } + + exec(editor: IDomEditor, value: string) { + if (this.isDisabled(editor)) return + const processRecordElem = { + type: 'process-record', + children: [{ text: '' }], + } + editor.insertNode(processRecordElem) + editor.move(1) + } +} + +const ProcessRecordMenuConf = { + key: 'ProcessRecordMenu', + factory() { + return new ProcessRecordMenu() + } +} + +export default ProcessRecordMenuConf diff --git a/src/views/bpm/model/form/PrintTemplate/module/parse-elem-html.ts b/src/views/bpm/model/form/PrintTemplate/module/parse-elem-html.ts new file mode 100644 index 000000000..44925cfb1 --- /dev/null +++ b/src/views/bpm/model/form/PrintTemplate/module/parse-elem-html.ts @@ -0,0 +1,20 @@ +import { DOMElement } from './utils/dom' +import { IDomEditor, SlateDescendant, SlateElement } from '@wangeditor/editor' + +function parseHtml( + elem: DOMElement, + children: SlateDescendant[], + editor: IDomEditor +): SlateElement { + return { + type: 'process-record', + children: [{ text: '' }], + } +} + +const parseHtmlConf = { + selector: 'span[data-w-e-type="process-record"]', + parseElemHtml: parseHtml, +} + +export default parseHtmlConf diff --git a/src/views/bpm/model/form/PrintTemplate/module/plugin.ts b/src/views/bpm/model/form/PrintTemplate/module/plugin.ts new file mode 100644 index 000000000..40cdd193e --- /dev/null +++ b/src/views/bpm/model/form/PrintTemplate/module/plugin.ts @@ -0,0 +1,28 @@ +import { DomEditor, IDomEditor } from '@wangeditor/editor' + +function withProcessRecord(editor: T) { + const { isInline, isVoid } = editor + const newEditor = editor + + newEditor.isInline = elem => { + const type = DomEditor.getNodeType(elem) + if (type === 'process-record') { + return true + } + + return isInline(elem) + } + + newEditor.isVoid = elem => { + const type = DomEditor.getNodeType(elem) + if (type === 'process-record') { + return true + } + + return isVoid(elem) + } + + return newEditor +} + +export default withProcessRecord diff --git a/src/views/bpm/model/form/PrintTemplate/module/render-elem.ts b/src/views/bpm/model/form/PrintTemplate/module/render-elem.ts new file mode 100644 index 000000000..58a9e6b0e --- /dev/null +++ b/src/views/bpm/model/form/PrintTemplate/module/render-elem.ts @@ -0,0 +1,72 @@ +import {h, VNode} from 'snabbdom' +import {DomEditor, IDomEditor, SlateElement} from '@wangeditor/editor' + +function renderProcessRecord(elem: SlateElement, children: VNode[] | null, editor: IDomEditor): VNode { + const selected = DomEditor.isNodeSelected(editor, elem) + + const vnode = h( + 'table', + { + props: { + contentEditable: false, + }, + style: { + width: '100%', + border: selected + ? '2px solid var(--w-e-textarea-selected-border-color)' + : '', + }, + }, + [ + h('thead', [ + h('tr', [h('th', {attrs: {colSpan: 3}}, '流程记录')]) + ]), + h('tbody', [ + h('tr', [ + h('td', [h( + 'span', + { + props: { + contentEditable: false, + }, + style: { + marginLeft: '3px', + marginRight: '3px', + backgroundColor: 'var(--w-e-textarea-slight-bg-color)', + borderRadius: '3px', + padding: '0 3px', + }, + }, + `节点` + ) + ]), + h('td', [h( + 'span', + { + props: { + contentEditable: false, + }, + style: { + marginLeft: '3px', + marginRight: '3px', + backgroundColor: 'var(--w-e-textarea-slight-bg-color)', + borderRadius: '3px', + padding: '0 3px', + }, + }, + `操作` + ) + ]) + ]) + ]) + ] + ) + return vnode +} + +const conf = { + type: 'process-record', + renderElem: renderProcessRecord, +} + +export default conf diff --git a/src/views/bpm/model/form/PrintTemplate/module/utils/dom.ts b/src/views/bpm/model/form/PrintTemplate/module/utils/dom.ts new file mode 100644 index 000000000..89ab553ef --- /dev/null +++ b/src/views/bpm/model/form/PrintTemplate/module/utils/dom.ts @@ -0,0 +1,21 @@ +import $, { append, on, hide, click } from 'dom7' + +if (hide) $.fn.hide = hide +if (append) $.fn.append = append +if (click) $.fn.click = click +if (on) $.fn.on = on + +export { Dom7Array } from 'dom7' +export default $ + +// COMPAT: This is required to prevent TypeScript aliases from doing some very +// weird things for Slate's types with the same name as globals. (2019/11/27) +// https://github.com/microsoft/TypeScript/issues/35002 +import DOMNode = globalThis.Node +import DOMComment = globalThis.Comment +import DOMElement = globalThis.Element +import DOMText = globalThis.Text +import DOMRange = globalThis.Range +import DOMSelection = globalThis.Selection +import DOMStaticRange = globalThis.StaticRange +export { DOMNode, DOMComment, DOMElement, DOMText, DOMRange, DOMSelection, DOMStaticRange } diff --git a/src/views/bpm/model/form/index.vue b/src/views/bpm/model/form/index.vue index 1933e4314..9974f0829 100644 --- a/src/views/bpm/model/form/index.vue +++ b/src/views/bpm/model/form/index.vue @@ -174,7 +174,10 @@ const formData: any = ref({ enable: false, summary: [] }, - allowWithdrawTask: false + allowWithdrawTask: false, + printTemplateSetting: { + enable: false + } }) // 流程数据 From 77e84cc4fa65ede51395136818474e71fb29af53 Mon Sep 17 00:00:00 2001 From: Lesan <1960681385@qq.com> Date: Fri, 29 Aug 2025 15:03:51 +0800 Subject: [PATCH 040/161] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E8=A1=A8?= =?UTF-8?q?=E5=8D=95=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/bpm/model/form/ExtraSettings.vue | 3 ++- src/views/bpm/model/form/PrintTemplate/Index.vue | 16 ++++++++++------ .../model/form/PrintTemplate/MentionModal.vue | 12 +++++++++++- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/views/bpm/model/form/ExtraSettings.vue b/src/views/bpm/model/form/ExtraSettings.vue index 73d316a9b..a1e904b85 100644 --- a/src/views/bpm/model/form/ExtraSettings.vue +++ b/src/views/bpm/model/form/ExtraSettings.vue @@ -418,6 +418,7 @@ const formFieldOptions4Summary = computed(() => { const unParsedFormFields = ref([]) /** 暴露给子组件 HttpRequestSetting 使用 */ provide('formFields', unParsedFormFields) +provide('formFieldsObj', formFields) /** 兼容以前未配置更多设置的流程 */ const initData = () => { @@ -491,7 +492,7 @@ watch( ) // TODO defaultTemplate 是否需要放到 infra_config -const defaultTemplate = '

@流程名称

打印人:@打印人

流程编号:@流程编号                        打印时间:@打印时间

发起人@发起人发起时间@发起时间
所属部门@发起人部门流程状态@流程状态

流程记录

' +const defaultTemplate = '

@流程名称

打印人:@打印人

流程编号:@流程编号                        打印时间:@打印时间

发起人@发起人发起时间@发起时间
所属部门@发起人部门流程状态@流程状态

流程记录

' const handlePrintTemplateEnableChange = (val: boolean) => { if (val) { if (!modelData.value.printTemplateSetting.template) { diff --git a/src/views/bpm/model/form/PrintTemplate/Index.vue b/src/views/bpm/model/form/PrintTemplate/Index.vue index ddb4383ca..9b95f6d6b 100644 --- a/src/views/bpm/model/form/PrintTemplate/Index.vue +++ b/src/views/bpm/model/form/PrintTemplate/Index.vue @@ -76,8 +76,11 @@ onBeforeUnmount(() => { - + From df3efa9ca5da9dcfcdad16032f210425638d3d7d Mon Sep 17 00:00:00 2001 From: Lesan <1960681385@qq.com> Date: Fri, 29 Aug 2025 15:31:44 +0800 Subject: [PATCH 042/161] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E6=89=93?= =?UTF-8?q?=E5=8D=B0=E6=8C=89=E9=92=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/bpm/processInstance/detail/index.vue | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/views/bpm/processInstance/detail/index.vue b/src/views/bpm/processInstance/detail/index.vue index c3f83cf06..fc32d2f42 100644 --- a/src/views/bpm/processInstance/detail/index.vue +++ b/src/views/bpm/processInstance/detail/index.vue @@ -8,7 +8,10 @@ :src="auditIconsMap[processInstance.status]" alt="" /> -
编号:{{ id }}
+
+
编号:{{ id }}
+ +
{{ processInstance.name }}
@@ -295,6 +298,10 @@ const refresh = () => { getDetail() } +const handlePrint = () => { + // TODO 打印 +} + /** 当前的Tab */ const activeTab = ref('form') From fa3f9eca1444c0c631337e39ab40781de1c9363d Mon Sep 17 00:00:00 2001 From: YunaiV Date: Fri, 29 Aug 2025 21:08:07 +0800 Subject: [PATCH 043/161] =?UTF-8?q?chore=EF=BC=9Aelement-plus=20from=202.9?= =?UTF-8?q?.1=20to=202.11.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 4 +- pnpm-lock.yaml | 251 ++++++++++++++++++++++++++----------------------- 2 files changed, 137 insertions(+), 118 deletions(-) diff --git a/package.json b/package.json index d3097b3db..b0aea4c44 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "lint:lint-staged": "lint-staged -c " }, "dependencies": { - "@element-plus/icons-vue": "^2.1.0", + "@element-plus/icons-vue": "2.3.2", "@form-create/designer": "^3.2.6", "@form-create/element-ui": "^3.2.11", "@iconify/iconify": "^3.1.1", @@ -47,7 +47,7 @@ "driver.js": "^1.3.1", "echarts": "^5.5.0", "echarts-wordcloud": "^2.1.0", - "element-plus": "2.9.1", + "element-plus": "2.11.1", "fast-xml-parser": "^4.3.2", "highlight.js": "^11.9.0", "jsencrypt": "^3.3.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ef52795ff..ee421c275 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,8 +9,8 @@ importers: .: dependencies: '@element-plus/icons-vue': - specifier: ^2.1.0 - version: 2.3.1(vue@3.5.12(typescript@5.3.3)) + specifier: 2.3.2 + version: 2.3.2(vue@3.5.12(typescript@5.3.3)) '@form-create/designer': specifier: ^3.2.6 version: 3.2.8(vue@3.5.12(typescript@5.3.3)) @@ -42,8 +42,8 @@ importers: specifier: ^4.1.1 version: 4.1.1 axios: - specifier: ^1.6.8 - version: 1.7.8 + specifier: 1.9.0 + version: 1.9.0 benz-amr-recorder: specifier: ^1.1.5 version: 1.1.5 @@ -75,8 +75,8 @@ importers: specifier: ^2.1.0 version: 2.1.0(echarts@5.5.1) element-plus: - specifier: 2.9.1 - version: 2.9.1(vue@3.5.12(typescript@5.3.3)) + specifier: 2.11.1 + version: 2.11.1(vue@3.5.12(typescript@5.3.3)) fast-xml-parser: specifier: ^4.3.2 version: 4.5.0 @@ -874,7 +874,7 @@ packages: engines: {node: '>=6.9.0'} '@bpmn-io/cm-theme@0.1.0-alpha.2': - resolution: {integrity: sha512-ZILgiYzxk3KMvxplUXmdRFQo45/JehDPg5k9tWfehmzUOSE13ssyLPil8uCloMQnb3yyzyOWTjb/wzKXTHlFQw==} + resolution: {integrity: sha512-ZILgiYzxk3KMvxplUXmdRFQo45/JehDPg5k9tWfehmzUOSE13ssyLPil8uCloMQnb3yyzyOWTjb/wzKXTHlFQw==, tarball: https://registry.npmmirror.com/@bpmn-io/cm-theme/-/cm-theme-0.1.0-alpha.2.tgz} '@bpmn-io/diagram-js-ui@0.2.3': resolution: {integrity: sha512-OGyjZKvGK8tHSZ0l7RfeKhilGoOGtFDcoqSGYkX0uhFlo99OVZ9Jn1K7TJGzcE9BdKwvA5Y5kGqHEhdTxHvFfw==, tarball: https://registry.npmmirror.com/@bpmn-io/diagram-js-ui/-/diagram-js-ui-0.2.3.tgz} @@ -883,17 +883,17 @@ packages: resolution: {integrity: sha512-yAS7ZYX+D56K+luC36u96eRMLb4VHcPUwTUqMZ/Z/Je2gou2DJLRbuBTHAB4jjKt4wFCHSG4B8Y+TrBciEYf4w==, tarball: https://registry.npmmirror.com/@bpmn-io/extract-process-variables/-/extract-process-variables-0.8.0.tgz} '@bpmn-io/feel-editor@1.9.1': - resolution: {integrity: sha512-UxSORdh5cwKM4fib4f9ov6J1/BHGpQVNtA+wPyEdKQyCyz3wqwE2/xe5wneVR1j5QFC5m2Na8nTy4a1TDFvZTw==} + resolution: {integrity: sha512-UxSORdh5cwKM4fib4f9ov6J1/BHGpQVNtA+wPyEdKQyCyz3wqwE2/xe5wneVR1j5QFC5m2Na8nTy4a1TDFvZTw==, tarball: https://registry.npmmirror.com/@bpmn-io/feel-editor/-/feel-editor-1.9.1.tgz} engines: {node: '>= 16'} '@bpmn-io/feel-lint@1.3.1': - resolution: {integrity: sha512-wcFkJKhOm/iqCt5bzkKvxL5Dr9wKwUD+t164bQYbJsTYouAqmkkxiGsoqck42hXwdIhMSguZ+vqQ3hj5QdiYCA==} + resolution: {integrity: sha512-wcFkJKhOm/iqCt5bzkKvxL5Dr9wKwUD+t164bQYbJsTYouAqmkkxiGsoqck42hXwdIhMSguZ+vqQ3hj5QdiYCA==, tarball: https://registry.npmmirror.com/@bpmn-io/feel-lint/-/feel-lint-1.3.1.tgz} '@bpmn-io/properties-panel@3.25.0': - resolution: {integrity: sha512-SRGgj8uJc1Yyjcht2g36Q+xKR7sTx5VZXvcwDrdmQKlx5Y3nRmvmMjDGzeGDJDb7pNU1DSlaBJic84uISDBMWg==} + resolution: {integrity: sha512-SRGgj8uJc1Yyjcht2g36Q+xKR7sTx5VZXvcwDrdmQKlx5Y3nRmvmMjDGzeGDJDb7pNU1DSlaBJic84uISDBMWg==, tarball: https://registry.npmmirror.com/@bpmn-io/properties-panel/-/properties-panel-3.25.0.tgz} '@codemirror/autocomplete@6.18.3': - resolution: {integrity: sha512-1dNIOmiM0z4BIBwxmxEfA1yoxh1MF/6KPBbh20a5vphGV0ictKlgQsbJs6D6SkR6iJpGbpwRsa6PFMNlg9T9pQ==} + resolution: {integrity: sha512-1dNIOmiM0z4BIBwxmxEfA1yoxh1MF/6KPBbh20a5vphGV0ictKlgQsbJs6D6SkR6iJpGbpwRsa6PFMNlg9T9pQ==, tarball: https://registry.npmmirror.com/@codemirror/autocomplete/-/autocomplete-6.18.3.tgz} peerDependencies: '@codemirror/language': ^6.0.0 '@codemirror/state': ^6.0.0 @@ -901,19 +901,19 @@ packages: '@lezer/common': ^1.0.0 '@codemirror/commands@6.7.1': - resolution: {integrity: sha512-llTrboQYw5H4THfhN4U3qCnSZ1SOJ60ohhz+SzU0ADGtwlc533DtklQP0vSFaQuCPDn3BPpOd1GbbnUtwNjsrw==} + resolution: {integrity: sha512-llTrboQYw5H4THfhN4U3qCnSZ1SOJ60ohhz+SzU0ADGtwlc533DtklQP0vSFaQuCPDn3BPpOd1GbbnUtwNjsrw==, tarball: https://registry.npmmirror.com/@codemirror/commands/-/commands-6.7.1.tgz} '@codemirror/language@6.10.6': - resolution: {integrity: sha512-KrsbdCnxEztLVbB5PycWXFxas4EOyk/fPAfruSOnDDppevQgid2XZ+KbJ9u+fDikP/e7MW7HPBTvTb8JlZK9vA==} + resolution: {integrity: sha512-KrsbdCnxEztLVbB5PycWXFxas4EOyk/fPAfruSOnDDppevQgid2XZ+KbJ9u+fDikP/e7MW7HPBTvTb8JlZK9vA==, tarball: https://registry.npmmirror.com/@codemirror/language/-/language-6.10.6.tgz} '@codemirror/lint@6.8.4': - resolution: {integrity: sha512-u4q7PnZlJUojeRe8FJa/njJcMctISGgPQ4PnWsd9268R4ZTtU+tfFYmwkBvgcrK2+QQ8tYFVALVb5fVJykKc5A==} + resolution: {integrity: sha512-u4q7PnZlJUojeRe8FJa/njJcMctISGgPQ4PnWsd9268R4ZTtU+tfFYmwkBvgcrK2+QQ8tYFVALVb5fVJykKc5A==, tarball: https://registry.npmmirror.com/@codemirror/lint/-/lint-6.8.4.tgz} '@codemirror/state@6.4.1': - resolution: {integrity: sha512-QkEyUiLhsJoZkbumGZlswmAhA7CBU02Wrz7zvH4SrcifbsqwlXShVXg65f3v/ts57W3dqyamEriMhij1Z3Zz4A==} + resolution: {integrity: sha512-QkEyUiLhsJoZkbumGZlswmAhA7CBU02Wrz7zvH4SrcifbsqwlXShVXg65f3v/ts57W3dqyamEriMhij1Z3Zz4A==, tarball: https://registry.npmmirror.com/@codemirror/state/-/state-6.4.1.tgz} '@codemirror/view@6.35.0': - resolution: {integrity: sha512-I0tYy63q5XkaWsJ8QRv5h6ves7kvtrBWjBcnf/bzohFJQc5c14a1AQRdE8QpPF9eMp5Mq2FMm59TCj1gDfE7kw==} + resolution: {integrity: sha512-I0tYy63q5XkaWsJ8QRv5h6ves7kvtrBWjBcnf/bzohFJQc5c14a1AQRdE8QpPF9eMp5Mq2FMm59TCj1gDfE7kw==, tarball: https://registry.npmmirror.com/@codemirror/view/-/view-6.35.0.tgz} '@commitlint/cli@19.6.0': resolution: {integrity: sha512-v17BgGD9w5KnthaKxXnEg6KLq6DYiAxyiN44TpiRtqyW8NSq+Kx99mkEG8Qo6uu6cI5eMzMojW2muJxjmPnF8w==, tarball: https://registry.npmmirror.com/@commitlint/cli/-/cli-19.6.0.tgz} @@ -1014,145 +1014,145 @@ packages: '@dual-bundle/import-meta-resolve@4.1.0': resolution: {integrity: sha512-+nxncfwHM5SgAtrVzgpzJOI1ol0PkumhVo469KCf9lUi21IGcY90G98VuHm9VRrUypmAzawAHO9bs6hqeADaVg==, tarball: https://registry.npmmirror.com/@dual-bundle/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz} - '@element-plus/icons-vue@2.3.1': - resolution: {integrity: sha512-XxVUZv48RZAd87ucGS48jPf6pKu0yV5UCg9f4FFwtrYxXOwWuVJo6wOvSLKEoMQKjv8GsX/mhP6UsC1lRwbUWg==, tarball: https://registry.npmmirror.com/@element-plus/icons-vue/-/icons-vue-2.3.1.tgz} + '@element-plus/icons-vue@2.3.2': + resolution: {integrity: sha512-OzIuTaIfC8QXEPmJvB4Y4kw34rSXdCJzxcD1kFStBvr8bK6X1zQAYDo0CNMjojnfTqRQCJ0I7prlErcoRiET2A==, tarball: https://registry.npmmirror.com/@element-plus/icons-vue/-/icons-vue-2.3.2.tgz} peerDependencies: vue: ^3.2.0 '@esbuild/aix-ppc64@0.19.12': - resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==} + resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==, tarball: https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz} engines: {node: '>=12'} cpu: [ppc64] os: [aix] '@esbuild/android-arm64@0.19.12': - resolution: {integrity: sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==} + resolution: {integrity: sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==, tarball: https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz} engines: {node: '>=12'} cpu: [arm64] os: [android] '@esbuild/android-arm@0.19.12': - resolution: {integrity: sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==} + resolution: {integrity: sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==, tarball: https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.19.12.tgz} engines: {node: '>=12'} cpu: [arm] os: [android] '@esbuild/android-x64@0.19.12': - resolution: {integrity: sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==} + resolution: {integrity: sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==, tarball: https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.19.12.tgz} engines: {node: '>=12'} cpu: [x64] os: [android] '@esbuild/darwin-arm64@0.19.12': - resolution: {integrity: sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==} + resolution: {integrity: sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==, tarball: https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz} engines: {node: '>=12'} cpu: [arm64] os: [darwin] '@esbuild/darwin-x64@0.19.12': - resolution: {integrity: sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==} + resolution: {integrity: sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==, tarball: https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz} engines: {node: '>=12'} cpu: [x64] os: [darwin] '@esbuild/freebsd-arm64@0.19.12': - resolution: {integrity: sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==} + resolution: {integrity: sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==, tarball: https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] '@esbuild/freebsd-x64@0.19.12': - resolution: {integrity: sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==} + resolution: {integrity: sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==, tarball: https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz} engines: {node: '>=12'} cpu: [x64] os: [freebsd] '@esbuild/linux-arm64@0.19.12': - resolution: {integrity: sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==} + resolution: {integrity: sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==, tarball: https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz} engines: {node: '>=12'} cpu: [arm64] os: [linux] '@esbuild/linux-arm@0.19.12': - resolution: {integrity: sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==} + resolution: {integrity: sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==, tarball: https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz} engines: {node: '>=12'} cpu: [arm] os: [linux] '@esbuild/linux-ia32@0.19.12': - resolution: {integrity: sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==} + resolution: {integrity: sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==, tarball: https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz} engines: {node: '>=12'} cpu: [ia32] os: [linux] '@esbuild/linux-loong64@0.19.12': - resolution: {integrity: sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==} + resolution: {integrity: sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==, tarball: https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz} engines: {node: '>=12'} cpu: [loong64] os: [linux] '@esbuild/linux-mips64el@0.19.12': - resolution: {integrity: sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==} + resolution: {integrity: sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==, tarball: https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz} engines: {node: '>=12'} cpu: [mips64el] os: [linux] '@esbuild/linux-ppc64@0.19.12': - resolution: {integrity: sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==} + resolution: {integrity: sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==, tarball: https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz} engines: {node: '>=12'} cpu: [ppc64] os: [linux] '@esbuild/linux-riscv64@0.19.12': - resolution: {integrity: sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==} + resolution: {integrity: sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==, tarball: https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz} engines: {node: '>=12'} cpu: [riscv64] os: [linux] '@esbuild/linux-s390x@0.19.12': - resolution: {integrity: sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==} + resolution: {integrity: sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==, tarball: https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz} engines: {node: '>=12'} cpu: [s390x] os: [linux] '@esbuild/linux-x64@0.19.12': - resolution: {integrity: sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==} + resolution: {integrity: sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==, tarball: https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz} engines: {node: '>=12'} cpu: [x64] os: [linux] '@esbuild/netbsd-x64@0.19.12': - resolution: {integrity: sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==} + resolution: {integrity: sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==, tarball: https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz} engines: {node: '>=12'} cpu: [x64] os: [netbsd] '@esbuild/openbsd-x64@0.19.12': - resolution: {integrity: sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==} + resolution: {integrity: sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==, tarball: https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz} engines: {node: '>=12'} cpu: [x64] os: [openbsd] '@esbuild/sunos-x64@0.19.12': - resolution: {integrity: sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==} + resolution: {integrity: sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==, tarball: https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz} engines: {node: '>=12'} cpu: [x64] os: [sunos] '@esbuild/win32-arm64@0.19.12': - resolution: {integrity: sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==} + resolution: {integrity: sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==, tarball: https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz} engines: {node: '>=12'} cpu: [arm64] os: [win32] '@esbuild/win32-ia32@0.19.12': - resolution: {integrity: sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==} + resolution: {integrity: sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==, tarball: https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz} engines: {node: '>=12'} cpu: [ia32] os: [win32] '@esbuild/win32-x64@0.19.12': - resolution: {integrity: sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==} + resolution: {integrity: sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==, tarball: https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz} engines: {node: '>=12'} cpu: [x64] os: [win32] @@ -1339,16 +1339,16 @@ packages: resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==, tarball: https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz} '@lezer/common@1.2.3': - resolution: {integrity: sha512-w7ojc8ejBqr2REPsWxJjrMFsA/ysDCFICn8zEOR9mrqzOu2amhITYuLD8ag6XZf0CFXDrhKqw7+tW8cX66NaDA==} + resolution: {integrity: sha512-w7ojc8ejBqr2REPsWxJjrMFsA/ysDCFICn8zEOR9mrqzOu2amhITYuLD8ag6XZf0CFXDrhKqw7+tW8cX66NaDA==, tarball: https://registry.npmmirror.com/@lezer/common/-/common-1.2.3.tgz} '@lezer/highlight@1.2.1': - resolution: {integrity: sha512-Z5duk4RN/3zuVO7Jq0pGLJ3qynpxUVsh7IbUbGj88+uV2ApSAn6kWg2au3iJb+0Zi7kKtqffIESgNcRXWZWmSA==} + resolution: {integrity: sha512-Z5duk4RN/3zuVO7Jq0pGLJ3qynpxUVsh7IbUbGj88+uV2ApSAn6kWg2au3iJb+0Zi7kKtqffIESgNcRXWZWmSA==, tarball: https://registry.npmmirror.com/@lezer/highlight/-/highlight-1.2.1.tgz} '@lezer/lr@1.4.2': - resolution: {integrity: sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA==} + resolution: {integrity: sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA==, tarball: https://registry.npmmirror.com/@lezer/lr/-/lr-1.4.2.tgz} '@lezer/markdown@1.3.2': - resolution: {integrity: sha512-Wu7B6VnrKTbBEohqa63h5vxXjiC4pO5ZQJ/TDbhJxPQaaIoRD/6UVDhSDtVsCwVZV12vvN9KxuLL3ATMnlG0oQ==} + resolution: {integrity: sha512-Wu7B6VnrKTbBEohqa63h5vxXjiC4pO5ZQJ/TDbhJxPQaaIoRD/6UVDhSDtVsCwVZV12vvN9KxuLL3ATMnlG0oQ==, tarball: https://registry.npmmirror.com/@lezer/markdown/-/markdown-1.3.2.tgz} '@microsoft/fetch-event-source@2.0.1': resolution: {integrity: sha512-W6CLUJ2eBMw3Rec70qrsEW0jOm/3twwJv21mrmj2yORiaVmVYGS4sSS5yUwvQc1ZlDLYGPnClVWmUUMagKNsfA==, tarball: https://registry.npmmirror.com/@microsoft/fetch-event-source/-/fetch-event-source-2.0.1.tgz} @@ -1366,89 +1366,95 @@ packages: engines: {node: '>= 8'} '@parcel/watcher-android-arm64@2.5.0': - resolution: {integrity: sha512-qlX4eS28bUcQCdribHkg/herLe+0A9RyYC+mm2PXpncit8z5b3nSqGVzMNR3CmtAOgRutiZ02eIJJgP/b1iEFQ==} + resolution: {integrity: sha512-qlX4eS28bUcQCdribHkg/herLe+0A9RyYC+mm2PXpncit8z5b3nSqGVzMNR3CmtAOgRutiZ02eIJJgP/b1iEFQ==, tarball: https://registry.npmmirror.com/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.0.tgz} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [android] '@parcel/watcher-darwin-arm64@2.5.0': - resolution: {integrity: sha512-hyZ3TANnzGfLpRA2s/4U1kbw2ZI4qGxaRJbBH2DCSREFfubMswheh8TeiC1sGZ3z2jUf3s37P0BBlrD3sjVTUw==} + resolution: {integrity: sha512-hyZ3TANnzGfLpRA2s/4U1kbw2ZI4qGxaRJbBH2DCSREFfubMswheh8TeiC1sGZ3z2jUf3s37P0BBlrD3sjVTUw==, tarball: https://registry.npmmirror.com/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.0.tgz} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [darwin] '@parcel/watcher-darwin-x64@2.5.0': - resolution: {integrity: sha512-9rhlwd78saKf18fT869/poydQK8YqlU26TMiNg7AIu7eBp9adqbJZqmdFOsbZ5cnLp5XvRo9wcFmNHgHdWaGYA==} + resolution: {integrity: sha512-9rhlwd78saKf18fT869/poydQK8YqlU26TMiNg7AIu7eBp9adqbJZqmdFOsbZ5cnLp5XvRo9wcFmNHgHdWaGYA==, tarball: https://registry.npmmirror.com/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.0.tgz} engines: {node: '>= 10.0.0'} cpu: [x64] os: [darwin] '@parcel/watcher-freebsd-x64@2.5.0': - resolution: {integrity: sha512-syvfhZzyM8kErg3VF0xpV8dixJ+RzbUaaGaeb7uDuz0D3FK97/mZ5AJQ3XNnDsXX7KkFNtyQyFrXZzQIcN49Tw==} + resolution: {integrity: sha512-syvfhZzyM8kErg3VF0xpV8dixJ+RzbUaaGaeb7uDuz0D3FK97/mZ5AJQ3XNnDsXX7KkFNtyQyFrXZzQIcN49Tw==, tarball: https://registry.npmmirror.com/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.0.tgz} engines: {node: '>= 10.0.0'} cpu: [x64] os: [freebsd] '@parcel/watcher-linux-arm-glibc@2.5.0': - resolution: {integrity: sha512-0VQY1K35DQET3dVYWpOaPFecqOT9dbuCfzjxoQyif1Wc574t3kOSkKevULddcR9znz1TcklCE7Ht6NIxjvTqLA==} + resolution: {integrity: sha512-0VQY1K35DQET3dVYWpOaPFecqOT9dbuCfzjxoQyif1Wc574t3kOSkKevULddcR9znz1TcklCE7Ht6NIxjvTqLA==, tarball: https://registry.npmmirror.com/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.0.tgz} engines: {node: '>= 10.0.0'} cpu: [arm] os: [linux] + libc: [glibc] '@parcel/watcher-linux-arm-musl@2.5.0': - resolution: {integrity: sha512-6uHywSIzz8+vi2lAzFeltnYbdHsDm3iIB57d4g5oaB9vKwjb6N6dRIgZMujw4nm5r6v9/BQH0noq6DzHrqr2pA==} + resolution: {integrity: sha512-6uHywSIzz8+vi2lAzFeltnYbdHsDm3iIB57d4g5oaB9vKwjb6N6dRIgZMujw4nm5r6v9/BQH0noq6DzHrqr2pA==, tarball: https://registry.npmmirror.com/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.0.tgz} engines: {node: '>= 10.0.0'} cpu: [arm] os: [linux] + libc: [musl] '@parcel/watcher-linux-arm64-glibc@2.5.0': - resolution: {integrity: sha512-BfNjXwZKxBy4WibDb/LDCriWSKLz+jJRL3cM/DllnHH5QUyoiUNEp3GmL80ZqxeumoADfCCP19+qiYiC8gUBjA==} + resolution: {integrity: sha512-BfNjXwZKxBy4WibDb/LDCriWSKLz+jJRL3cM/DllnHH5QUyoiUNEp3GmL80ZqxeumoADfCCP19+qiYiC8gUBjA==, tarball: https://registry.npmmirror.com/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.0.tgz} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [linux] + libc: [glibc] '@parcel/watcher-linux-arm64-musl@2.5.0': - resolution: {integrity: sha512-S1qARKOphxfiBEkwLUbHjCY9BWPdWnW9j7f7Hb2jPplu8UZ3nes7zpPOW9bkLbHRvWM0WDTsjdOTUgW0xLBN1Q==} + resolution: {integrity: sha512-S1qARKOphxfiBEkwLUbHjCY9BWPdWnW9j7f7Hb2jPplu8UZ3nes7zpPOW9bkLbHRvWM0WDTsjdOTUgW0xLBN1Q==, tarball: https://registry.npmmirror.com/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.0.tgz} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [linux] + libc: [musl] '@parcel/watcher-linux-x64-glibc@2.5.0': - resolution: {integrity: sha512-d9AOkusyXARkFD66S6zlGXyzx5RvY+chTP9Jp0ypSTC9d4lzyRs9ovGf/80VCxjKddcUvnsGwCHWuF2EoPgWjw==} + resolution: {integrity: sha512-d9AOkusyXARkFD66S6zlGXyzx5RvY+chTP9Jp0ypSTC9d4lzyRs9ovGf/80VCxjKddcUvnsGwCHWuF2EoPgWjw==, tarball: https://registry.npmmirror.com/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.0.tgz} engines: {node: '>= 10.0.0'} cpu: [x64] os: [linux] + libc: [glibc] '@parcel/watcher-linux-x64-musl@2.5.0': - resolution: {integrity: sha512-iqOC+GoTDoFyk/VYSFHwjHhYrk8bljW6zOhPuhi5t9ulqiYq1togGJB5e3PwYVFFfeVgc6pbz3JdQyDoBszVaA==} + resolution: {integrity: sha512-iqOC+GoTDoFyk/VYSFHwjHhYrk8bljW6zOhPuhi5t9ulqiYq1togGJB5e3PwYVFFfeVgc6pbz3JdQyDoBszVaA==, tarball: https://registry.npmmirror.com/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.0.tgz} engines: {node: '>= 10.0.0'} cpu: [x64] os: [linux] + libc: [musl] '@parcel/watcher-win32-arm64@2.5.0': - resolution: {integrity: sha512-twtft1d+JRNkM5YbmexfcH/N4znDtjgysFaV9zvZmmJezQsKpkfLYJ+JFV3uygugK6AtIM2oADPkB2AdhBrNig==} + resolution: {integrity: sha512-twtft1d+JRNkM5YbmexfcH/N4znDtjgysFaV9zvZmmJezQsKpkfLYJ+JFV3uygugK6AtIM2oADPkB2AdhBrNig==, tarball: https://registry.npmmirror.com/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.0.tgz} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [win32] '@parcel/watcher-win32-ia32@2.5.0': - resolution: {integrity: sha512-+rgpsNRKwo8A53elqbbHXdOMtY/tAtTzManTWShB5Kk54N8Q9mzNWV7tV+IbGueCbcj826MfWGU3mprWtuf1TA==} + resolution: {integrity: sha512-+rgpsNRKwo8A53elqbbHXdOMtY/tAtTzManTWShB5Kk54N8Q9mzNWV7tV+IbGueCbcj826MfWGU3mprWtuf1TA==, tarball: https://registry.npmmirror.com/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.0.tgz} engines: {node: '>= 10.0.0'} cpu: [ia32] os: [win32] '@parcel/watcher-win32-x64@2.5.0': - resolution: {integrity: sha512-lPrxve92zEHdgeff3aiu4gDOIt4u7sJYha6wbdEZDCDUhtjTsOMiaJzG5lMY4GkWH8p0fMmO2Ppq5G5XXG+DQw==} + resolution: {integrity: sha512-lPrxve92zEHdgeff3aiu4gDOIt4u7sJYha6wbdEZDCDUhtjTsOMiaJzG5lMY4GkWH8p0fMmO2Ppq5G5XXG+DQw==, tarball: https://registry.npmmirror.com/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.0.tgz} engines: {node: '>= 10.0.0'} cpu: [x64] os: [win32] '@parcel/watcher@2.5.0': - resolution: {integrity: sha512-i0GV1yJnm2n3Yq1qw6QrUrd/LI9bE8WEBOTtOkpCXHHdyN3TAGgqAK/DAT05z4fq2x04cARXt2pDmjWjL92iTQ==} + resolution: {integrity: sha512-i0GV1yJnm2n3Yq1qw6QrUrd/LI9bE8WEBOTtOkpCXHHdyN3TAGgqAK/DAT05z4fq2x04cARXt2pDmjWjL92iTQ==, tarball: https://registry.npmmirror.com/@parcel/watcher/-/watcher-2.5.0.tgz} engines: {node: '>= 10.0.0'} '@pkgjs/parseargs@0.11.0': - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==, tarball: https://registry.npmmirror.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz} engines: {node: '>=14'} '@pkgr/core@0.1.1': @@ -1494,92 +1500,101 @@ packages: optional: true '@rollup/rollup-android-arm-eabi@4.27.4': - resolution: {integrity: sha512-2Y3JT6f5MrQkICUyRVCw4oa0sutfAsgaSsb0Lmmy1Wi2y7X5vT9Euqw4gOsCyy0YfKURBg35nhUKZS4mDcfULw==} + resolution: {integrity: sha512-2Y3JT6f5MrQkICUyRVCw4oa0sutfAsgaSsb0Lmmy1Wi2y7X5vT9Euqw4gOsCyy0YfKURBg35nhUKZS4mDcfULw==, tarball: https://registry.npmmirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.27.4.tgz} cpu: [arm] os: [android] '@rollup/rollup-android-arm64@4.27.4': - resolution: {integrity: sha512-wzKRQXISyi9UdCVRqEd0H4cMpzvHYt1f/C3CoIjES6cG++RHKhrBj2+29nPF0IB5kpy9MS71vs07fvrNGAl/iA==} + resolution: {integrity: sha512-wzKRQXISyi9UdCVRqEd0H4cMpzvHYt1f/C3CoIjES6cG++RHKhrBj2+29nPF0IB5kpy9MS71vs07fvrNGAl/iA==, tarball: https://registry.npmmirror.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.27.4.tgz} cpu: [arm64] os: [android] '@rollup/rollup-darwin-arm64@4.27.4': - resolution: {integrity: sha512-PlNiRQapift4LNS8DPUHuDX/IdXiLjf8mc5vdEmUR0fF/pyy2qWwzdLjB+iZquGr8LuN4LnUoSEvKRwjSVYz3Q==} + resolution: {integrity: sha512-PlNiRQapift4LNS8DPUHuDX/IdXiLjf8mc5vdEmUR0fF/pyy2qWwzdLjB+iZquGr8LuN4LnUoSEvKRwjSVYz3Q==, tarball: https://registry.npmmirror.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.27.4.tgz} cpu: [arm64] os: [darwin] '@rollup/rollup-darwin-x64@4.27.4': - resolution: {integrity: sha512-o9bH2dbdgBDJaXWJCDTNDYa171ACUdzpxSZt+u/AAeQ20Nk5x+IhA+zsGmrQtpkLiumRJEYef68gcpn2ooXhSQ==} + resolution: {integrity: sha512-o9bH2dbdgBDJaXWJCDTNDYa171ACUdzpxSZt+u/AAeQ20Nk5x+IhA+zsGmrQtpkLiumRJEYef68gcpn2ooXhSQ==, tarball: https://registry.npmmirror.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.27.4.tgz} cpu: [x64] os: [darwin] '@rollup/rollup-freebsd-arm64@4.27.4': - resolution: {integrity: sha512-NBI2/i2hT9Q+HySSHTBh52da7isru4aAAo6qC3I7QFVsuhxi2gM8t/EI9EVcILiHLj1vfi+VGGPaLOUENn7pmw==} + resolution: {integrity: sha512-NBI2/i2hT9Q+HySSHTBh52da7isru4aAAo6qC3I7QFVsuhxi2gM8t/EI9EVcILiHLj1vfi+VGGPaLOUENn7pmw==, tarball: https://registry.npmmirror.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.27.4.tgz} cpu: [arm64] os: [freebsd] '@rollup/rollup-freebsd-x64@4.27.4': - resolution: {integrity: sha512-wYcC5ycW2zvqtDYrE7deary2P2UFmSh85PUpAx+dwTCO9uw3sgzD6Gv9n5X4vLaQKsrfTSZZ7Z7uynQozPVvWA==} + resolution: {integrity: sha512-wYcC5ycW2zvqtDYrE7deary2P2UFmSh85PUpAx+dwTCO9uw3sgzD6Gv9n5X4vLaQKsrfTSZZ7Z7uynQozPVvWA==, tarball: https://registry.npmmirror.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.27.4.tgz} cpu: [x64] os: [freebsd] '@rollup/rollup-linux-arm-gnueabihf@4.27.4': - resolution: {integrity: sha512-9OwUnK/xKw6DyRlgx8UizeqRFOfi9mf5TYCw1uolDaJSbUmBxP85DE6T4ouCMoN6pXw8ZoTeZCSEfSaYo+/s1w==} + resolution: {integrity: sha512-9OwUnK/xKw6DyRlgx8UizeqRFOfi9mf5TYCw1uolDaJSbUmBxP85DE6T4ouCMoN6pXw8ZoTeZCSEfSaYo+/s1w==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.27.4.tgz} cpu: [arm] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm-musleabihf@4.27.4': - resolution: {integrity: sha512-Vgdo4fpuphS9V24WOV+KwkCVJ72u7idTgQaBoLRD0UxBAWTF9GWurJO9YD9yh00BzbkhpeXtm6na+MvJU7Z73A==} + resolution: {integrity: sha512-Vgdo4fpuphS9V24WOV+KwkCVJ72u7idTgQaBoLRD0UxBAWTF9GWurJO9YD9yh00BzbkhpeXtm6na+MvJU7Z73A==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.27.4.tgz} cpu: [arm] os: [linux] + libc: [musl] '@rollup/rollup-linux-arm64-gnu@4.27.4': - resolution: {integrity: sha512-pleyNgyd1kkBkw2kOqlBx+0atfIIkkExOTiifoODo6qKDSpnc6WzUY5RhHdmTdIJXBdSnh6JknnYTtmQyobrVg==} + resolution: {integrity: sha512-pleyNgyd1kkBkw2kOqlBx+0atfIIkkExOTiifoODo6qKDSpnc6WzUY5RhHdmTdIJXBdSnh6JknnYTtmQyobrVg==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.27.4.tgz} cpu: [arm64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm64-musl@4.27.4': - resolution: {integrity: sha512-caluiUXvUuVyCHr5DxL8ohaaFFzPGmgmMvwmqAITMpV/Q+tPoaHZ/PWa3t8B2WyoRcIIuu1hkaW5KkeTDNSnMA==} + resolution: {integrity: sha512-caluiUXvUuVyCHr5DxL8ohaaFFzPGmgmMvwmqAITMpV/Q+tPoaHZ/PWa3t8B2WyoRcIIuu1hkaW5KkeTDNSnMA==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.27.4.tgz} cpu: [arm64] os: [linux] + libc: [musl] '@rollup/rollup-linux-powerpc64le-gnu@4.27.4': - resolution: {integrity: sha512-FScrpHrO60hARyHh7s1zHE97u0KlT/RECzCKAdmI+LEoC1eDh/RDji9JgFqyO+wPDb86Oa/sXkily1+oi4FzJQ==} + resolution: {integrity: sha512-FScrpHrO60hARyHh7s1zHE97u0KlT/RECzCKAdmI+LEoC1eDh/RDji9JgFqyO+wPDb86Oa/sXkily1+oi4FzJQ==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.27.4.tgz} cpu: [ppc64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-riscv64-gnu@4.27.4': - resolution: {integrity: sha512-qyyprhyGb7+RBfMPeww9FlHwKkCXdKHeGgSqmIXw9VSUtvyFZ6WZRtnxgbuz76FK7LyoN8t/eINRbPUcvXB5fw==} + resolution: {integrity: sha512-qyyprhyGb7+RBfMPeww9FlHwKkCXdKHeGgSqmIXw9VSUtvyFZ6WZRtnxgbuz76FK7LyoN8t/eINRbPUcvXB5fw==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.27.4.tgz} cpu: [riscv64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-s390x-gnu@4.27.4': - resolution: {integrity: sha512-PFz+y2kb6tbh7m3A7nA9++eInGcDVZUACulf/KzDtovvdTizHpZaJty7Gp0lFwSQcrnebHOqxF1MaKZd7psVRg==} + resolution: {integrity: sha512-PFz+y2kb6tbh7m3A7nA9++eInGcDVZUACulf/KzDtovvdTizHpZaJty7Gp0lFwSQcrnebHOqxF1MaKZd7psVRg==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.27.4.tgz} cpu: [s390x] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.27.4': - resolution: {integrity: sha512-Ni8mMtfo+o/G7DVtweXXV/Ol2TFf63KYjTtoZ5f078AUgJTmaIJnj4JFU7TK/9SVWTaSJGxPi5zMDgK4w+Ez7Q==} + resolution: {integrity: sha512-Ni8mMtfo+o/G7DVtweXXV/Ol2TFf63KYjTtoZ5f078AUgJTmaIJnj4JFU7TK/9SVWTaSJGxPi5zMDgK4w+Ez7Q==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.27.4.tgz} cpu: [x64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-musl@4.27.4': - resolution: {integrity: sha512-5AeeAF1PB9TUzD+3cROzFTnAJAcVUGLuR8ng0E0WXGkYhp6RD6L+6szYVX+64Rs0r72019KHZS1ka1q+zU/wUw==} + resolution: {integrity: sha512-5AeeAF1PB9TUzD+3cROzFTnAJAcVUGLuR8ng0E0WXGkYhp6RD6L+6szYVX+64Rs0r72019KHZS1ka1q+zU/wUw==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.27.4.tgz} cpu: [x64] os: [linux] + libc: [musl] '@rollup/rollup-win32-arm64-msvc@4.27.4': - resolution: {integrity: sha512-yOpVsA4K5qVwu2CaS3hHxluWIK5HQTjNV4tWjQXluMiiiu4pJj4BN98CvxohNCpcjMeTXk/ZMJBRbgRg8HBB6A==} + resolution: {integrity: sha512-yOpVsA4K5qVwu2CaS3hHxluWIK5HQTjNV4tWjQXluMiiiu4pJj4BN98CvxohNCpcjMeTXk/ZMJBRbgRg8HBB6A==, tarball: https://registry.npmmirror.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.27.4.tgz} cpu: [arm64] os: [win32] '@rollup/rollup-win32-ia32-msvc@4.27.4': - resolution: {integrity: sha512-KtwEJOaHAVJlxV92rNYiG9JQwQAdhBlrjNRp7P9L8Cb4Rer3in+0A+IPhJC9y68WAi9H0sX4AiG2NTsVlmqJeQ==} + resolution: {integrity: sha512-KtwEJOaHAVJlxV92rNYiG9JQwQAdhBlrjNRp7P9L8Cb4Rer3in+0A+IPhJC9y68WAi9H0sX4AiG2NTsVlmqJeQ==, tarball: https://registry.npmmirror.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.27.4.tgz} cpu: [ia32] os: [win32] '@rollup/rollup-win32-x64-msvc@4.27.4': - resolution: {integrity: sha512-3j4jx1TppORdTAoBJRd+/wJRGCPC0ETWkXOecJ6PPZLj6SptXkrXcNqdj0oclbKML6FkQltdz7bBA3rUSirZug==} + resolution: {integrity: sha512-3j4jx1TppORdTAoBJRd+/wJRGCPC0ETWkXOecJ6PPZLj6SptXkrXcNqdj0oclbKML6FkQltdz7bBA3rUSirZug==, tarball: https://registry.npmmirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.27.4.tgz} cpu: [x64] os: [win32] @@ -1590,61 +1605,65 @@ packages: resolution: {integrity: sha512-XExJS3cLqgrmNBIP3bBw6+1oQ1ksGjFh0+oClDKFYpCCqx/hlqwWO5KO/S63fzUo67SxI9dMrF0y5T/Ey7h8Zw==} '@swc/core-darwin-arm64@1.9.3': - resolution: {integrity: sha512-hGfl/KTic/QY4tB9DkTbNuxy5cV4IeejpPD4zo+Lzt4iLlDWIeANL4Fkg67FiVceNJboqg48CUX+APhDHO5G1w==} + resolution: {integrity: sha512-hGfl/KTic/QY4tB9DkTbNuxy5cV4IeejpPD4zo+Lzt4iLlDWIeANL4Fkg67FiVceNJboqg48CUX+APhDHO5G1w==, tarball: https://registry.npmmirror.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.9.3.tgz} engines: {node: '>=10'} cpu: [arm64] os: [darwin] '@swc/core-darwin-x64@1.9.3': - resolution: {integrity: sha512-IaRq05ZLdtgF5h9CzlcgaNHyg4VXuiStnOFpfNEMuI5fm5afP2S0FHq8WdakUz5WppsbddTdplL+vpeApt/WCQ==} + resolution: {integrity: sha512-IaRq05ZLdtgF5h9CzlcgaNHyg4VXuiStnOFpfNEMuI5fm5afP2S0FHq8WdakUz5WppsbddTdplL+vpeApt/WCQ==, tarball: https://registry.npmmirror.com/@swc/core-darwin-x64/-/core-darwin-x64-1.9.3.tgz} engines: {node: '>=10'} cpu: [x64] os: [darwin] '@swc/core-linux-arm-gnueabihf@1.9.3': - resolution: {integrity: sha512-Pbwe7xYprj/nEnZrNBvZfjnTxlBIcfApAGdz2EROhjpPj+FBqBa3wOogqbsuGGBdCphf8S+KPprL1z+oDWkmSQ==} + resolution: {integrity: sha512-Pbwe7xYprj/nEnZrNBvZfjnTxlBIcfApAGdz2EROhjpPj+FBqBa3wOogqbsuGGBdCphf8S+KPprL1z+oDWkmSQ==, tarball: https://registry.npmmirror.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.9.3.tgz} engines: {node: '>=10'} cpu: [arm] os: [linux] '@swc/core-linux-arm64-gnu@1.9.3': - resolution: {integrity: sha512-AQ5JZiwNGVV/2K2TVulg0mw/3LYfqpjZO6jDPtR2evNbk9Yt57YsVzS+3vHSlUBQDRV9/jqMuZYVU3P13xrk+g==} + resolution: {integrity: sha512-AQ5JZiwNGVV/2K2TVulg0mw/3LYfqpjZO6jDPtR2evNbk9Yt57YsVzS+3vHSlUBQDRV9/jqMuZYVU3P13xrk+g==, tarball: https://registry.npmmirror.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.9.3.tgz} engines: {node: '>=10'} cpu: [arm64] os: [linux] + libc: [glibc] '@swc/core-linux-arm64-musl@1.9.3': - resolution: {integrity: sha512-tzVH480RY6RbMl/QRgh5HK3zn1ZTFsThuxDGo6Iuk1MdwIbdFYUY034heWUTI4u3Db97ArKh0hNL0xhO3+PZdg==} + resolution: {integrity: sha512-tzVH480RY6RbMl/QRgh5HK3zn1ZTFsThuxDGo6Iuk1MdwIbdFYUY034heWUTI4u3Db97ArKh0hNL0xhO3+PZdg==, tarball: https://registry.npmmirror.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.9.3.tgz} engines: {node: '>=10'} cpu: [arm64] os: [linux] + libc: [musl] '@swc/core-linux-x64-gnu@1.9.3': - resolution: {integrity: sha512-ivXXBRDXDc9k4cdv10R21ccBmGebVOwKXT/UdH1PhxUn9m/h8erAWjz5pcELwjiMf27WokqPgaWVfaclDbgE+w==} + resolution: {integrity: sha512-ivXXBRDXDc9k4cdv10R21ccBmGebVOwKXT/UdH1PhxUn9m/h8erAWjz5pcELwjiMf27WokqPgaWVfaclDbgE+w==, tarball: https://registry.npmmirror.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.9.3.tgz} engines: {node: '>=10'} cpu: [x64] os: [linux] + libc: [glibc] '@swc/core-linux-x64-musl@1.9.3': - resolution: {integrity: sha512-ILsGMgfnOz1HwdDz+ZgEuomIwkP1PHT6maigZxaCIuC6OPEhKE8uYna22uU63XvYcLQvZYDzpR3ms47WQPuNEg==} + resolution: {integrity: sha512-ILsGMgfnOz1HwdDz+ZgEuomIwkP1PHT6maigZxaCIuC6OPEhKE8uYna22uU63XvYcLQvZYDzpR3ms47WQPuNEg==, tarball: https://registry.npmmirror.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.9.3.tgz} engines: {node: '>=10'} cpu: [x64] os: [linux] + libc: [musl] '@swc/core-win32-arm64-msvc@1.9.3': - resolution: {integrity: sha512-e+XmltDVIHieUnNJHtspn6B+PCcFOMYXNJB1GqoCcyinkEIQNwC8KtWgMqUucUbEWJkPc35NHy9k8aCXRmw9Kg==} + resolution: {integrity: sha512-e+XmltDVIHieUnNJHtspn6B+PCcFOMYXNJB1GqoCcyinkEIQNwC8KtWgMqUucUbEWJkPc35NHy9k8aCXRmw9Kg==, tarball: https://registry.npmmirror.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.9.3.tgz} engines: {node: '>=10'} cpu: [arm64] os: [win32] '@swc/core-win32-ia32-msvc@1.9.3': - resolution: {integrity: sha512-rqpzNfpAooSL4UfQnHhkW8aL+oyjqJniDP0qwZfGnjDoJSbtPysHg2LpcOBEdSnEH+uIZq6J96qf0ZFD8AGfXA==} + resolution: {integrity: sha512-rqpzNfpAooSL4UfQnHhkW8aL+oyjqJniDP0qwZfGnjDoJSbtPysHg2LpcOBEdSnEH+uIZq6J96qf0ZFD8AGfXA==, tarball: https://registry.npmmirror.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.9.3.tgz} engines: {node: '>=10'} cpu: [ia32] os: [win32] '@swc/core-win32-x64-msvc@1.9.3': - resolution: {integrity: sha512-3YJJLQ5suIEHEKc1GHtqVq475guiyqisKSoUnoaRtxkDaW5g1yvPt9IoSLOe2mRs7+FFhGGU693RsBUSwOXSdQ==} + resolution: {integrity: sha512-3YJJLQ5suIEHEKc1GHtqVq475guiyqisKSoUnoaRtxkDaW5g1yvPt9IoSLOe2mRs7+FFhGGU693RsBUSwOXSdQ==, tarball: https://registry.npmmirror.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.9.3.tgz} engines: {node: '>=10'} cpu: [x64] os: [win32] @@ -1665,7 +1684,7 @@ packages: resolution: {integrity: sha512-V5gRru+aD8YVyCOMAjMpWR1Ui577DD5KSJsHP8RAxopAH22jFz6GZd/qxqjO6MJHQhcsjvjOFXyDhyLQUnMveQ==, tarball: https://registry.npmmirror.com/@swc/types/-/types-0.1.17.tgz} '@sxzz/popperjs-es@2.11.7': - resolution: {integrity: sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==} + resolution: {integrity: sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==, tarball: https://registry.npmmirror.com/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz} '@transloadit/prettier-bytes@0.0.7': resolution: {integrity: sha512-VeJbUb0wEKbcwaSlj5n+LscBl9IPgLPkHVGBkh00cztv6X4L/TJXK58LzFuBKX7/GAfiGhIwH67YTLTlzvIzBA==, tarball: https://registry.npmmirror.com/@transloadit/prettier-bytes/-/prettier-bytes-0.0.7.tgz} @@ -1810,10 +1829,10 @@ packages: resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==, tarball: https://registry.npmmirror.com/@types/semver/-/semver-7.5.8.tgz} '@types/trusted-types@2.0.7': - resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==, tarball: https://registry.npmmirror.com/@types/trusted-types/-/trusted-types-2.0.7.tgz} '@types/video.js@7.3.58': - resolution: {integrity: sha512-1CQjuSrgbv1/dhmcfQ83eVyYbvGyqhTvb2Opxr0QCV+iJ4J6/J+XWQ3Om59WiwCd1MN3rDUHasx5XRrpUtewYQ==} + resolution: {integrity: sha512-1CQjuSrgbv1/dhmcfQ83eVyYbvGyqhTvb2Opxr0QCV+iJ4J6/J+XWQ3Om59WiwCd1MN3rDUHasx5XRrpUtewYQ==, tarball: https://registry.npmmirror.com/@types/video.js/-/video.js-7.3.58.tgz} '@types/web-bluetooth@0.0.16': resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==, tarball: https://registry.npmmirror.com/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz} @@ -2418,8 +2437,8 @@ packages: axios@0.26.1: resolution: {integrity: sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==, tarball: https://registry.npmmirror.com/axios/-/axios-0.26.1.tgz} - axios@1.7.8: - resolution: {integrity: sha512-Uu0wb7KNqK2t5K+YQyVCLM76prD5sRFjKHbJYCP1J7JFGEQ6nN7HWn9+04LAeiJ3ji54lgS/gZCH1oxyrf1SPw==, tarball: https://registry.npmmirror.com/axios/-/axios-1.7.8.tgz} + axios@1.9.0: + resolution: {integrity: sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==, tarball: https://registry.npmmirror.com/axios/-/axios-1.9.0.tgz} babel-plugin-polyfill-corejs2@0.4.12: resolution: {integrity: sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og==, tarball: https://registry.npmmirror.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.12.tgz} @@ -2515,7 +2534,7 @@ packages: engines: {node: '>=6'} camunda-bpmn-js-behaviors@1.7.2: - resolution: {integrity: sha512-xjLJHc18T40tcYu4JCeYDo1wR5i9+ZqcVnXVP6c4ooAe2gKISbBvFc07gqGpqiwm7TpEBvUfDj3PrRr+ofaf4w==} + resolution: {integrity: sha512-xjLJHc18T40tcYu4JCeYDo1wR5i9+ZqcVnXVP6c4ooAe2gKISbBvFc07gqGpqiwm7TpEBvUfDj3PrRr+ofaf4w==, tarball: https://registry.npmmirror.com/camunda-bpmn-js-behaviors/-/camunda-bpmn-js-behaviors-1.7.2.tgz} peerDependencies: bpmn-js: '>= 9' camunda-bpmn-moddle: '>= 7' @@ -2555,7 +2574,7 @@ packages: engines: {node: '>= 14.16.0'} classnames@2.5.1: - resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==} + resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==, tarball: https://registry.npmmirror.com/classnames/-/classnames-2.5.1.tgz} cli-cursor@5.0.0: resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==, tarball: https://registry.npmmirror.com/cli-cursor/-/cli-cursor-5.0.0.tgz} @@ -2681,7 +2700,7 @@ packages: optional: true crelt@1.0.6: - resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==} + resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==, tarball: https://registry.npmmirror.com/crelt/-/crelt-1.0.6.tgz} cropperjs@1.6.2: resolution: {integrity: sha512-nhymn9GdnV3CqiEHJVai54TULFAE3VshJTXSqSJKa8yXAKyBKDWdhHarnlIPrshJ0WMFTGuFvG02YjLXfPiuOA==, tarball: https://registry.npmmirror.com/cropperjs/-/cropperjs-1.6.2.tgz} @@ -2971,7 +2990,7 @@ packages: resolution: {integrity: sha512-m4yreHcUWHBncGVV7U+yQzc12vIlq0jMrtHZ5mW6dQMiL/7skSYNVX9wqKwOtyO9SGCgevrAFEgOCAHmamHTUA==, tarball: https://registry.npmmirror.com/domify/-/domify-1.4.2.tgz} domify@2.0.0: - resolution: {integrity: sha512-rmvrrmWQPD/X1A/nPBfIVg4r05792QdG9Z4Prk6oQG0F9zBMDkr0GKAdds1wjb2dq1rTz/ywc4ZxpZbgz0tttg==} + resolution: {integrity: sha512-rmvrrmWQPD/X1A/nPBfIVg4r05792QdG9Z4Prk6oQG0F9zBMDkr0GKAdds1wjb2dq1rTz/ywc4ZxpZbgz0tttg==, tarball: https://registry.npmmirror.com/domify/-/domify-2.0.0.tgz} engines: {node: '>=18'} dompurify@3.2.1: @@ -3009,8 +3028,8 @@ packages: electron-to-chromium@1.5.67: resolution: {integrity: sha512-nz88NNBsD7kQSAGGJyp8hS6xSPtWwqNogA0mjtc2nUYeEf3nURK9qpV18TuBdDmEDgVWotS8Wkzf+V52dSQ/LQ==, tarball: https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.5.67.tgz} - element-plus@2.9.1: - resolution: {integrity: sha512-9Agqf/jt4Ugk7EZ6C5LME71sgkvauPCsnvJN12Xid2XVobjufxMGpRE4L7pS4luJMOmFAH3J0NgYEGZT5r+NDg==, tarball: https://registry.npmmirror.com/element-plus/-/element-plus-2.9.1.tgz} + element-plus@2.11.1: + resolution: {integrity: sha512-weYFIniyNXTAe9vJZnmZpYzurh4TDbdKhBsJwhbzuo0SDZ8PLwHVll0qycJUxc6SLtH+7A9F7dvdDh5CnqeIVA==, tarball: https://registry.npmmirror.com/element-plus/-/element-plus-2.11.1.tgz} peerDependencies: vue: ^3.2.0 @@ -3228,10 +3247,10 @@ packages: optional: true feelers@1.4.0: - resolution: {integrity: sha512-CGa/7ILuqoqTaeYeoKsg/4tzu2es9sEEJTmSjdu0lousZBw4V9gcYhHYFNmbrSrKmbAVfOzj6/DsymGJWFIOeg==} + resolution: {integrity: sha512-CGa/7ILuqoqTaeYeoKsg/4tzu2es9sEEJTmSjdu0lousZBw4V9gcYhHYFNmbrSrKmbAVfOzj6/DsymGJWFIOeg==, tarball: https://registry.npmmirror.com/feelers/-/feelers-1.4.0.tgz} feelin@3.2.0: - resolution: {integrity: sha512-GFDbHsTYk7YXO1tyw1dOjb7IODeAZvNIosdGZThUwPx5XcD/XhO0hnPZXsIbAzSsIdrgGlTEEdby9fZ2gixysA==} + resolution: {integrity: sha512-GFDbHsTYk7YXO1tyw1dOjb7IODeAZvNIosdGZThUwPx5XcD/XhO0hnPZXsIbAzSsIdrgGlTEEdby9fZ2gixysA==, tarball: https://registry.npmmirror.com/feelin/-/feelin-3.2.0.tgz} file-entry-cache@6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==, tarball: https://registry.npmmirror.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz} @@ -3272,7 +3291,7 @@ packages: resolution: {integrity: sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==, tarball: https://registry.npmmirror.com/flatted/-/flatted-3.3.2.tgz} focus-trap@7.6.2: - resolution: {integrity: sha512-9FhUxK1hVju2+AiQIDJ5Dd//9R2n2RAfJ0qfhF4IHGHgcoEUTMpbTeG/zbEuwaiYXfuAH6XE0/aCyxDdRM+W5w==} + resolution: {integrity: sha512-9FhUxK1hVju2+AiQIDJ5Dd//9R2n2RAfJ0qfhF4IHGHgcoEUTMpbTeG/zbEuwaiYXfuAH6XE0/aCyxDdRM+W5w==, tarball: https://registry.npmmirror.com/focus-trap/-/focus-trap-7.6.2.tgz} follow-redirects@1.15.9: resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==, tarball: https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.9.tgz} @@ -3306,7 +3325,7 @@ packages: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==, tarball: https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz} fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==, tarball: https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] @@ -3682,14 +3701,14 @@ packages: resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==, tarball: https://registry.npmmirror.com/kolorist/-/kolorist-1.8.0.tgz} lang-feel@2.2.0: - resolution: {integrity: sha512-Ebo5nftYsMfJzB3Ny8Oy4oaDXZXb5x61qtVVmKv6aImvAZUbT76mD60ZbEilizjZQzsR2CcU1iMK5sacIa1NVA==} + resolution: {integrity: sha512-Ebo5nftYsMfJzB3Ny8Oy4oaDXZXb5x61qtVVmKv6aImvAZUbT76mD60ZbEilizjZQzsR2CcU1iMK5sacIa1NVA==, tarball: https://registry.npmmirror.com/lang-feel/-/lang-feel-2.2.0.tgz} levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==, tarball: https://registry.npmmirror.com/levn/-/levn-0.4.1.tgz} engines: {node: '>= 0.8.0'} lezer-feel@1.4.0: - resolution: {integrity: sha512-kNxG7O38gwpuYy+C3JCRxQNTCE2qu9uTuH5dE3EGVnRhIQMe6rPDz0S8t3urLEOsMud6HI795m6zX2ujfUaqTw==} + resolution: {integrity: sha512-kNxG7O38gwpuYy+C3JCRxQNTCE2qu9uTuH5dE3EGVnRhIQMe6rPDz0S8t3urLEOsMud6HI795m6zX2ujfUaqTw==, tarball: https://registry.npmmirror.com/lezer-feel/-/lezer-feel-1.4.0.tgz} lilconfig@3.1.2: resolution: {integrity: sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==, tarball: https://registry.npmmirror.com/lilconfig/-/lilconfig-3.1.2.tgz} @@ -3809,7 +3828,7 @@ packages: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==, tarball: https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz} luxon@3.5.0: - resolution: {integrity: sha512-rh+Zjr6DNfUYR3bPwJEnuwDdqMbxZW7LOQfUN4B54+Cl+0o5zaU9RJ6bcidfDtC1cWCZXQ+nvX8bf6bAji37QQ==} + resolution: {integrity: sha512-rh+Zjr6DNfUYR3bPwJEnuwDdqMbxZW7LOQfUN4B54+Cl+0o5zaU9RJ6bcidfDtC1cWCZXQ+nvX8bf6bAji37QQ==, tarball: https://registry.npmmirror.com/luxon/-/luxon-3.5.0.tgz} engines: {node: '>=12'} m3u8-parser@4.8.0: @@ -3914,7 +3933,7 @@ packages: resolution: {integrity: sha512-TMoL8SEEIhUWYgkj7XMSgxmwSyGI+4fP2KFFGnN3FbHfbGHVdsLYSz8LoIsgPhz4dWRmLvxWWSMgzZMJW5sZuA==, tarball: https://registry.npmmirror.com/min-dom/-/min-dom-4.2.1.tgz} min-dom@5.1.1: - resolution: {integrity: sha512-GaKUlguMAofd3OJsB0OkP17i5kucKqErgVCJxPawO9l5NwIPnr28SAr99zzlzMCWWljISBYrnZVWdE2Q92YGFQ==} + resolution: {integrity: sha512-GaKUlguMAofd3OJsB0OkP17i5kucKqErgVCJxPawO9l5NwIPnr28SAr99zzlzMCWWljISBYrnZVWdE2Q92YGFQ==, tarball: https://registry.npmmirror.com/min-dom/-/min-dom-5.1.1.tgz} minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==, tarball: https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz} @@ -4607,7 +4626,7 @@ packages: resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==, tarball: https://registry.npmmirror.com/strnum/-/strnum-1.0.5.tgz} style-mod@4.1.2: - resolution: {integrity: sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==} + resolution: {integrity: sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==, tarball: https://registry.npmmirror.com/style-mod/-/style-mod-4.1.2.tgz} stylelint-config-html@1.1.0: resolution: {integrity: sha512-IZv4IVESjKLumUGi+HWeb7skgO6/g4VMuAYrJdlqQFndgbj6WJAXPhaysvBiXefX79upBdQVumgYcdd17gCpjQ==, tarball: https://registry.npmmirror.com/stylelint-config-html/-/stylelint-config-html-1.1.0.tgz} @@ -4674,7 +4693,7 @@ packages: resolution: {integrity: sha512-Nk8c4lXvMB98MtbmjX7JwJRgJOL8fluecYCfCeYBznwmpOs8Bf15hLM6z4z71EDAhQVrQrI+wt1aLWSXZq+hXA==, tarball: https://registry.npmmirror.com/systemjs/-/systemjs-6.15.1.tgz} tabbable@6.2.0: - resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} + resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==, tarball: https://registry.npmmirror.com/tabbable/-/tabbable-6.2.0.tgz} table@6.8.2: resolution: {integrity: sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==, tarball: https://registry.npmmirror.com/table/-/table-6.8.2.tgz} @@ -5015,7 +5034,7 @@ packages: vue: ^3.0.1 w3c-keyname@2.2.8: - resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} + resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==, tarball: https://registry.npmmirror.com/w3c-keyname/-/w3c-keyname-2.2.8.tgz} wangeditor@4.7.15: resolution: {integrity: sha512-aPTdREd8BxXVyJ5MI+LU83FQ7u1EPd341iXIorRNYSOvoimNoZ4nPg+yn3FGbB93/owEa6buLw8wdhYnMCJQLg==, tarball: https://registry.npmmirror.com/wangeditor/-/wangeditor-4.7.15.tgz} @@ -5131,7 +5150,7 @@ packages: engines: {node: '>=12.20'} zeebe-bpmn-moddle@1.7.0: - resolution: {integrity: sha512-eZ6OXSt0c4n9V/oN/46gTlwDIS3GhWQLt9jbM5uS/YryB4yN8wdrrKrtw+TpyNy0SSKWXNDHyC83nCA2blPO3Q==} + resolution: {integrity: sha512-eZ6OXSt0c4n9V/oN/46gTlwDIS3GhWQLt9jbM5uS/YryB4yN8wdrrKrtw+TpyNy0SSKWXNDHyC83nCA2blPO3Q==, tarball: https://registry.npmmirror.com/zeebe-bpmn-moddle/-/zeebe-bpmn-moddle-1.7.0.tgz} zrender@5.6.0: resolution: {integrity: sha512-uzgraf4njmmHAbEUxMJ8Oxg+P3fT04O+9p7gY+wJRVxo8Ge+KmYv0WJev945EH4wFuc4OY2NLXz46FZrWS9xJg==, tarball: https://registry.npmmirror.com/zrender/-/zrender-5.6.0.tgz} @@ -6057,7 +6076,7 @@ snapshots: '@dual-bundle/import-meta-resolve@4.1.0': {} - '@element-plus/icons-vue@2.3.1(vue@3.5.12(typescript@5.3.3))': + '@element-plus/icons-vue@2.3.2(vue@3.5.12(typescript@5.3.3))': dependencies: vue: 3.5.12(typescript@5.3.3) @@ -6209,7 +6228,7 @@ snapshots: '@form-create/element-ui': 3.2.14(vue@3.5.12(typescript@5.3.3)) '@form-create/utils': 3.2.14 codemirror: 6.65.7 - element-plus: 2.9.1(vue@3.5.12(typescript@5.3.3)) + element-plus: 2.11.1(vue@3.5.12(typescript@5.3.3)) vue: 3.5.12(typescript@5.3.3) vuedraggable: 4.1.0(vue@3.5.12(typescript@5.3.3)) transitivePeerDependencies: @@ -7648,7 +7667,7 @@ snapshots: transitivePeerDependencies: - debug - axios@1.7.8: + axios@1.9.0: dependencies: follow-redirects: 1.15.9(debug@4.3.7) form-data: 4.0.1 @@ -8297,10 +8316,10 @@ snapshots: electron-to-chromium@1.5.67: {} - element-plus@2.9.1(vue@3.5.12(typescript@5.3.3)): + element-plus@2.11.1(vue@3.5.12(typescript@5.3.3)): dependencies: '@ctrl/tinycolor': 3.6.1 - '@element-plus/icons-vue': 2.3.1(vue@3.5.12(typescript@5.3.3)) + '@element-plus/icons-vue': 2.3.2(vue@3.5.12(typescript@5.3.3)) '@floating-ui/dom': 1.6.12 '@popperjs/core': '@sxzz/popperjs-es@2.11.7' '@types/lodash': 4.17.13 From 7c710d2afe413cddbfb41513a8fde4dced6bc307 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 31 Aug 2025 09:39:09 +0800 Subject: [PATCH 044/161] =?UTF-8?q?fix=EF=BC=9A=E5=AF=8C=E6=96=87=E6=9C=AC?= =?UTF-8?q?=E5=9C=A8=20val=20=E4=B8=BA=20null=20=E4=BC=9A=E6=8A=A5?= =?UTF-8?q?=E9=94=99=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Editor/src/Editor.vue | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/Editor/src/Editor.vue b/src/components/Editor/src/Editor.vue index 3b0513b8d..7e81c58eb 100644 --- a/src/components/Editor/src/Editor.vue +++ b/src/components/Editor/src/Editor.vue @@ -40,6 +40,9 @@ const valueHtml = ref('') watch( () => props.modelValue, (val: string) => { + if (!val) { + val = '' + } if (val === unref(valueHtml)) return valueHtml.value = val }, From 7ddbf8712c38926c573c0954bc36b98fbd04ead1 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 31 Aug 2025 11:30:56 +0800 Subject: [PATCH 045/161] =?UTF-8?q?(=E3=80=83'=E2=96=BD'=E3=80=83)=20v2025?= =?UTF-8?q?.09=20=E5=8F=91=E5=B8=83=EF=BC=9A=E6=96=B0=E5=A2=9E=20AI=20?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E8=81=94=E7=BD=91=E6=90=9C=E7=B4=A2=E3=80=81?= =?UTF-8?q?=E6=8E=A8=E7=90=86=E3=80=81=E6=96=87=E4=BB=B6/=E5=9B=BE?= =?UTF-8?q?=E7=89=87=E3=80=81MCP=20=E7=AD=89=E5=8A=9F=E8=83=BD=EF=BC=8C?= =?UTF-8?q?=E5=AE=8C=E5=96=84=20IoT=20=E5=9C=BA=E6=99=AF=E8=81=94=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .image/common/ai-feature.png | Bin 33087 -> 41435 bytes package.json | 2 +- pnpm-lock.yaml | 63 ++++++++++++++++++----------------- 3 files changed, 34 insertions(+), 31 deletions(-) diff --git a/.image/common/ai-feature.png b/.image/common/ai-feature.png index 7f8c92f8cdca66cfd6bba53af2bfdf483698685f..1c22dbe4ee576cd2a58b134d4ad158afd2de5ff8 100644 GIT binary patch literal 41435 zcmY(qbzGBS_XiBpAV`O!OA%0%7~LTtAl-;kqHx1TgQRqKhk$@|3ESvyP)cGWM@V;z zyz_aU-}`>v{k8krb^1Ezd$#K=;n z78dsK>sNY8cXxN!+rRJ5c3yWy-CZBv9qiryx!E*RSM3OEXJWWJK7u*{WrbfH?B5@* zEP1=Tg$4zn>JGM$bBp6+R+g4Vh6dYic2|cR9k6;tZI!v1>C`|k`qyMZR>s`e;Q7XS zUkf5BCi>N@SFzz?Bc1KKIy!gfrvX0RQ(w2gmzVDP02xUMf6j01tgZgeD<5nw+^j78 zUY?1bsk^&7zu5aTS1?!etq2WU*lb@K-b3Z2C7ttv9I>B+3bl_(Z9Q$os7Sd00Iuk@*5Q7R3^8M?5@GKJ)|Mfxh27Zs{QtCeD zp}Ucqa7sVUyfgzuzTSYCZpET(d82l#fIR@&Kmu#{Yn~PAz8m;!Tic(laSBk)(Wn4L zl`7+ud#bT*?$26D2~T(bi90gmoK3lBZ(@gY?3%*ML#|qdjX9nF|JR*`e^Zg9aOGFs z^jp4xpF7@zwN)-{x(hR0qwYD!k6(_f4!WB>`c&j?%I-*&i^q1I_`Y%wm1;B*Ba=9T zw0#A$2vP<24KzM?Y1Pj6n3yyWkcZj|sriz1k+0B-x~e|_D}a>=!7CyxE9aeyt$#!`d$1V~j0B}dCXaF2m)t8X zjk(L#%!>-Crh7lMT*A$<4h6zN6{ueX27o1YIH_v?&kN!Ygawm!|icY<|Ztny_SFmRm`WRX79JU ze9BFAD*7kk-@V$l$HG50gHJmRK^ho)ZDt+JhrBdG0e3H%^HOsuZYZVg^l!ExLKV#9sa319kTNjai8S4B|zTCa8?}-e*fMCp{f}FxAsLr;jfo3 z%;S>(PR^T;z6Mdm{36R>wP))QrIJs6tD>5$-Nc|l>;o)UNXnt!Ay2YD9DIw_pY1Ty z(Dp%_?Yv#B?;hYa%hI>uRwjl_hV%S<724t)JZ8vxE&at5c0WoC0Cv7sRzg!7C~{U) zC9G2gIh8V%wfCdlb4&v*`5fq}{&*eZ`v8^+)4ih~&4KWFz$=?t9Qd5IZPnZ#THB03 z%pFO$jo-I0bE{-=?w4qXoBx#fZLq zL!_xxC2G6l!uMREATCg2)q?Z8?#syVpOvbFt&F3jMY#O95S*P0BZxwEv?*Nue!{*< z8`=dG>deR}ecRn_P2FrSFvbC#W{|UV( zFGSH;s3lbAkEB?=IVK02giSVobG`HV@6kteIREq{qYDu$CojvdqPFE>&^iy<<* zQlDC4KPwCs!`=Ai4*Js=VbwCtW`9D1%**K6B-&z-jS0!^mGO3(7ef!JRV2T|uwvA>h&U2_0!fgBckDaQIK3;J8h0y(gj z*-=P&Ihr{3$Ajt=a$&z(NV6F;IOhGeXx>=dsWZJ@9id5-k!|Q}9iuSScXaldqaKi7 z*SHkz#oC~cOkq-BXJuv{;7zN@{ww|)K`W8G1vC@E56@bb>^HQqb?eY@Y4$z(7AtbQ zU`i-FQMJJ4@QBx06GOt%{+C5dbL|+yd>RSQH|#t449_9M6f8?pjAP_ctN=OqFqah= z?#M;*Ah4F-mWOBkeZO_`IR&{Dkb>Dp1G%BcfWl{Z;KlbyxG&@$3x5bahx|Vffhit4 zF4!I21{AO#TFWjcHBbq*8YspnHlS~lMd829{V<>EUh0sCBZ&gxfq1My&1R!C9hT(% zReWC9S>S(VNQ5{^2K|@q@~73%=RJ-*FIWav{)|D+f52YJkjSDsuB9|l`~EqgT!y>d zgX)s*jDAP2&=+sEk%jyjW0SvAb2RGFW}+E8rmOskD0wZ?b4-n}M=i(;w`&!=O}c$xDXgwmNJZQzfd`xpg~*6-OUUPf_$*e%*O%A;89gE$zE zaQ6tI{j~Hg&u9k~W%Xxi=EMKe^pI987541?_0YEfpV6ErzUam8>t=kqYtEwU5%Zi` z{Q(+jFFC5|;gv5l`q%IoD*%X)Qc@(UzQ|+77kc1rVjGqez(%u{ufc0OuJ^M=yO?K+ z8m2f9vwrw%22$9-TNvNG;LhlBT8)9`+gwiIDp`2?;jBUH&%xuSwr7&NS<)n<*f&l~ zj8FP*EM$5pc9eqMP*pnldDlxV(eMn_m74UZc&c~hi=|&RGtlWufiF?#WGYmB#I!Y}W4P)044fgod2xByL(U2< z|Ftp6>4WnA9A@1LYqxY9Xu9j&-A!Lx|FCITTp92L)lZ%zRU%%Ur z?R{ggH-~1WMZSF7=arg!FlXmwv;qDhsKtTw_hm#l@0zsIyP# zrP%(#iUB$7D#~-b83F=*4r_kveCdXMpfF)&L3a6MhQP_yoW*Bf^ggoh@vHy}-bMj6 zV7LtF)wsLenrXjW-!WbK>n;Ou7qvu}I((83PdTU2=jYPn*#R#*iIHGGXCUgDbXkfe3%@AJPr)q4$!;|*T!JR%o zI_w#&a2_ZzklH*`Jh)%>R{l3!OyhSeTncIY63%z?K zOam2_`>rFz6GFa14Ne4q$~u_~*U2Yv8QDSEi7a>|U-ze&<`S#MTc5An;vA#~EzL<} zEh)!54zT;#QYqAp_3q0jtC6sTD8AvyUl9&mLu^R(ua6f#mNS<#d)pth>TTaGV9&%( zevg^_Me4bv6`0}m%CaHB&s$Ky`Iu1&V0qRMM$q&OtVTC|{E3e?suz`XrD3WgrRR$r z(U{X9G2B7rmDd=|IIeiTMOSEQ0PTK9TwWfRHLh=f9v%k){uidtyFMgs0X`~I?|rsg zeyT52Byx_YpgO`o>+fkrYXT8l+XtRs*7{a6wgEz^;kxucam(2tD7ivBa=OU<=&cse z=CK#npgb&Da5{gI9XfFpw0$9c23K`rkLjCEhN>4X20bnRsAe@vQZF>4NIO&60U!O5c^ZZm6RyVsvGB)S@Y36U~Q8teQh zd-c{kcPGyd;b-EZ?tijpIqd;;#CVBbu&3gkDlaG{c|7NxW2EuDRHqyr1kxFT#C z;m@RPVT253+IB5+{jz>1VTw3PUQuWnc+{c2cJ6$!hV*-(Q9YCFuHT+rPIfYq_Hf$n zq|QutG|5~yL|tZDkL%1y@0nPMP-;mEqSf{)C5MvT(S}1maVkK20||N6F;J&%j)l!| z`P|;#Gl}b>Sbyd!vIt@Si+FOa%DSy^M>XAMvR3fkmTQKoYrx!VU|?A+74`H2$safE zn7>xMC!CkE;Qp?AVy22eqzVQ6{7cUvlHm1|SudUzCqStwPs!e%0b>3))~Q$a&k=l( zmBJREv(W@Wb9|Qy8bh!VJSRj*nJtW`HE+e1wDv?SyuQ3}!VB!E<(u(lUi$KZWA?>- z-{3jOG!W-?MP zAn5-6WDpeVb3C$pJq+gmTm7YoK*?ECV7$766Zl0$Sel(C0=%^l)V+A8%J_BS8{!~HQh+Xck@_#YEC z*l;tuW%CQ$+GVtYv|<^Hr+{ zYoQsY{<0YB1aJ}NW~Y|+JVTW#|I-u(HFN)}l`GRZci6*&OG1eM2U%V|C~9jkvH@?x>$crjJ?uHBzRA?LVQ#MYOhmngEWv zl}akl=6U-T#og$38j4BUdb4#igYEl;hcvL)Jr!9WI~>o1uSF!Smf;>VcH6Jh+O-{| zanyX!IgZ5*k1qJ;8tLBdk)x06u03P$v%%pbahCt<&SocxM?b2AGC&hDv23vN3y+)8 zfUHQfbnfbEjWP2ymxOYD)2~qV?QyqRH$5rIWDuJ`r83`e+M&}rzRlBM`kgBKbjmLoUef#lo@;Zn1$^937SUiA8W-0Uw5p@ zO$Rkn%uCF(Wm_jgz9&7mIv+7;_WbZ1i`K|8obt=hz+Ec|itoAEHD5ne5A%a@?)mKt zVhJ=+-5Vm^lDhkhI<^1$jApWc z7#mlO*?H#0d?Xbu{__&77^RMC6?W{$y|1jX+?gU32OXz^HLdU+Q55DPwlnUp1yiZ9 zYU3wMt##FV<@QM1zHgg-lL^X@v`BMGl9)no{?3q4=NQ6n70`Vmke?NUdo8I zp{V61g(BPzJefy({_OCQ9Wnf{10c6aGMJIT`00_+_6|JEeWIA-`d4f4%oR6Jx5 zqpg1>kp0Bg0Gs{o#I)l=0}-A5hYbo-{R~F`>Uviyr#)Iwggpp^C_+0=5A9uy#M~6s z3~>(Bg}XW&*BJnlq9h>J3W{aJ=RIEdJ>gcSXYXAk>M$wwHShIa`{w>F&Gf)uQoQx* z#A-?Xtdfc90{8Ikr^%=arLgKx+#FToC-O4SMycBJzcjM=`}Jup?Ox)!Lx;-?hLfO! z>Grj?Se7=-c2yKa%<&ly*fXfR8f|C>ByIRcIl9eX2$=bT!bDuq`NNeEURcI$l{U2e zmD21GznYy0dM+4yj=eYsh1#|-QGMYuz-0-ZC*n|_ux>>r>iRu|E>q7ZI@TtK>oEB&b^F} zNh0QGCElDCA=LX6&XD_#?3A_!@`T_+^Fm>ruYR(FDocIMkW%fL&;*CIzRc+!m^HPk z@BPqtC7bD#Sy1W|dv_?w*HT6NIVo6$T0jngtiv3<@R$E%@Yg#=6@X=H9kAY>E)LpU zkpA+pm24(?;-kvdtLwpc(r?mKi_NGbgkr7YXnW@+^bxn$y=iL)VMR6m3T*HPmb_qt z8Cltl#Ecl@VtGT2gjXLX4anQ;t^OK?vt~ez{kJvSkr%9{&SRuoJpJ*=^_vIt{JWXC@}_W? zO8y2-V5cE9ym5cjRZUpBxNMP3-JZu5nCIJy7}~3^e&Ygj#Vv2KHbvl7!uS@M$wNCA zcs{O+RC03gL?Ah<;c?*tM11WtkA|O0vl9;}E*E=uia_f}N~<&l)UgVTe=Y71MQ!OU z&Bqv{H35bWp)_~qR{<1uBLywtMD~KxQAb26}Vm4E@0Yr|LL*3iH9U#}~vAK@-2ph7yDbXZ@_h zupQ9b)WuNLH#5l6i~{JCk5KnLmjPbv4=nmahkLt6O?zKWeV(`_=nZM`2@}#Myy^R5 z@+tBMg6($mCA8V+%T4Au-o;j9?Ki2i*V9WZ`zelMC3@ScDgrVKAmVCsQ#DK7E?WX0 z0(Y8OnzDCPeZ~6s<62{i)!Wqa0`oynB>BPZ9H`Y8cgp4l zV9F1RSSaf0V$yI)Ub}bG!$oAs#hg>_ej#hW-#P^-s;eUPkU(|+6kfTPwiZ`)eCMae z9}dBMEyTjW1k!1xfZ$E|73aG0u6|dJ0)wdWI`eR%OC7I7Uu^);F2s$PG*9ZKA z?J((FsM> zJm>B~jT~oackFLQ=jOIH6%;wRht$W^E)cm*3sJy4?K+mmnLdSZ%=@!gxagLU-1m`M zhZMpLJ)TH@2}sJ4Us(%f8W&r3uk4a)3D1&e17<05Z~)#OQVews%$*iqdKhpIL;39= ze5Eq<{nj(4x-VMiy+WRAqs^JhPLFsvZr-tZ0?je<6KZD%pQJ@Ypv&79UXLm5n zz)vJiBL7d6@p5rjVbT9d!UJHZa|TyV*WB$+6U8aFnfD9o$ktCvhHi%hjngWZ2=v<>jZmg(&Pr4>j1t zfOMMND;iS(mBJ$O3Uqs>m2%r8ecIu57(3w(4U9lb7N1Y()f3S(to{y zG`trtU)aah?q?BeeA==-7j^UkJ17ZMY*Nx0BPmksjL-X=ssDMF+9YH1!KTd;2s>q8 zxL9hyyZ`Hayd#ygCV*S#_F;OfiPb*_`Dx=j2-PGX-D`0FhGT*Llv{1G0d@Hf!7)dL z=k?rnX1y!B9tRbGmn}&;5y}drLvyfTJLN3jaZnqX3H%z>LK?b-Ci2gQ&$t}#4Kfsk z*u_ngsPXu%{*gP>w*QSK>nXj;nRfpi9!Mtcf{w#ld*TseJ95svBJ#|w06ca|c@rQ= zPbc=MV~4zvZZh3$;UHJ@B5|~IvW*Eq7Seyd4XUZa>LJyw)LlOBW&=`o;BV)DIc63c z>z|$0X*?_ChkVR#s|oWHL~t2%_iXU)@T@9_TRc3z>2fPfCjZ6kS4NcLs&bKiid}SC zl&!ir_`YG4XU<#tyt^OH%|BVZgFwOc0z|gOPq#%P7B;w07TKsTkx+I>edHI*5fZG( zOsZiL%17^Bdn@T2mTBUtnp*-Kis%;;g9{oxeUnkfb-sIg&dAvnZrfU5;7-Tb<#Fp1 z9)A<8z@bqHv|De-8lFI46`A-jf4Xu;)6ma-E4^q>$z4nnNd7SAOp=nxm~l(06@hNHPWViQ^xO2=05lduBP@HPx>EwDUg(uoI<5arpQXqW2+Gf z&!qnx-Pqk;o>ay8OLUMbrxM~?06*4WWavLz!AGyzBF{V5Z09)ujU+*3OkAJhk-O2( zP$`d)U~>YMTr<#_;IVA?ZXrYje|D^mDTPn8DG?fr$ChEBo*QKr2**T@9rgWIrRQgt zQIoGjNYuc{x1PP@I@(saVrh zFsP52A|oQrd05Gi%c|?iF%v)%6%7|N?R6zQhuhQ>)i43J-;KSZL3s`03F^N4+~nTR zmbr^U_SRCB82@u{C{a~gdmo%e-f6_VCF~Y(-k@v{I5LeewZ|`J(eL_wJ1clA-vpkT z3kLD09h_w%36|Q99uU7)CUS;NPMp4)xHpN)!mQ?GiaaJdqYY0)F79-7zEy~^JmLn46(3o{$Ez$y8C47 zBg@6=tfx(y%((}Uq>P45Z)J<<66GHd-qRtMN-v?+jbu+=!eX;W9eZKr)!(Q8j(aT; zM*+WYqzU)pueH<6Qz;SBnISd`Q5ow!0J2GeTv$4V+QgQD^neBilQJEmVjm8Q9+0Je zj+00tQpG2sPHS9OwO;(T=)TbhR~zL~z7LP+>YTYy-TAKec7hr)eEg zk==e5)Q3;P8Q9ogrpIS799o+=#J)otGh7e{a8ibYFlu$}jSCX{8Hwd9m)eRKSKG^J zl_HWO@y^LVY4(ce3w=aJH>$_Ph7puT#J!R75>J*i0SxGu`iUhhuSK`lQ>df`y6;~J zVtI)&tgQ}~cYWVGYzTC~nOiB9Wo{>Y)CBxu46n!k)JUycHMy*85SNhPm^SG_l&%Qe z(XwT6^ri58l3!uLeZVX=&wUR%WVtA&%#UsJHa70f+wHRhv~pF|zLWkXdB`0V@C;v8 zli^UnoKs*t68?7E?IB89f5o@&?gE}88K3YRQ%q};mfd|yx^AM;c8|YJ;)S;6Zo|h- zBajWm2ZFIlS>pdeXXE8Yb_{&47Hfus+!Zm<9#bqEo+bVtsKy3lP*p;BT_1sM*TA>c zC6d5}p$v*Q5Tprg2Pgg89)KJzd4k#qh4WCahB74_!+pIQuGK=2nBE}dKj2M(+Hcdr z2DfY!Ytqr5dv69{q+cAat`)x)MZ8t{Dha$%MFA9;wgS?rFwjqG!fHh6f7CyQo4+yVg=Asm6NmgyKJkAWkx@)5poZ#>`hOLv)axYu|L7LJ z1^rLy^G7~*CrC+B{6n#0oW#8zZWf`XB}eLzZ+b-w<(dcIyO)E6*vKFCz_AIQvO?s; zaaKp#qm%q~wz2(1i z#Lg&eu(Y6aXE=jXa5)DEIUyd;ui0GioV~kCrNF&%k_3o__8VgLja=VAiEF>^247{S zkzDtfL{Lzo$Itm8{@>SuR1RE<@ZSmyN^x(um5k;b!_0%$y#Y1H8MoGSzS~Hbu#=%9 ztPr_fF*(ZueP@%_(jg59xk4Jqgm3I%xH6VL%D|nYTKloe>eiHM?fG(&O3LDjYudTf zjMFn&O#N|v6gd=wieGv7yAAc)te_t&iLS{G4`SJ{$XQRKNy2uj<{4}goZf_;REB@( zsdQ3S#`~e*<}rfD0;?n*DcnS7tUMLVP8-pZ0PTLLu^Ih=ZjyjSs(IJw&9m?AgC}Vq zd4a*l*zr&W?jXmX0+t*wYbw=|Hn|P%fG*q&xeoQuX|<}6DTBm<-{GK#!P-Bpq)%FY zeO~+`60FA=!2D&c*z@n7Zs-n6zB9>%!pWCufn33He)anF;>)fs^{SN{MezmlcU)ki zt<)UL7zVfZga)8Q_Kyx>*egNl-veI;6wN@Va37oIiF{vDjXI?_D|xOl6Gxe-UvL)k ztuMJGc+Qx+PbpPwv4=|ju=dbp&im1H*1U@@V~=1w@~nG#pe->^!MtK6gK9#r@whi- z<5rUiZSRR#@rP}?E4zQ;mq08y^SZyF+@vi%o;O=(Tfr-sV#N!&+!>1OXCUg&Fuslr z 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 K8VwM;sQ&>O``elT literal 33087 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 Z!>4Z+lZ{pJ@TmVa$jhimBc%+3{vR@)I86Wm diff --git a/package.json b/package.json index 949738dbb..6bfaa9584 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "yudao-ui-admin-vue3", - "version": "2025.08-snapshot", + "version": "2025.09-snapshot", "description": "基于vue3、vite4、element-plus、typesScript", "author": "xingyu", "private": false, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ee421c275..be1cf6c89 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -86,6 +86,9 @@ importers: jsencrypt: specifier: ^3.3.2 version: 3.3.2 + jsoneditor: + specifier: ^10.1.3 + version: 10.4.1 lodash-es: specifier: ^4.17.21 version: 4.17.21 @@ -134,9 +137,6 @@ importers: url: specifier: ^0.11.3 version: 0.11.4 - v3-jsoneditor: - specifier: ^0.0.6 - version: 0.0.6 video.js: specifier: ^7.21.5 version: 7.21.6 @@ -183,6 +183,9 @@ importers: '@purge-icons/generated': specifier: ^0.9.0 version: 0.9.0 + '@types/jsoneditor': + specifier: ^9.9.5 + version: 9.9.6 '@types/lodash-es': specifier: ^4.17.12 version: 4.17.12 @@ -1602,7 +1605,7 @@ packages: resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==, tarball: https://registry.npmmirror.com/@sinclair/typebox/-/typebox-0.27.8.tgz} '@sphinxxxx/color-conversion@2.2.2': - resolution: {integrity: sha512-XExJS3cLqgrmNBIP3bBw6+1oQ1ksGjFh0+oClDKFYpCCqx/hlqwWO5KO/S63fzUo67SxI9dMrF0y5T/Ey7h8Zw==} + resolution: {integrity: sha512-XExJS3cLqgrmNBIP3bBw6+1oQ1ksGjFh0+oClDKFYpCCqx/hlqwWO5KO/S63fzUo67SxI9dMrF0y5T/Ey7h8Zw==, tarball: https://registry.npmmirror.com/@sphinxxxx/color-conversion/-/color-conversion-2.2.2.tgz} '@swc/core-darwin-arm64@1.9.3': resolution: {integrity: sha512-hGfl/KTic/QY4tB9DkTbNuxy5cV4IeejpPD4zo+Lzt4iLlDWIeANL4Fkg67FiVceNJboqg48CUX+APhDHO5G1w==, tarball: https://registry.npmmirror.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.9.3.tgz} @@ -1693,6 +1696,9 @@ packages: resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} engines: {node: '>=10.13.0'} + '@types/ace@0.0.52': + resolution: {integrity: sha512-YPF9S7fzpuyrxru+sG/rrTpZkC6gpHBPF14W3x70kqVOD+ks6jkYLapk4yceh36xej7K4HYxcyz9ZDQ2lTvwgQ==, tarball: https://registry.npmmirror.com/@types/ace/-/ace-0.0.52.tgz} + '@types/conventional-commits-parser@5.0.1': resolution: {integrity: sha512-7uz5EHdzz2TqoMfV7ee61Egf5y6NkcO4FB/1iCCQnbeiI1F3xzv3vK5dBCXUCLQgGYS+mUeigK1iKQzvED+QnQ==, tarball: https://registry.npmmirror.com/@types/conventional-commits-parser/-/conventional-commits-parser-5.0.1.tgz} @@ -1804,6 +1810,9 @@ packages: '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==, tarball: https://registry.npmmirror.com/@types/json-schema/-/json-schema-7.0.15.tgz} + '@types/jsoneditor@9.9.6': + resolution: {integrity: sha512-SJ29nWBIhnhtU5n72wxhPiuUVd8cnDHd7ZYMqVkzWtdRxTUdS8+oy1pg66yhmM1kcuanX3xmAAKfcyhhBnHEjQ==, tarball: https://registry.npmmirror.com/@types/jsoneditor/-/jsoneditor-9.9.6.tgz} + '@types/lodash-es@4.17.12': resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==, tarball: https://registry.npmmirror.com/@types/lodash-es/-/lodash-es-4.17.12.tgz} @@ -2334,7 +2343,7 @@ packages: hasBin: true ace-builds@1.39.1: - resolution: {integrity: sha512-HcJbBzx8qY66t9gZo/sQu7pi0wO/CFLdYn1LxQO1WQTfIkMfyc7LRnBpsp/oNCSSU/LL83jXHN1fqyOTuIhUjg==} + resolution: {integrity: sha512-HcJbBzx8qY66t9gZo/sQu7pi0wO/CFLdYn1LxQO1WQTfIkMfyc7LRnBpsp/oNCSSU/LL83jXHN1fqyOTuIhUjg==, tarball: https://registry.npmmirror.com/ace-builds/-/ace-builds-1.39.1.tgz} acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==, tarball: https://registry.npmmirror.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz} @@ -3607,7 +3616,7 @@ packages: hasBin: true javascript-natural-sort@0.7.1: - resolution: {integrity: sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==} + resolution: {integrity: sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==, tarball: https://registry.npmmirror.com/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz} jiti@1.21.6: resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==, tarball: https://registry.npmmirror.com/jiti/-/jiti-1.21.6.tgz} @@ -3618,7 +3627,7 @@ packages: hasBin: true jmespath@0.16.0: - resolution: {integrity: sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==} + resolution: {integrity: sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==, tarball: https://registry.npmmirror.com/jmespath/-/jmespath-0.16.0.tgz} engines: {node: '>= 0.6.0'} js-tokens@4.0.0: @@ -3652,7 +3661,7 @@ packages: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==, tarball: https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz} json-source-map@0.6.1: - resolution: {integrity: sha512-1QoztHPsMQqhDq0hlXY5ZqcEdUzxQEIxgFkKl4WUp2pgShObl+9ovi4kRh2TfvAfxAoHOJ9vIMEqk3k4iex7tg==} + resolution: {integrity: sha512-1QoztHPsMQqhDq0hlXY5ZqcEdUzxQEIxgFkKl4WUp2pgShObl+9ovi4kRh2TfvAfxAoHOJ9vIMEqk3k4iex7tg==, tarball: https://registry.npmmirror.com/json-source-map/-/json-source-map-0.6.1.tgz} json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==, tarball: https://registry.npmmirror.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz} @@ -3666,8 +3675,8 @@ packages: resolution: {integrity: sha512-WYDyuc/uFcGp6YtM2H0uKmUwieOuzeE/5YocFJLnLfclZ4inf3mRn8ZVy1s7Hxji7Jxm6Ss8gqpexD/GlKoGgg==, tarball: https://registry.npmmirror.com/jsonc-eslint-parser/-/jsonc-eslint-parser-2.4.0.tgz} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - jsoneditor@9.10.5: - resolution: {integrity: sha512-fVZ0NMt+zm4rqTKBv2x7zPdLeaRyKo1EjJkaR1QjK4gEM1rMwICILYSW1OPxSc1qqyAoDaA/eeNrluKoxOocCA==} + jsoneditor@10.4.1: + resolution: {integrity: sha512-89ao8IOKq6yTY+LSNw7FHoqcNrkATZN9W1u476P9ofGLSN/V0l2Je0MWG8HrYKMYqriJEpXmlsGT1CZbr99GWg==, tarball: https://registry.npmmirror.com/jsoneditor/-/jsoneditor-10.4.1.tgz} jsonfile@6.1.0: resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==, tarball: https://registry.npmmirror.com/jsonfile/-/jsonfile-6.1.0.tgz} @@ -3676,8 +3685,8 @@ packages: resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==, tarball: https://registry.npmmirror.com/jsonparse/-/jsonparse-1.3.1.tgz} engines: {'0': node >= 0.2.0} - jsonrepair@3.1.0: - resolution: {integrity: sha512-idqReg23J0PVRAADmZMc5xQM3xeOX5bTB6OTyMnzq33IXJXmn9iJuWIEvGmrN80rQf4d7uLTMEDwpzujNcI0Rg==} + jsonrepair@3.13.0: + resolution: {integrity: sha512-5YRzlAQ7tuzV1nAJu3LvDlrKtBFIALHN2+a+I1MGJCt3ldRDBF/bZuvIPzae8Epot6KBXd0awRZZcuoeAsZ/mw==, tarball: https://registry.npmmirror.com/jsonrepair/-/jsonrepair-3.13.0.tgz} hasBin: true katex@0.16.11: @@ -3963,9 +3972,6 @@ packages: mlly@1.7.3: resolution: {integrity: sha512-xUsx5n/mN0uQf4V548PKQ+YShA4/IW0KI1dZhrNrPCLG+xizETbHTkOa1f8/xut9JRPp8kQuMnz0oqwkTiLo/A==, tarball: https://registry.npmmirror.com/mlly/-/mlly-1.7.3.tgz} - mobius1-selectr@2.4.13: - resolution: {integrity: sha512-Mk9qDrvU44UUL0EBhbAA1phfQZ7aMZPjwtL7wkpiBzGh8dETGqfsh50mWoX9EkjDlkONlErWXArHCKfoxVg0Bw==} - moddle-xml@10.1.0: resolution: {integrity: sha512-erWckwLt+dYskewKXJso9u+aAZ5172lOiYxSOqKCPTy7L/xmqH1PoeoA7eVC7oJTt3PqF5TkZzUmbjGH6soQBg==, tarball: https://registry.npmmirror.com/moddle-xml/-/moddle-xml-10.1.0.tgz} @@ -4188,7 +4194,7 @@ packages: engines: {node: '>=12'} picomodal@3.0.0: - resolution: {integrity: sha512-FoR3TDfuLlqUvcEeK5ifpKSVVns6B4BQvc8SDF6THVMuadya6LLtji0QgUDSStw0ZR2J7I6UGi5V2V23rnPWTw==} + resolution: {integrity: sha512-FoR3TDfuLlqUvcEeK5ifpKSVVns6B4BQvc8SDF6THVMuadya6LLtji0QgUDSStw0ZR2J7I6UGi5V2V23rnPWTw==, tarball: https://registry.npmmirror.com/picomodal/-/picomodal-3.0.0.tgz} pidtree@0.6.0: resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==, tarball: https://registry.npmmirror.com/pidtree/-/pidtree-0.6.0.tgz} @@ -4882,11 +4888,8 @@ packages: resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==, tarball: https://registry.npmmirror.com/uuid/-/uuid-10.0.0.tgz} hasBin: true - v3-jsoneditor@0.0.6: - resolution: {integrity: sha512-9G0sXWXUn67SBkn46ycWfwPwjuJu/lcsQaNzMtXAR2/95hMV21WfcRNsqJ+vVVrSHQehohB/9fVLwYEXz0u/KA==} - vanilla-picker@2.12.3: - resolution: {integrity: sha512-qVkT1E7yMbUsB2mmJNFmaXMWE2hF8ffqzMMwe9zdAikd8u2VfnsVY2HQcOUi2F38bgbxzlJBEdS1UUhOXdF9GQ==} + resolution: {integrity: sha512-qVkT1E7yMbUsB2mmJNFmaXMWE2hF8ffqzMMwe9zdAikd8u2VfnsVY2HQcOUi2F38bgbxzlJBEdS1UUhOXdF9GQ==, tarball: https://registry.npmmirror.com/vanilla-picker/-/vanilla-picker-2.12.3.tgz} video.js@7.21.6: resolution: {integrity: sha512-m41TbODrUCToVfK1aljVd296CwDQnCRewpIm5tTXMuV87YYSGw1H+VDOaV45HlpcWSsTWWLF++InDgGJfthfUw==, tarball: https://registry.npmmirror.com/video.js/-/video.js-7.21.6.tgz} @@ -6637,6 +6640,8 @@ snapshots: '@trysound/sax@0.2.0': {} + '@types/ace@0.0.52': {} + '@types/conventional-commits-parser@5.0.1': dependencies: '@types/node': 20.17.9 @@ -6771,6 +6776,11 @@ snapshots: '@types/json-schema@7.0.15': {} + '@types/jsoneditor@9.9.6': + dependencies: + '@types/ace': 0.0.52 + ajv: 6.12.6 + '@types/lodash-es@4.17.12': dependencies: '@types/lodash': 4.17.13 @@ -8991,15 +9001,14 @@ snapshots: espree: 9.6.1 semver: 7.6.3 - jsoneditor@9.10.5: + jsoneditor@10.4.1: dependencies: ace-builds: 1.39.1 ajv: 6.12.6 javascript-natural-sort: 0.7.1 jmespath: 0.16.0 json-source-map: 0.6.1 - jsonrepair: 3.1.0 - mobius1-selectr: 2.4.13 + jsonrepair: 3.13.0 picomodal: 3.0.0 vanilla-picker: 2.12.3 @@ -9011,7 +9020,7 @@ snapshots: jsonparse@1.3.1: {} - jsonrepair@3.1.0: {} + jsonrepair@3.13.0: {} katex@0.16.11: dependencies: @@ -9313,8 +9322,6 @@ snapshots: pkg-types: 1.2.1 ufo: 1.5.4 - mobius1-selectr@2.4.13: {} - moddle-xml@10.1.0: dependencies: min-dash: 4.2.2 @@ -10242,10 +10249,6 @@ snapshots: uuid@10.0.0: {} - v3-jsoneditor@0.0.6: - dependencies: - jsoneditor: 9.10.5 - vanilla-picker@2.12.3: dependencies: '@sphinxxxx/color-conversion': 2.2.2 From 29b2ad4492f7dfcabe4c51d3921226c53c68dece Mon Sep 17 00:00:00 2001 From: Lesan <1960681385@qq.com> Date: Tue, 2 Sep 2025 17:04:01 +0800 Subject: [PATCH 046/161] =?UTF-8?q?chore:=20=E6=B7=BB=E5=8A=A0=E6=89=93?= =?UTF-8?q?=E5=8D=B0=E6=89=80=E9=9C=80=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index a79cec967..84341f3cd 100644 --- a/package.json +++ b/package.json @@ -76,6 +76,7 @@ "vue-i18n": "9.10.2", "vue-router": "4.4.5", "vue-types": "^5.1.1", + "vue3-print-nb": "^0.1.4", "vue3-signature": "^0.2.4", "vuedraggable": "^4.1.0", "web-storage-cache": "^1.1.1", From 4118112423d0fddac161552edf3f0c91f4a4070a Mon Sep 17 00:00:00 2001 From: Lesan <1960681385@qq.com> Date: Tue, 2 Sep 2025 17:04:31 +0800 Subject: [PATCH 047/161] =?UTF-8?q?feat:=20=E5=AE=9E=E7=8E=B0=E6=B5=81?= =?UTF-8?q?=E7=A8=8B=E6=89=93=E5=8D=B0=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/bpm/processInstance/index.ts | 5 + src/main.ts | 4 + .../processInstance/detail/PrintDialog.vue | 107 ++++++++++++++++++ .../bpm/processInstance/detail/index.vue | 7 +- 4 files changed, 121 insertions(+), 2 deletions(-) create mode 100644 src/views/bpm/processInstance/detail/PrintDialog.vue diff --git a/src/api/bpm/processInstance/index.ts b/src/api/bpm/processInstance/index.ts index 6b7921300..1e8f04dac 100644 --- a/src/api/bpm/processInstance/index.ts +++ b/src/api/bpm/processInstance/index.ts @@ -108,3 +108,8 @@ export const getFormFieldsPermission = async (params: any) => { export const getProcessInstanceBpmnModelView = async (id: string) => { return await request.get({ url: '/bpm/process-instance/get-bpmn-model-view?id=' + id }) } + +// 获取流程实例打印数据 +export const getProcessInstancePrintData = async (id: string) => { + return await request.get({ url: '/bpm/process-instance/get-print-data?processInstanceId=' + id }) +} diff --git a/src/main.ts b/src/main.ts index 211ecfbc3..3ffa5f0c9 100644 --- a/src/main.ts +++ b/src/main.ts @@ -45,6 +45,8 @@ import VueDOMPurifyHTML from 'vue-dompurify-html' // 解决v-html 的安全隐 // wangeditor插件注册 import {setupWangeditorPlugin} from "@/views/bpm/model/form/PrintTemplate"; +import print from 'vue3-print-nb' // 打印插件 + // 创建实例 const setupAll = async () => { const app = createApp(App) @@ -71,6 +73,8 @@ const setupAll = async () => { app.use(VueDOMPurifyHTML) + app.use(print) + app.mount('#app') } diff --git a/src/views/bpm/processInstance/detail/PrintDialog.vue b/src/views/bpm/processInstance/detail/PrintDialog.vue new file mode 100644 index 000000000..498e46b64 --- /dev/null +++ b/src/views/bpm/processInstance/detail/PrintDialog.vue @@ -0,0 +1,107 @@ + + + + + diff --git a/src/views/bpm/processInstance/detail/index.vue b/src/views/bpm/processInstance/detail/index.vue index fc32d2f42..b952560cd 100644 --- a/src/views/bpm/processInstance/detail/index.vue +++ b/src/views/bpm/processInstance/detail/index.vue @@ -128,6 +128,7 @@
+ diff --git a/src/views/bpm/model/form/PrintTemplate/Index.vue b/src/views/bpm/model/form/PrintTemplate/Index.vue index 6dff06d6a..dd37e1dec 100644 --- a/src/views/bpm/model/form/PrintTemplate/Index.vue +++ b/src/views/bpm/model/form/PrintTemplate/Index.vue @@ -1,11 +1,11 @@ From 535ccd33890b00c34d8558e433b143b5706eb1f5 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 4 Sep 2025 22:53:11 +0800 Subject: [PATCH 051/161] =?UTF-8?q?review=EF=BC=9A=E3=80=90bpm=20=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C=E6=B5=81=E3=80=91=E6=B5=81=E7=A8=8B=E6=89=93=E5=8D=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bpm/processInstance/detail/PrintDialog.vue | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/views/bpm/processInstance/detail/PrintDialog.vue b/src/views/bpm/processInstance/detail/PrintDialog.vue index dfa1fe6bf..527b0e771 100644 --- a/src/views/bpm/processInstance/detail/PrintDialog.vue +++ b/src/views/bpm/processInstance/detail/PrintDialog.vue @@ -22,7 +22,6 @@ const open = async (id: string) => { printData.value = await ProcessInstanceApi.getProcessInstancePrintData(id) initPrintDataMap() parseFormFields() - console.log(printData.value) } finally { loading.value = false } @@ -31,6 +30,7 @@ const open = async (id: string) => { defineExpose({ open }) const parseFormFields = () => { + // TODO @lesan:form field 有可能基于 form-create 什么 api 生成么?好像也挺难的 = = const formFieldsObj = decodeFields(printData.value.formFields) const processVariables = printData.value.processVariables let res: any = [] @@ -39,10 +39,10 @@ const parseFormFields = () => { const name = item['title'] let html = '暂不支持此类型的表单展示' // TODO 完善各类型表单的展示 + // TODO @lesan:要不 UploadImg、UploadFile 特殊处理下,其它就 else processVariables[item['field']]? if (item['type'] === 'input') { html = processVariables[item['field']] - } - if (item['type'] === 'UploadImg') { + } else if (item['type'] === 'UploadImg') { html = `` } printDataMap.value[item['field']] = html @@ -75,7 +75,7 @@ const getPrintTemplateHTML = () => { item.setAttribute('border', '1') item.setAttribute('style', (item.getAttribute('style') || '') + 'border-collapse:collapse;') }) - // 替换mentions + // 替换 mentions let mentions = doc.querySelectorAll('[data-w-e-type="mention"]') mentions.forEach((item) => { const mentionId = JSON.parse(decodeURIComponent(item.getAttribute('data-info') ?? ''))['id'] @@ -83,7 +83,7 @@ const getPrintTemplateHTML = () => { }) // 替换流程记录 let processRecords = doc.querySelectorAll('[data-w-e-type="process-record"]') - let processRecordTable : Element = document.createElement('table') + let processRecordTable: Element = document.createElement('table') if (processRecords.length > 0) { // 构建流程记录html processRecordTable.setAttribute('border', '1') @@ -96,7 +96,7 @@ const getPrintTemplateHTML = () => { headTd.innerHTML = '流程节点' headTr.appendChild(headTd) processRecordTable.appendChild(headTr) - printData.value.approveNodes.forEach(item => { + printData.value.approveNodes.forEach((item) => { const tr = document.createElement('tr') const td1 = document.createElement('td') td1.innerHTML = item.nodeName @@ -107,10 +107,10 @@ const getPrintTemplateHTML = () => { processRecordTable.appendChild(tr) }) } - processRecords.forEach(item => { + processRecords.forEach((item) => { item.innerHTML = processRecordTable.outerHTML }) - // 返回html + // 返回 html return doc.body.innerHTML } From 722d6405a172da9fbb493267453354c144e3c0ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B1=B1=E9=87=8E=E7=BE=A1=E6=B0=91?= Date: Fri, 5 Sep 2025 03:58:12 +0000 Subject: [PATCH 052/161] =?UTF-8?q?=E9=9B=AA=E8=8A=B1=20ID=20=E6=BA=A2?= =?UTF-8?q?=E5=87=BA=E9=97=AE=E9=A2=98=20update=20src/views/mall/promotion?= =?UTF-8?q?/rewardActivity/components/RewardRuleCouponSelect.vue.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 山野羡民 --- .../rewardActivity/components/RewardRuleCouponSelect.vue | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/views/mall/promotion/rewardActivity/components/RewardRuleCouponSelect.vue b/src/views/mall/promotion/rewardActivity/components/RewardRuleCouponSelect.vue index 504e72275..41b1f2bbb 100644 --- a/src/views/mall/promotion/rewardActivity/components/RewardRuleCouponSelect.vue +++ b/src/views/mall/promotion/rewardActivity/components/RewardRuleCouponSelect.vue @@ -89,9 +89,7 @@ const initGiveCouponList = async () => { if (isEmpty(rewardRule.value) || isEmpty(rewardRule.value.giveCouponTemplateCounts)) { return } - const tempLateIds = Object.keys(rewardRule.value.giveCouponTemplateCounts!).map((item) => - parseInt(item) - ) + const tempLateIds = Object.keys(rewardRule.value.giveCouponTemplateCounts!) const data = await CouponTemplateApi.getCouponTemplateList(tempLateIds) if (!data) { return From d64b49ba9427d3b70e86d1a9c742e3d6568db457 Mon Sep 17 00:00:00 2001 From: Lesan <1960681385@qq.com> Date: Sat, 6 Sep 2025 10:37:41 +0800 Subject: [PATCH 053/161] =?UTF-8?q?feat:=20=E4=BB=A3=E7=A0=81=E8=AF=84?= =?UTF-8?q?=E5=AE=A1=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../processInstance/detail/PrintDialog.vue | 129 ++++++++++++++---- 1 file changed, 101 insertions(+), 28 deletions(-) diff --git a/src/views/bpm/processInstance/detail/PrintDialog.vue b/src/views/bpm/processInstance/detail/PrintDialog.vue index 527b0e771..37ce48a04 100644 --- a/src/views/bpm/processInstance/detail/PrintDialog.vue +++ b/src/views/bpm/processInstance/detail/PrintDialog.vue @@ -3,7 +3,9 @@ import * as ProcessInstanceApi from '@/api/bpm/processInstance' import { useUserStore } from '@/store/modules/user' import { formatDate } from '@/utils/formatTime' import { DICT_TYPE, getDictLabel } from '@/utils/dict' -import { decodeFields } from '@/utils/formCreate' +import { decodeFields, setConfAndFields2 } from '@/utils/formCreate' +import type { ApiAttrs } from '@form-create/element-ui/types/config' +import formCreate from "@form-create/element-ui"; const userStore = useUserStore() @@ -16,6 +18,21 @@ const printTime = ref(formatDate(new Date(), 'YYYY-MM-DD HH:mm')) const formFields = ref() const printDataMap = ref({}) +const fApi = ref() +const detailForm = ref({ + rule: [], + option: {}, + value: {} +}) + +const fApiH = ref() +const detailFormH = ref({ + rule: [], + option: {}, + value: {} +}) +const fcRef = ref() + const open = async (id: string) => { loading.value = true try { @@ -30,9 +47,38 @@ const open = async (id: string) => { defineExpose({ open }) const parseFormFields = () => { + const processInstance = printData.value.processInstance + const processDefinition = processInstance.processDefinition + setConfAndFields2( + detailForm, + processDefinition.formConf, + processDefinition.formFields, + processInstance.formVariables + ) + detailForm.value.option = { + submitBtn: false, + resetBtn: false, + form: { + disabled: true + } + } + setConfAndFields2( + detailFormH, + processDefinition.formConf, + processDefinition.formFields, + processInstance.formVariables + ) + detailFormH.value.option = { + submitBtn: false, + resetBtn: false, + form: { + disabled: true + } + } + return // TODO @lesan:form field 有可能基于 form-create 什么 api 生成么?好像也挺难的 = = const formFieldsObj = decodeFields(printData.value.formFields) - const processVariables = printData.value.processVariables + const processVariables = printData.value.processInstance.formVariables let res: any = [] for (const item of formFieldsObj) { const id = item['field'] @@ -40,6 +86,7 @@ const parseFormFields = () => { let html = '暂不支持此类型的表单展示' // TODO 完善各类型表单的展示 // TODO @lesan:要不 UploadImg、UploadFile 特殊处理下,其它就 else processVariables[item['field']]? + // TODO @芋艿:感觉很多都要处理一下,select那些都要转为可读的label,还有子表单那些,都需要处理一下... if (item['type'] === 'input') { html = processVariables[item['field']] } else if (item['type'] === 'UploadImg') { @@ -52,15 +99,15 @@ const parseFormFields = () => { } const initPrintDataMap = () => { - printDataMap.value['startUser'] = printData.value.startUser.nickname - printDataMap.value['startUserDept'] = printData.value.startUser.deptName - printDataMap.value['processName'] = printData.value.processName - printDataMap.value['processNum'] = printData.value.processInstanceId - printDataMap.value['startTime'] = printData.value.startTime - printDataMap.value['endTime'] = printData.value.endTime + printDataMap.value['startUser'] = printData.value.processInstance.startUser.nickname + printDataMap.value['startUserDept'] = printData.value.processInstance.startUser.deptName + printDataMap.value['processName'] = printData.value.processInstance.name + printDataMap.value['processNum'] = printData.value.processInstance.id + printDataMap.value['startTime'] = formatDate(printData.value.processInstance.startTime) + printDataMap.value['endTime'] = formatDate(printData.value.processInstance.endTime) printDataMap.value['processStatus'] = getDictLabel( DICT_TYPE.BPM_PROCESS_INSTANCE_STATUS, - printData.value.processStatus + printData.value.processInstance.status ) printDataMap.value['printUsername'] = userName.value printDataMap.value['printTime'] = printTime.value @@ -96,12 +143,12 @@ const getPrintTemplateHTML = () => { headTd.innerHTML = '流程节点' headTr.appendChild(headTd) processRecordTable.appendChild(headTr) - printData.value.approveNodes.forEach((item) => { + printData.value.tasks.forEach((item) => { const tr = document.createElement('tr') const td1 = document.createElement('td') - td1.innerHTML = item.nodeName + td1.innerHTML = item.name const td2 = document.createElement('td') - td2.innerHTML = item.nodeDesc + td2.innerHTML = item.description tr.appendChild(td1) tr.appendChild(td2) processRecordTable.appendChild(tr) @@ -114,6 +161,25 @@ const getPrintTemplateHTML = () => { return doc.body.innerHTML } +const html = ref('') +const handleDialogOpened = async () => { + const processInstance = printData.value.processInstance + const processDefinition = processInstance.processDefinition + let fcData = { + rule: [], + option: {}, + value: {} + } + setConfAndFields2( + fcData, + processDefinition.formConf, + processDefinition.formFields, + processInstance.formVariables + ) + const api = formCreate.create(fcData.rule,fcData.option) + console.log(api) +} + const printObj = ref({ id: 'printDivTag', popTitle: ' ', @@ -128,26 +194,31 @@ const printObj = ref({
-

{{ printData.processName }}

+

{{ printData.processInstance.name }}

{{ '打印人员: ' + userName }}
-
{{ '流程编号: ' + printData.processInstanceId }}
+
{{ '流程编号: ' + printData.processInstance.id }}
{{ '打印时间: ' + printTime }}
- + - + - + @@ -155,12 +226,14 @@ const printObj = ref({

表单内容

- - - + @@ -168,12 +241,12 @@ const printObj = ref({

流程节点

- + - - + + @@ -258,7 +202,7 @@ const printObj = ref({ From bcf8f6c821c441c2875d2d436680a6228aceea17 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 7 Sep 2025 17:21:52 +0800 Subject: [PATCH 056/161] =?UTF-8?q?review=EF=BC=9A=E3=80=90bpm=20=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C=E6=B5=81=E3=80=91=E6=B5=81=E7=A8=8B=E6=89=93=E5=8D=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/bpm/processInstance/detail/PrintDialog.vue | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/views/bpm/processInstance/detail/PrintDialog.vue b/src/views/bpm/processInstance/detail/PrintDialog.vue index 4be26eed6..99cde927b 100644 --- a/src/views/bpm/processInstance/detail/PrintDialog.vue +++ b/src/views/bpm/processInstance/detail/PrintDialog.vue @@ -42,6 +42,7 @@ const parseFormFields = () => { // TODO 完善各类型表单的展示 // TODO @lesan:要不 UploadImg、UploadFile 特殊处理下,其它就 else processVariables[item['field']]? // TODO @芋艿:感觉很多都要处理一下,select那些都要转为可读的label,还有子表单那些,都需要处理一下... + // TODO @lesan:有办法基于 form-create api 来读取值么?如果不行,就兜底让大模型生成一些常用的。子表单可以往后放; if (item['type'] === 'input') { html = processVariables[item['field']] } else if (item['type'] === 'UploadImg') { @@ -191,8 +192,8 @@ const printObj = ref({ From ba640310152826d5aada960296847d5fb3a2ed48 Mon Sep 17 00:00:00 2001 From: Lesan <1960681385@qq.com> Date: Mon, 8 Sep 2025 09:57:02 +0800 Subject: [PATCH 057/161] =?UTF-8?q?fix:=20=E6=89=93=E5=8D=B0=E5=8F=AA?= =?UTF-8?q?=E8=83=BD=E6=98=BE=E7=A4=BA=E4=B8=80=E9=A1=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bpm/processInstance/detail/PrintDialog.vue | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/views/bpm/processInstance/detail/PrintDialog.vue b/src/views/bpm/processInstance/detail/PrintDialog.vue index 99cde927b..c152c0196 100644 --- a/src/views/bpm/processInstance/detail/PrintDialog.vue +++ b/src/views/bpm/processInstance/detail/PrintDialog.vue @@ -128,7 +128,7 @@ const printObj = ref({ + + From bd91bd9057a803f2ec7064267db57865a88f2620 Mon Sep 17 00:00:00 2001 From: Lesan <1960681385@qq.com> Date: Mon, 8 Sep 2025 11:27:31 +0800 Subject: [PATCH 058/161] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0radio?= =?UTF-8?q?=E3=80=81checkbox=E3=80=81select=E6=89=93=E5=8D=B0=E6=98=BE?= =?UTF-8?q?=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../processInstance/detail/PrintDialog.vue | 56 +++++++++++-------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/src/views/bpm/processInstance/detail/PrintDialog.vue b/src/views/bpm/processInstance/detail/PrintDialog.vue index c152c0196..ab17f8c0f 100644 --- a/src/views/bpm/processInstance/detail/PrintDialog.vue +++ b/src/views/bpm/processInstance/detail/PrintDialog.vue @@ -30,23 +30,37 @@ const open = async (id: string) => { defineExpose({ open }) const parseFormFields = () => { - // TODO @lesan:form field 有可能基于 form-create 什么 api 生成么?好像也挺难的 = = - // TODO @芋艿:默认打印可以直接用form-create的预览表单模式,但是自定义模板打印就没法这么做 const formFieldsObj = decodeFields(printData.value.processInstance.processDefinition.formFields) const processVariables = printData.value.processInstance.formVariables let res: any = [] for (const item of formFieldsObj) { const id = item['field'] const name = item['title'] - let html = '暂不支持此类型的表单展示' - // TODO 完善各类型表单的展示 - // TODO @lesan:要不 UploadImg、UploadFile 特殊处理下,其它就 else processVariables[item['field']]? - // TODO @芋艿:感觉很多都要处理一下,select那些都要转为可读的label,还有子表单那些,都需要处理一下... - // TODO @lesan:有办法基于 form-create api 来读取值么?如果不行,就兜底让大模型生成一些常用的。子表单可以往后放; - if (item['type'] === 'input') { - html = processVariables[item['field']] - } else if (item['type'] === 'UploadImg') { - html = `` + const variable = processVariables[item['field']] + let html = variable + switch (item['type']) { + case 'UploadImg': { + let imgEl = document.createElement('img') + imgEl.setAttribute('src', variable) + imgEl.setAttribute('style', 'max-width: 600px;') + html = imgEl.outerHTML + break + } + case 'radio': + case 'checkbox': + case 'select': { + const options = item['options'] || [] + const temp: any = [] + if (Array.isArray(variable)) { + const labels = options.filter((o) => variable.includes(o.value)).map((o) => o.label) + temp.push(...labels) + } else { + const opt = options.find((o) => o.value === variable) + temp.push(opt.label) + } + html = temp.join(',') + } + // TODO 更多表单打印展示 } printDataMap.value[item['field']] = html res.push({ id, name, html }) @@ -128,7 +142,7 @@ const printObj = ref({ From 9c8abbc3419fa954a364c52ba5c78e4b128bd6c7 Mon Sep 17 00:00:00 2001 From: sunjianfeng Date: Fri, 12 Sep 2025 01:05:07 +0800 Subject: [PATCH 059/161] =?UTF-8?q?fix:=E5=89=8D=E7=AB=AF=E4=B8=8A?= =?UTF-8?q?=E4=BC=A0=E5=A4=B4=E5=83=8F=E5=90=8D=E7=A7=B0=E5=8F=96=E5=80=BC?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E4=BB=A5=E5=8F=8A=E7=94=A8=E6=88=B7=E4=BF=9D?= =?UTF-8?q?=E5=AD=98=E4=B8=AA=E4=BA=BA=E4=BF=A1=E6=81=AF=E6=97=B6=E8=BF=98?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E7=9A=84=E6=98=AF=E6=97=A7=E7=9A=84=E5=A4=B4?= =?UTF-8?q?=E5=83=8F=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/UploadFile/src/useUpload.ts | 10 +++++----- src/views/Profile/components/BasicInfo.vue | 15 +++++++++++++++ src/views/Profile/components/ProfileUser.vue | 13 +++++++++++++ 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/src/components/UploadFile/src/useUpload.ts b/src/components/UploadFile/src/useUpload.ts index 951b23978..9fc27a0b4 100644 --- a/src/components/UploadFile/src/useUpload.ts +++ b/src/components/UploadFile/src/useUpload.ts @@ -20,7 +20,7 @@ export const useUpload = (directory?: string) => { // 模式一:前端上传 if (isClientUpload) { // 1.1 生成文件名称 - const fileName = await generateFileName(options.file) + const fileName = options.filename // 1.2 获取文件预签名地址 const presignedInfo = await FileApi.getFilePresignedUrl(fileName, directory) // 1.3 上传文件(不能使用 ElUpload 的 ajaxUpload 方法的原因:其使用的是 FormData 上传,Minio 不支持) @@ -32,7 +32,7 @@ export const useUpload = (directory?: string) => { }) .then(() => { // 1.4. 记录文件信息到后端(异步) - createFile(presignedInfo, options.file) + createFile(presignedInfo, options.file,fileName) // 通知成功,数据格式保持与后端上传的返回结果一致 return { data: presignedInfo.url } }) @@ -64,15 +64,15 @@ export const useUpload = (directory?: string) => { /** * 创建文件信息 * @param vo 文件预签名信息 - * @param name 文件名称 * @param file 文件 + * @param fileName */ -function createFile(vo: FileApi.FilePresignedUrlRespVO, file: UploadRawFile) { +function createFile(vo: FileApi.FilePresignedUrlRespVO, file: UploadRawFile, fileName: string) { const fileVo = { configId: vo.configId, url: vo.url, path: vo.path, - name: file.name, + name: fileName, type: file.type, size: file.size } diff --git a/src/views/Profile/components/BasicInfo.vue b/src/views/Profile/components/BasicInfo.vue index f785affb9..82181d1f1 100644 --- a/src/views/Profile/components/BasicInfo.vue +++ b/src/views/Profile/components/BasicInfo.vue @@ -78,6 +78,21 @@ const schema = reactive([ } ]) const formRef = ref() // 表单 Ref + +// 监听 userStore 中头像的变化,同步更新表单数据 +watch( + () => userStore.getUser.avatar, + (newAvatar) => { + if (newAvatar && formRef.value) { + // 直接更新表单模型中的头像字段 + const formModel = formRef.value.formModel + if (formModel) { + formModel.avatar = newAvatar + } + } + } +) + const submit = () => { const elForm = unref(formRef)?.getElFormRef() if (!elForm) return diff --git a/src/views/Profile/components/ProfileUser.vue b/src/views/Profile/components/ProfileUser.vue index 6282c3e0d..e226af09f 100644 --- a/src/views/Profile/components/ProfileUser.vue +++ b/src/views/Profile/components/ProfileUser.vue @@ -49,18 +49,31 @@ From 481b483ee416ca44ce6f9a746b517b28850e36cf Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 21 Sep 2025 19:22:17 +0800 Subject: [PATCH 064/161] =?UTF-8?q?fix=EF=BC=9A=E3=80=90ai=20=E5=A4=A7?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B=E3=80=91=E9=80=89=E6=8B=A9=E8=A7=92=E8=89=B2?= =?UTF-8?q?=E5=90=8E=EF=BC=8C=E6=96=B0=E5=A2=9E=20tab=20=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ai/chat/index/components/role/RoleRepository.vue | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/views/ai/chat/index/components/role/RoleRepository.vue b/src/views/ai/chat/index/components/role/RoleRepository.vue index e9bb2054d..04113731f 100644 --- a/src/views/ai/chat/index/components/role/RoleRepository.vue +++ b/src/views/ai/chat/index/components/role/RoleRepository.vue @@ -70,8 +70,11 @@ import { ChatRoleApi, ChatRolePageReqVO, ChatRoleVO } from '@/api/ai/model/chatR import { ChatConversationApi, ChatConversationVO } from '@/api/ai/chat/conversation' import { Search } from '@element-plus/icons-vue' import { TabsPaneContext } from 'element-plus' +import { useTagsViewStore } from '@/store/modules/tagsView' const router = useRouter() // 路由对象 +const { currentRoute } = useRouter() // 路由 +const { delView } = useTagsViewStore() // 视图操作 // 属性定义 const loading = ref(false) // 加载中 @@ -121,7 +124,7 @@ const getPublicRole = async (append?: boolean) => { name: search.value, publicStatus: true } - const { total, list } = await ChatRoleApi.getMyPage(params) + const { list } = await ChatRoleApi.getMyPage(params) if (append) { publicRoleList.value.push.apply(publicRoleList.value, list) } else { @@ -201,7 +204,8 @@ const handlerCardUse = async (role) => { const conversationId = await ChatConversationApi.createChatConversationMy(data) // 2. 跳转页面 - await router.push({ + delView(unref(currentRoute)) + await router.replace({ name: 'AiChat', query: { conversationId: conversationId From a126f42c35c9bd6efcde1761e8551708fd99638f Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 2 Oct 2025 09:36:06 +0800 Subject: [PATCH 065/161] =?UTF-8?q?fix=EF=BC=9A=E3=80=90bpm=20=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C=E6=B5=81=E3=80=91=E5=B7=B2=E5=8A=9E=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E7=9A=84=E5=AE=A1=E6=89=B9=E7=8A=B6=E6=80=81=E8=BF=87=E6=BB=A4?= =?UTF-8?q?=E4=B8=8D=E6=AD=A3=E7=A1=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/bpm/task/done/index.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/views/bpm/task/done/index.vue b/src/views/bpm/task/done/index.vue index 29c4d7558..202cd0e7d 100644 --- a/src/views/bpm/task/done/index.vue +++ b/src/views/bpm/task/done/index.vue @@ -52,13 +52,13 @@ Date: Thu, 2 Oct 2025 09:41:54 +0800 Subject: [PATCH 066/161] =?UTF-8?q?fix=EF=BC=9A=E5=89=8D=E7=AB=AF=E7=9A=84?= =?UTF-8?q?=E5=AF=86=E7=A0=81=E9=95=BF=E5=BA=A6=E9=99=90=E5=88=B6=E7=BB=9F?= =?UTF-8?q?=E4=B8=80=EF=BC=8Chttps://gitee.com/yudaocode/yudao-ui-admin-vu?= =?UTF-8?q?e3/issues/ICVDAT?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/Profile/components/ResetPwd.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/views/Profile/components/ResetPwd.vue b/src/views/Profile/components/ResetPwd.vue index 477be91f4..d9e0de183 100644 --- a/src/views/Profile/components/ResetPwd.vue +++ b/src/views/Profile/components/ResetPwd.vue @@ -44,11 +44,11 @@ const equalToPassword = (_rule, value, callback) => { const rules = reactive({ oldPassword: [ { required: true, message: t('profile.password.oldPwdMsg'), trigger: 'blur' }, - { min: 6, max: 20, message: t('profile.password.pwdRules'), trigger: 'blur' } + { min: 4, max: 16, message: t('profile.password.pwdRules'), trigger: 'blur' } ], newPassword: [ { required: true, message: t('profile.password.newPwdMsg'), trigger: 'blur' }, - { min: 6, max: 20, message: t('profile.password.pwdRules'), trigger: 'blur' } + { min: 4, max: 16, message: t('profile.password.pwdRules'), trigger: 'blur' } ], confirmPassword: [ { required: true, message: t('profile.password.cfPwdMsg'), trigger: 'blur' }, From 62a9a991469e6db8d61e844f7b895f91c408206b Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 2 Oct 2025 10:24:22 +0800 Subject: [PATCH 067/161] =?UTF-8?q?fix=EF=BC=9A=E3=80=90pay=20=E6=94=AF?= =?UTF-8?q?=E4=BB=98=E3=80=91=E5=BE=AE=E4=BF=A1=E6=94=AF=E4=BB=98=20public?= =?UTF-8?q?KeyContent=20=E8=B0=83=E6=95=B4=E4=B8=BA=E9=9D=9E=E5=BF=85?= =?UTF-8?q?=E5=A1=AB=EF=BC=8C=E5=85=BC=E5=AE=B9=20https://t.zsxq.com/ODR5V?= =?UTF-8?q?=E3=80=81https://gitee.com/yudaocode/yudao-ui-admin-vue3/issues?= =?UTF-8?q?/ICUE53?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/channel/WeixinChannelForm.vue | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/views/pay/app/components/channel/WeixinChannelForm.vue b/src/views/pay/app/components/channel/WeixinChannelForm.vue index daebb41e0..fd915548e 100644 --- a/src/views/pay/app/components/channel/WeixinChannelForm.vue +++ b/src/views/pay/app/components/channel/WeixinChannelForm.vue @@ -147,7 +147,11 @@ 前往微信商户平台查看证书序列号 - + - + - + 微信支付公钥产品简介及使用说明 @@ -246,7 +243,6 @@ const formRules = { { required: true, message: '请上传 apiclient_key.pem 证书', trigger: 'blur' } ], 'config.certSerialNo': [{ required: true, message: '请输入证书序列号', trigger: 'blur' }], - 'config.publicKeyContent': [{ required: true, message: '请上传 public_key.pem 证书', trigger: 'blur' }], 'config.publicKeyId': [{ required: true, message: '请输入公钥 ID', trigger: 'blur' }], 'config.apiV3Key': [{ required: true, message: '请上传 api V3 密钥值', trigger: 'blur' }] } From bdb42bb927261410af56c39a75a7821a3e2791ec Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 2 Oct 2025 11:25:34 +0800 Subject: [PATCH 068/161] =?UTF-8?q?fix=EF=BC=9A=E3=80=90=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E3=80=91=E4=BA=A7=E5=93=81=E8=B7=B3=E8=BD=AC=E5=88=B0=E8=AE=BE?= =?UTF-8?q?=E5=A4=87=E5=88=97=E8=A1=A8=E6=97=B6=EF=BC=8CproductId=20?= =?UTF-8?q?=E6=9C=AA=E4=BC=A0=E9=80=92=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=8C?= =?UTF-8?q?=E5=AF=B9=E5=BA=94=20https://t.zsxq.com/jvXyq?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/iot/device/device/index.vue | 10 ++++++++-- .../product/product/detail/ProductDetailsHeader.vue | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/views/iot/device/device/index.vue b/src/views/iot/device/device/index.vue index 56139be9a..67ef01cb7 100644 --- a/src/views/iot/device/device/index.vue +++ b/src/views/iot/device/device/index.vue @@ -384,6 +384,7 @@ defineOptions({ name: 'IoTDevice' }) const message = useMessage() // 消息弹窗 const { t } = useI18n() // 国际化 +const route = useRoute() const loading = ref(true) // 列表加载中 const list = ref([]) // 列表的数据 @@ -392,7 +393,7 @@ const queryParams = reactive({ pageNo: 1, pageSize: 10, deviceName: undefined, - productId: undefined, + productId: undefined as number | undefined, deviceType: undefined, nickname: undefined, status: undefined, @@ -513,7 +514,12 @@ const handleImport = () => { /** 初始化 **/ onMounted(async () => { - getList() + // 处理 productId 参数 + const { productId } = route.query + if (productId) { + queryParams.productId = Number(productId) + } + await getList() // 获取产品列表 products.value = await ProductApi.getSimpleProductList() diff --git a/src/views/iot/product/product/detail/ProductDetailsHeader.vue b/src/views/iot/product/product/detail/ProductDetailsHeader.vue index 919006477..3eb999fa4 100644 --- a/src/views/iot/product/product/detail/ProductDetailsHeader.vue +++ b/src/views/iot/product/product/detail/ProductDetailsHeader.vue @@ -72,7 +72,7 @@ const copyToClipboard = async (text: string) => { /** 路由跳转到设备管理 */ const { push } = useRouter() const goToDeviceList = (productId: number) => { - push({ name: 'IoTDevice', params: { productId } }) + push({ name: 'IoTDevice', query: { productId } }) } /** 修改操作 */ From 9bc289cb2a354b3bca138f7ac7ec2987b503bff6 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Mon, 6 Oct 2025 20:45:35 +0800 Subject: [PATCH 069/161] =?UTF-8?q?fix=EF=BC=9A=E6=9B=B4=E6=96=B0=E6=8C=89?= =?UTF-8?q?=E9=92=AE=E6=96=87=E6=9C=AC=E4=B8=BA=E2=80=9C=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E9=94=80=E5=94=AE=E4=BA=A7=E5=93=81=E2=80=9D=E5=B9=B6=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E6=94=AF=E4=BB=98=E4=BF=A1=E6=81=AF=E5=B1=95=E7=A4=BA?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/erp/sale/order/components/SaleOrderItemForm.vue | 2 +- src/views/pay/cashier/index.vue | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/views/erp/sale/order/components/SaleOrderItemForm.vue b/src/views/erp/sale/order/components/SaleOrderItemForm.vue index 3a579d5b5..817775f56 100644 --- a/src/views/erp/sale/order/components/SaleOrderItemForm.vue +++ b/src/views/erp/sale/order/components/SaleOrderItemForm.vue @@ -132,7 +132,7 @@ - + 添加采购产品 + + 添加销售产品 diff --git a/src/views/mp/freePublish/index.vue b/src/views/mp/freePublish/index.vue index 2ed8ae77e..c5639ec3e 100644 --- a/src/views/mp/freePublish/index.vue +++ b/src/views/mp/freePublish/index.vue @@ -97,7 +97,9 @@ const handleDelete = async (item: any) => { message.success(t('common.delSuccess')) // 刷新列表 await getList() - } catch {} + } catch { + // + } } diff --git a/src/views/mp/template/MsgTemplateLog.vue b/src/views/mp/template/MsgTemplateLog.vue new file mode 100644 index 000000000..e3fd9234c --- /dev/null +++ b/src/views/mp/template/MsgTemplateLog.vue @@ -0,0 +1,214 @@ + + + diff --git a/src/views/mp/template/MsgTemplateLogForm.vue b/src/views/mp/template/MsgTemplateLogForm.vue new file mode 100644 index 000000000..1266806f5 --- /dev/null +++ b/src/views/mp/template/MsgTemplateLogForm.vue @@ -0,0 +1,144 @@ + + \ No newline at end of file diff --git a/src/views/mp/template/MsgTemplateSend.vue b/src/views/mp/template/MsgTemplateSend.vue new file mode 100644 index 000000000..286be80e9 --- /dev/null +++ b/src/views/mp/template/MsgTemplateSend.vue @@ -0,0 +1,82 @@ + + + + + diff --git a/src/views/mp/user/index.vue b/src/views/mp/user/index.vue index 772018e80..431e1c6ba 100644 --- a/src/views/mp/user/index.vue +++ b/src/views/mp/user/index.vue @@ -11,7 +11,7 @@ label-width="68px" > - + - + + @@ -105,20 +106,24 @@ From c099f27f178dfc65c7ab40559edb5476fa72b99e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=82=93=E8=B6=85?= <2325690622@qq.com> Date: Fri, 21 Nov 2025 11:38:47 +0800 Subject: [PATCH 090/161] Add bottom padding to prevent scrollbar from hiding last row --- src/views/mall/product/spu/components/SkuList.vue | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/views/mall/product/spu/components/SkuList.vue b/src/views/mall/product/spu/components/SkuList.vue index 2ffb37d0b..c41da4b2c 100644 --- a/src/views/mall/product/spu/components/SkuList.vue +++ b/src/views/mall/product/spu/components/SkuList.vue @@ -574,3 +574,10 @@ const getSkuTableRef = () => { // 暴露出生成 sku 方法,给添加属性成功时调用 defineExpose({ generateTableData, validateSku, getSkuTableRef }) + From 224ea2977be8fd9af867316a911b1c569283e09d Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 22 Nov 2025 09:01:13 +0800 Subject: [PATCH 091/161] =?UTF-8?q?fix=EF=BC=9A=E3=80=90erp=E3=80=91receip?= =?UTF-8?q?t=20=E5=B0=86=20supplierList=20=E4=BF=AE=E5=A4=8D=E4=B8=BA=20cu?= =?UTF-8?q?stomerList?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/erp/finance/receipt/index.vue | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/views/erp/finance/receipt/index.vue b/src/views/erp/finance/receipt/index.vue index b96a33d5c..d754c4608 100644 --- a/src/views/erp/finance/receipt/index.vue +++ b/src/views/erp/finance/receipt/index.vue @@ -33,16 +33,16 @@ class="!w-240px" /> - + ([]) // 供应商列表 +const customerList = ref([]) // 客户列表 const userList = ref([]) // 用户列表 const accountList = ref([]) // 账户列表 @@ -384,8 +384,8 @@ const handleSelectionChange = (rows: FinanceReceiptVO[]) => { /** 初始化 **/ onMounted(async () => { await getList() - // 加载供应商、用户、账户 - supplierList.value = await SupplierApi.getSupplierSimpleList() + // 加载客户、用户、账户 + customerList.value = await CustomerApi.getCustomerSimpleList() userList.value = await UserApi.getSimpleUserList() accountList.value = await AccountApi.getAccountSimpleList() }) From 559a13defd89f58c5a2698befffa55a7e8e58901 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 22 Nov 2025 10:28:28 +0800 Subject: [PATCH 092/161] =?UTF-8?q?fix:=20=E7=AE=80=E5=8C=96=E5=89=8D?= =?UTF-8?q?=E7=AB=AF=E7=9A=84=E6=89=8B=E6=9C=BA=E6=A0=A1=E9=AA=8C=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=EF=BC=8C=E5=85=BC=E5=AE=B9=E6=9B=B4=E5=A4=9A=E5=8F=B7?= =?UTF-8?q?=E6=AE=B5=EF=BC=8C=E4=BE=8B=E5=A6=82=E8=AF=B4=20190?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/Profile/components/BasicInfo.vue | 2 +- src/views/mall/trade/delivery/pickUpStore/PickUpStoreForm.vue | 2 +- src/views/system/dept/DeptForm.vue | 4 +--- src/views/system/user/UserForm.vue | 2 +- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/views/Profile/components/BasicInfo.vue b/src/views/Profile/components/BasicInfo.vue index 1492664fc..094df400e 100644 --- a/src/views/Profile/components/BasicInfo.vue +++ b/src/views/Profile/components/BasicInfo.vue @@ -48,7 +48,7 @@ const rules = reactive({ mobile: [ { required: true, message: t('profile.rules.phone'), trigger: 'blur' }, { - pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, + pattern: /^1[3-9]\d{9}$/, message: t('profile.rules.truephone'), trigger: 'blur' } diff --git a/src/views/mall/trade/delivery/pickUpStore/PickUpStoreForm.vue b/src/views/mall/trade/delivery/pickUpStore/PickUpStoreForm.vue index 077ba6720..f026ff6d3 100644 --- a/src/views/mall/trade/delivery/pickUpStore/PickUpStoreForm.vue +++ b/src/views/mall/trade/delivery/pickUpStore/PickUpStoreForm.vue @@ -145,7 +145,7 @@ const formRules = reactive({ logo: [{ required: true, message: '门店 logo 不能为空', trigger: 'blur' }], phone: [ { required: true, message: '门店手机不能为空', trigger: 'blur' }, - { pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: '请输入正确的手机号码', trigger: 'blur' } + { pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号码', trigger: 'blur' } ], areaId: [{ required: true, message: '门店所在区域不能为空', trigger: 'blur' }], detailAddress: [{ required: true, message: '门店详细地址不能为空', trigger: 'blur' }], diff --git a/src/views/system/dept/DeptForm.vue b/src/views/system/dept/DeptForm.vue index c759ef38d..d6333f786 100644 --- a/src/views/system/dept/DeptForm.vue +++ b/src/views/system/dept/DeptForm.vue @@ -90,9 +90,7 @@ const formRules = reactive({ name: [{ required: true, message: '部门名称不能为空', trigger: 'blur' }], sort: [{ required: true, message: '显示排序不能为空', trigger: 'blur' }], email: [{ type: 'email', message: '请输入正确的邮箱地址', trigger: ['blur', 'change'] }], - phone: [ - { pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: '请输入正确的手机号码', trigger: 'blur' } - ], + phone: [{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号码', trigger: 'blur' }], status: [{ required: true, message: '状态不能为空', trigger: 'blur' }] }) const formRef = ref() // 表单 Ref diff --git a/src/views/system/user/UserForm.vue b/src/views/system/user/UserForm.vue index 630688a33..89498e034 100644 --- a/src/views/system/user/UserForm.vue +++ b/src/views/system/user/UserForm.vue @@ -140,7 +140,7 @@ const formRules = reactive({ ], mobile: [ { - pattern: /^(?:(?:\+|00)86)?1(?:3[\d]|4[5-79]|5[0-35-9]|6[5-7]|7[0-8]|8[\d]|9[189])\d{8}$/, + pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号码', trigger: 'blur' } From 5ebbc756c4509ec277b6c3edc974ec5f2a6305f5 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 22 Nov 2025 10:53:29 +0800 Subject: [PATCH 093/161] =?UTF-8?q?fix:=20=E3=80=90mall=E3=80=91=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E5=95=86=E5=9F=8E=E7=B3=BB=E7=BB=9F=E8=AE=A2=E5=8D=95?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E4=B8=AD=E8=A1=A8=E5=A4=B4=E6=9C=AA=E6=A0=B9?= =?UTF-8?q?=E6=8D=AE=E8=A1=A8=E4=BD=93=E8=87=AA=E9=80=82=E5=BA=94=E5=AE=BD?= =?UTF-8?q?=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../order/components/OrderTableColumn.vue | 58 ++++++++++++++++--- 1 file changed, 49 insertions(+), 9 deletions(-) diff --git a/src/views/mall/trade/order/components/OrderTableColumn.vue b/src/views/mall/trade/order/components/OrderTableColumn.vue index a2955941e..6e387cf03 100644 --- a/src/views/mall/trade/order/components/OrderTableColumn.vue +++ b/src/views/mall/trade/order/components/OrderTableColumn.vue @@ -40,7 +40,7 @@ From 50c7d4798436bde5a1221677c6bbf2ebcc7056c8 Mon Sep 17 00:00:00 2001 From: sinkingsoul <286447685@qq.com> Date: Fri, 31 Oct 2025 17:07:31 +0800 Subject: [PATCH 109/161] =?UTF-8?q?feat:=20=E5=88=A0=E9=99=A4http=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E7=BB=84=E4=BB=B6=E5=9B=BE=E6=A0=87=EF=BC=8C=E6=94=B9?= =?UTF-8?q?=E6=88=90=E6=9C=8D=E5=8A=A1=E4=BB=BB=E5=8A=A1=E7=9A=84=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E7=B1=BB=E5=9E=8B=E4=B8=8B=E6=8B=89=E6=A1=86=E4=B8=AD?= =?UTF-8?q?=E9=80=89=E6=8B=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../designer/plugins/palette/CustomPalette.js | 28 ------------------- .../plugins/palette/paletteProvider.js | 28 ------------------- 2 files changed, 56 deletions(-) diff --git a/src/components/bpmnProcessDesigner/package/designer/plugins/palette/CustomPalette.js b/src/components/bpmnProcessDesigner/package/designer/plugins/palette/CustomPalette.js index 8bdbcfca3..126838717 100644 --- a/src/components/bpmnProcessDesigner/package/designer/plugins/palette/CustomPalette.js +++ b/src/components/bpmnProcessDesigner/package/designer/plugins/palette/CustomPalette.js @@ -89,25 +89,6 @@ F.prototype.getPaletteEntries = function () { create.start(event, elementFactory.createParticipantShape()) } - function createHttpServiceTask(event) { - const httpTask = elementFactory.createShape({ - type: 'bpmn:ServiceTask' - }) - - const businessObject = httpTask.businessObject - - if (typeof businessObject.set === 'function') { - businessObject.set('flowable:type', 'http') - } else { - businessObject['flowable:type'] = 'http' - } - - if (!businessObject.name) { - businessObject.name = translate('HTTP Task') - } - - create.start(event, httpTask) - } assign(actions, { 'hand-tool': { @@ -197,15 +178,6 @@ F.prototype.getPaletteEntries = function () { 'bpmn-icon-service', translate('Create Service Task') ), - 'create.http-service-task': { - group: 'activity', - className: 'bpmn-icon-service', - title: translate('Create HTTP Task'), - action: { - dragstart: createHttpServiceTask, - click: createHttpServiceTask - } - }, 'create.data-object': createAction( 'bpmn:DataObjectReference', 'data-object', diff --git a/src/components/bpmnProcessDesigner/package/designer/plugins/palette/paletteProvider.js b/src/components/bpmnProcessDesigner/package/designer/plugins/palette/paletteProvider.js index e9cb2d31a..8a5858887 100644 --- a/src/components/bpmnProcessDesigner/package/designer/plugins/palette/paletteProvider.js +++ b/src/components/bpmnProcessDesigner/package/designer/plugins/palette/paletteProvider.js @@ -96,25 +96,6 @@ PaletteProvider.prototype.getPaletteEntries = function () { create.start(event, elementFactory.createParticipantShape()) } - function createHttpServiceTask(event) { - const httpTask = elementFactory.createShape({ - type: 'bpmn:ServiceTask' - }) - - const businessObject = httpTask.businessObject - - if (typeof businessObject.set === 'function') { - businessObject.set('flowable:type', 'http') - } else { - businessObject['flowable:type'] = 'http' - } - - if (!businessObject.name) { - businessObject.name = translate('HTTP Task') - } - - create.start(event, httpTask) - } assign(actions, { 'hand-tool': { @@ -197,15 +178,6 @@ PaletteProvider.prototype.getPaletteEntries = function () { 'bpmn-icon-service', translate('Create Service Task') ), - 'create.http-service-task': { - group: 'activity', - className: 'bpmn-icon-service', - title: translate('Create HTTP Task'), - action: { - dragstart: createHttpServiceTask, - click: createHttpServiceTask - } - }, 'create.data-object': createAction( 'bpmn:DataObjectReference', 'data-object', From d04a30fe41f0b6da0e79030c3019df5969b9eb46 Mon Sep 17 00:00:00 2001 From: zhanglc Date: Tue, 25 Nov 2025 11:31:47 +0800 Subject: [PATCH 110/161] typo --- .../package/penal/task/task-components/ServiceTask.vue | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/bpmnProcessDesigner/package/penal/task/task-components/ServiceTask.vue b/src/components/bpmnProcessDesigner/package/penal/task/task-components/ServiceTask.vue index cc4d2abff..37573c8c7 100644 --- a/src/components/bpmnProcessDesigner/package/penal/task/task-components/ServiceTask.vue +++ b/src/components/bpmnProcessDesigner/package/penal/task/task-components/ServiceTask.vue @@ -1,6 +1,6 @@ @@ -94,12 +100,15 @@ const HTTP_FIELD_NAMES = [ 'requestHeaders', 'disallowRedirects', 'ignoreException', + 'saveResponseParameters', + 'resultVariablePrefix', 'saveResponseParametersTransient', 'saveResponseVariableAsJson' ] const HTTP_BOOLEAN_FIELDS = new Set([ 'disallowRedirects', 'ignoreException', + 'saveResponseParameters', 'saveResponseParametersTransient', 'saveResponseVariableAsJson' ]) @@ -115,8 +124,10 @@ const DEFAULT_HTTP_FORM = { requestMethod: 'GET', requestUrl: '', requestHeaders: 'Content-Type: application/json', + resultVariablePrefix: '', disallowRedirects: false, ignoreException: false, + saveResponseParameters: false, saveResponseParametersTransient: false, saveResponseVariableAsJson: false } From c50e0dee8c76d6eea04b0121f1cd69dbf9037300 Mon Sep 17 00:00:00 2001 From: zhanglc Date: Tue, 18 Nov 2025 11:40:58 +0800 Subject: [PATCH 113/161] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8DHTTP=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E4=B8=AD=E8=AF=B7=E6=B1=82=E5=A4=B4=E4=B8=8D=E8=83=BD?= =?UTF-8?q?=E4=BD=BF=E7=94=A8EL=E8=A1=A8=E8=BE=BE=E5=BC=8F=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../task/task-components/ServiceTask.vue | 51 ++++++++++++++----- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/src/components/bpmnProcessDesigner/package/penal/task/task-components/ServiceTask.vue b/src/components/bpmnProcessDesigner/package/penal/task/task-components/ServiceTask.vue index eda9168e3..3c8e37e36 100644 --- a/src/components/bpmnProcessDesigner/package/penal/task/task-components/ServiceTask.vue +++ b/src/components/bpmnProcessDesigner/package/penal/task/task-components/ServiceTask.vue @@ -139,22 +139,32 @@ const httpInitializing = ref(false) const bpmnInstances = () => (window as any)?.bpmnInstances +// 判断字符串是否包含表达式 +const isExpression = (value: string): boolean => { + if (!value) return false + // 检测 ${...} 或 #{...} 格式的表达式 + return /\${[^}]+}/.test(value) || /#{[^}]+}/.test(value) +} + const collectHttpExtensionInfo = () => { const businessObject = bpmnElement.value?.businessObject const extensionElements = businessObject?.extensionElements const httpFields = new Map() + const httpFieldTypes = new Map() const otherExtensions: any[] = [] extensionElements?.values?.forEach((item: any) => { if (item?.$type === flowableFieldType && HTTP_FIELD_NAMES.includes(item.name)) { const value = item.string ?? item.stringValue ?? item.expression ?? '' + const fieldType = item.expression ? 'expression' : 'string' httpFields.set(item.name, value) + httpFieldTypes.set(item.name, fieldType) } else { otherExtensions.push(item) } }) - return { httpFields, otherExtensions } + return { httpFields, httpFieldTypes, otherExtensions } } const resetHttpDefaults = () => { @@ -168,7 +178,7 @@ const resetHttpDefaults = () => { const resetHttpForm = () => { httpInitializing.value = true const { httpFields } = collectHttpExtensionInfo() - const nextForm: Record = { ...DEFAULT_HTTP_FORM } + const nextForm = { ...DEFAULT_HTTP_FORM } HTTP_FIELD_NAMES.forEach((name) => { const stored = httpFields.get(name) @@ -228,7 +238,11 @@ const updateHttpExtensions = (force = false) => { return } - const { httpFields: existingFields, otherExtensions } = collectHttpExtensionInfo() + const { + httpFields: existingFields, + httpFieldTypes: existingTypes, + otherExtensions + } = collectHttpExtensionInfo() const desiredEntries: [string, string][] = [] HTTP_FIELD_NAMES.forEach((name) => { @@ -246,21 +260,32 @@ const updateHttpExtensions = (force = false) => { desiredEntries.push([name, persisted]) }) - if ( - !force && - desiredEntries.length === existingFields.size && - desiredEntries.every(([name, value]) => existingFields.get(name) === value) - ) { - return + // 检查是否有变化:不仅比较值,还要比较字段类型(string vs expression) + if (!force && desiredEntries.length === existingFields.size) { + let noChange = true + for (const [name, value] of desiredEntries) { + const existingValue = existingFields.get(name) + const existingType = existingTypes.get(name) + const currentType = isExpression(value) ? 'expression' : 'string' + if (existingValue !== value || existingType !== currentType) { + noChange = false + break + } + } + if (noChange) { + return + } } const moddle = bpmnInstances().moddle - const httpFieldElements = desiredEntries.map(([name, value]) => - moddle.create(flowableFieldType, { + const httpFieldElements = desiredEntries.map(([name, value]) => { + // 根据值是否包含表达式来决定使用 string 还是 expression 属性 + const isExpr = isExpression(value) + return moddle.create(flowableFieldType, { name, - string: value + ...(isExpr ? { expression: value } : { string: value }) }) - ) + }) updateElementExtensions(bpmnElement.value, [...otherExtensions, ...httpFieldElements]) } From d66cd5d209c52ab565b53cd3806028a1a2bd7b24 Mon Sep 17 00:00:00 2001 From: zhanglc Date: Tue, 18 Nov 2025 14:52:42 +0800 Subject: [PATCH 114/161] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96HTTP=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E8=AF=B7=E6=B1=82=E5=A4=B4=E8=BE=93=E5=85=A5=EF=BC=8C?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E9=94=AE=E5=80=BC=E5=AF=B9=E5=8D=95=E7=8B=AC?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E6=A1=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../task/task-components/HttpHeaderEditor.vue | 178 ++++++++++++++++++ .../task/task-components/ServiceTask.vue | 55 ++++-- 2 files changed, 219 insertions(+), 14 deletions(-) create mode 100644 src/components/bpmnProcessDesigner/package/penal/task/task-components/HttpHeaderEditor.vue diff --git a/src/components/bpmnProcessDesigner/package/penal/task/task-components/HttpHeaderEditor.vue b/src/components/bpmnProcessDesigner/package/penal/task/task-components/HttpHeaderEditor.vue new file mode 100644 index 000000000..5d0a13349 --- /dev/null +++ b/src/components/bpmnProcessDesigner/package/penal/task/task-components/HttpHeaderEditor.vue @@ -0,0 +1,178 @@ + + + + + diff --git a/src/components/bpmnProcessDesigner/package/penal/task/task-components/ServiceTask.vue b/src/components/bpmnProcessDesigner/package/penal/task/task-components/ServiceTask.vue index 3c8e37e36..642c3c288 100644 --- a/src/components/bpmnProcessDesigner/package/penal/task/task-components/ServiceTask.vue +++ b/src/components/bpmnProcessDesigner/package/penal/task/task-components/ServiceTask.vue @@ -43,22 +43,34 @@ - - - + + + - +
+ + + 编辑 + +
@@ -66,24 +78,34 @@ - + - + - + - + + + + diff --git a/src/views/mp/messageTemplate/index.vue b/src/views/mp/messageTemplate/index.vue new file mode 100644 index 000000000..1bac3f7e7 --- /dev/null +++ b/src/views/mp/messageTemplate/index.vue @@ -0,0 +1,142 @@ + + + diff --git a/src/views/mp/template/MsgTemplate.vue b/src/views/mp/template/MsgTemplate.vue deleted file mode 100644 index da6447599..000000000 --- a/src/views/mp/template/MsgTemplate.vue +++ /dev/null @@ -1,333 +0,0 @@ - - - diff --git a/src/views/mp/template/MsgTemplateForm.vue b/src/views/mp/template/MsgTemplateForm.vue deleted file mode 100644 index 77d31830a..000000000 --- a/src/views/mp/template/MsgTemplateForm.vue +++ /dev/null @@ -1,335 +0,0 @@ - - - - - diff --git a/src/views/mp/template/MsgTemplateLog.vue b/src/views/mp/template/MsgTemplateLog.vue deleted file mode 100644 index e3fd9234c..000000000 --- a/src/views/mp/template/MsgTemplateLog.vue +++ /dev/null @@ -1,214 +0,0 @@ - - - diff --git a/src/views/mp/template/MsgTemplateLogForm.vue b/src/views/mp/template/MsgTemplateLogForm.vue deleted file mode 100644 index 1266806f5..000000000 --- a/src/views/mp/template/MsgTemplateLogForm.vue +++ /dev/null @@ -1,144 +0,0 @@ - - \ No newline at end of file diff --git a/src/views/mp/template/MsgTemplateSend.vue b/src/views/mp/template/MsgTemplateSend.vue deleted file mode 100644 index 286be80e9..000000000 --- a/src/views/mp/template/MsgTemplateSend.vue +++ /dev/null @@ -1,82 +0,0 @@ - - - - - From 521911ca7e5678dd9f7ad5e1f1940de404dfba3b Mon Sep 17 00:00:00 2001 From: YunaiV Date: Wed, 26 Nov 2025 18:56:46 +0800 Subject: [PATCH 126/161] =?UTF-8?q?feat=EF=BC=9A=E3=80=90mp=E3=80=91?= =?UTF-8?q?=E5=AE=8C=E5=96=84=E2=80=9C=E6=A8=A1=E7=89=88=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E2=80=9D=E7=9A=84=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 14bb23a2e..295946d97 100644 --- a/README.md +++ b/README.md @@ -200,18 +200,19 @@ ### 微信公众号 -| | 功能 | 描述 | -|-----|--------|-------------------------------| -| 🚀 | 账号管理 | 配置接入的微信公众号,可支持多个公众号 | -| 🚀 | 数据统计 | 统计公众号的用户增减、累计用户、消息概况、接口分析等数据 | -| 🚀 | 粉丝管理 | 查看已关注、取关的粉丝列表,可对粉丝进行同步、打标签等操作 | -| 🚀 | 消息管理 | 查看粉丝发送的消息列表,可主动回复粉丝消息 | -| 🚀 | 自动回复 | 自动回复粉丝发送的消息,支持关注回复、消息回复、关键字回复 | -| 🚀 | 标签管理 | 对公众号的标签进行创建、查询、修改、删除等操作 | -| 🚀 | 菜单管理 | 自定义公众号的菜单,也可以从公众号同步菜单 | -| 🚀 | 素材管理 | 管理公众号的图片、语音、视频等素材,支持在线播放语音、视频 | -| 🚀 | 图文草稿箱 | 新增常用的图文素材到草稿箱,可发布到公众号 | -| 🚀 | 图文发表记录 | 查看已发布成功的图文素材,支持删除操作 | +| | 功能 | 描述 | +|----|--------|-------------------------------| +| 🚀 | 账号管理 | 配置接入的微信公众号,可支持多个公众号 | +| 🚀 | 数据统计 | 统计公众号的用户增减、累计用户、消息概况、接口分析等数据 | +| 🚀 | 粉丝管理 | 查看已关注、取关的粉丝列表,可对粉丝进行同步、打标签等操作 | +| 🚀 | 消息管理 | 查看粉丝发送的消息列表,可主动回复粉丝消息 | +| 🚀 | 模版消息 | 配置和发送模版消息,用于向粉丝推送通知类消息 | +| 🚀 | 自动回复 | 自动回复粉丝发送的消息,支持关注回复、消息回复、关键字回复 | +| 🚀 | 标签管理 | 对公众号的标签进行创建、查询、修改、删除等操作 | +| 🚀 | 菜单管理 | 自定义公众号的菜单,也可以从公众号同步菜单 | +| 🚀 | 素材管理 | 管理公众号的图片、语音、视频等素材,支持在线播放语音、视频 | +| 🚀 | 图文草稿箱 | 新增常用的图文素材到草稿箱,可发布到公众号 | +| 🚀 | 图文发表记录 | 查看已发布成功的图文素材,支持删除操作 | ### 商城系统 From 01a804631e39f0882d9aa39737bc5d335422d133 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Wed, 26 Nov 2025 19:04:47 +0800 Subject: [PATCH 127/161] =?UTF-8?q?feat=EF=BC=9A=E3=80=90mp=E3=80=91?= =?UTF-8?q?=E5=AE=8C=E5=96=84=E2=80=9C=E6=A8=A1=E7=89=88=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E2=80=9D=E7=9A=84=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/mp/messageTemplate/index.vue | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/views/mp/messageTemplate/index.vue b/src/views/mp/messageTemplate/index.vue index 1bac3f7e7..d163db7b7 100644 --- a/src/views/mp/messageTemplate/index.vue +++ b/src/views/mp/messageTemplate/index.vue @@ -1,4 +1,6 @@ From 3a6454cfc170158a7034654cd7d84aed0e6a7947 Mon Sep 17 00:00:00 2001 From: zhanglc Date: Tue, 9 Dec 2025 21:50:54 +0800 Subject: [PATCH 141/161] =?UTF-8?q?feat:=20=E3=80=90bpm=E3=80=91bpmn?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=E5=99=A8:=20=E4=B8=9A=E5=8A=A1=E8=A1=A8?= =?UTF-8?q?=E5=8D=95=E6=B5=81=E7=A8=8B=E6=B7=BB=E5=8A=A0=E9=87=8D=E6=96=B0?= =?UTF-8?q?=E5=8F=91=E8=B5=B7=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/bpm/model/index.ts | 1 + src/views/bpm/oa/leave/create.vue | 26 +++++++++++++++++++++++++ src/views/bpm/oa/leave/index.vue | 19 ++++++++++++++++++ src/views/bpm/processInstance/index.vue | 21 ++++++++++++-------- 4 files changed, 59 insertions(+), 8 deletions(-) diff --git a/src/api/bpm/model/index.ts b/src/api/bpm/model/index.ts index 63b6af6ad..6d2b4d224 100644 --- a/src/api/bpm/model/index.ts +++ b/src/api/bpm/model/index.ts @@ -6,6 +6,7 @@ export type ProcessDefinitionVO = { deploymentTIme: string suspensionState: number formType?: number + formCustomCreatePath?: string } export type ModelVO = { diff --git a/src/views/bpm/oa/leave/create.vue b/src/views/bpm/oa/leave/create.vue index cf4a13e2a..4c7b336e4 100644 --- a/src/views/bpm/oa/leave/create.vue +++ b/src/views/bpm/oa/leave/create.vue @@ -79,6 +79,7 @@ defineOptions({ name: 'BpmOALeaveCreate' }) const message = useMessage() // 消息弹窗 const { delView } = useTagsViewStore() // 视图操作 const { push, currentRoute } = useRouter() // 路由 +const { query } = useRoute() // 查询参数 const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用 const formData = ref({ @@ -190,6 +191,26 @@ const daysDifference = () => { return Math.floor(diffTime / oneDay) } +/** 获取请假数据,用于重新发起时自动填充 */ +const getLeaveData = async (id: number) => { + try { + formLoading.value = true + const data = await LeaveApi.getLeave(id) + if (!data) { + message.error('重新发起请假失败,原因:请假数据不存在') + return + } + formData.value = { + type: data.type, + reason: data.reason, + startTime: data.startTime, + endTime: data.endTime + } + } finally { + formLoading.value = false + } +} + /** 初始化 */ onMounted(async () => { // TODO @小北:这里可以简化,统一通过 getApprovalDetail 处理么? @@ -205,6 +226,11 @@ onMounted(async () => { processDefinitionId.value = processDefinitionDetail.id startUserSelectTasks.value = processDefinitionDetail.startUserSelectTasks + // 如果有业务编号,说明是重新发起,需要加载原有数据 + if (query.id) { + await getLeaveData(Number(query.id)) + } + // 审批相关:加载最新的审批详情,主要用于节点预测 await getApprovalDetail() }) diff --git a/src/views/bpm/oa/leave/index.vue b/src/views/bpm/oa/leave/index.vue index 1d1d42740..9fab923a0 100644 --- a/src/views/bpm/oa/leave/index.vue +++ b/src/views/bpm/oa/leave/index.vue @@ -140,6 +140,15 @@ > 取消 + + 重新发起 + @@ -206,6 +215,16 @@ const handleCreate = () => { router.push({ name: 'OALeaveCreate' }) } +/** 重新发起操作 */ +const handleReCreate = (row: LeaveApi.LeaveVO) => { + router.push({ + name: 'OALeaveCreate', + query: { + id: row.id + } + }) +} + /** 详情操作 */ const handleDetail = (row: LeaveApi.LeaveVO) => { router.push({ diff --git a/src/views/bpm/processInstance/index.vue b/src/views/bpm/processInstance/index.vue index d6fc83d38..9d7d6cc72 100644 --- a/src/views/bpm/processInstance/index.vue +++ b/src/views/bpm/processInstance/index.vue @@ -275,21 +275,26 @@ const resetQuery = () => { /** 发起流程操作 **/ const handleCreate = async (row?: ProcessInstanceVO) => { - // 如果是【业务表单】,不支持重新发起 if (row?.id) { const processDefinitionDetail = await DefinitionApi.getProcessDefinition( row.processDefinitionId ) + //如果是【业务表单】,跳转到对应的发起界面 if (processDefinitionDetail.formType === 20) { - message.error('重新发起流程失败,原因:该流程使用业务表单,不支持重新发起') - return + await router.push({ + path: processDefinitionDetail.formCustomCreatePath, + query: { + id: row.businessKey + } + }) + } else if (processDefinitionDetail.formType === 10) { + //如果是【流程表单】,跳转到流程发起界面 + await router.push({ + name: 'BpmProcessInstanceCreate', + query: { processInstanceId: row.id } + }) } } - // 跳转发起流程界面 - await router.push({ - name: 'BpmProcessInstanceCreate', - query: { processInstanceId: row?.id } - }) } /** 查看详情 */ From 8f5f2e96b391ad5040728d2b5641bce613645397 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=85=89=E5=B8=86?= <1048766504@qq.com> Date: Fri, 12 Dec 2025 08:47:29 +0000 Subject: [PATCH 142/161] =?UTF-8?q?=E3=80=90=E5=8A=9F=E8=83=BD=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E3=80=91=E6=96=87=E4=BB=B6=E5=88=97=E8=A1=A8:=20?= =?UTF-8?q?=E5=A4=8D=E5=88=B6=E9=93=BE=E6=8E=A5=E5=8A=9F=E8=83=BD=E5=9C=A8?= =?UTF-8?q?=E9=83=A8=E5=88=86=E6=B5=8F=E8=A7=88=E5=99=A8=E7=8E=AF=E5=A2=83?= =?UTF-8?q?=E4=B8=8B=E6=8A=A5=E9=94=99=E7=9A=84=E9=97=AE=E9=A2=98=20?= =?UTF-8?q?=E5=9C=A8=20navigator.clipboard=20=E4=B8=BA=20undefined?= =?UTF-8?q?=EF=BC=8C=E5=AF=BC=E8=87=B4=E6=97=A0=E6=B3=95=E8=AF=BB=E5=8F=96?= =?UTF-8?q?=20writeText=20=E6=96=B9=E6=B3=95=EF=BC=8C=E6=B5=8F=E8=A7=88?= =?UTF-8?q?=E5=99=A8=E6=8A=9B=E5=87=BA=E5=BC=82=E5=B8=B8=EF=BC=9A=20Uncaug?= =?UTF-8?q?ht=20TypeError:=20Cannot=20read=20properties=20of=20undefined?= =?UTF-8?q?=20(reading=20'writeText')?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 光帆 <1048766504@qq.com> --- src/views/infra/file/index.vue | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/views/infra/file/index.vue b/src/views/infra/file/index.vue index 901139180..a0c9e258b 100644 --- a/src/views/infra/file/index.vue +++ b/src/views/infra/file/index.vue @@ -187,9 +187,29 @@ const openForm = () => { /** 复制到剪贴板方法 */ const copyToClipboard = (text: string) => { - navigator.clipboard.writeText(text).then(() => { - message.success('复制成功') - }) + if (navigator.clipboard && window.isSecureContext) { + navigator.clipboard + .writeText(text) + .then(() => { + message.success('复制成功') + }) + .catch(() => { + message.error('复制失败') + }) + } else { + // 兼容不支持 clipboard 的情况 + try { + const textarea = document.createElement('textarea') + textarea.value = text + document.body.appendChild(textarea) + textarea.select() + document.execCommand('copy') + document.body.removeChild(textarea) + message.success('复制成功') + } catch (error) { + message.error('复制失败') + } + } } /** 删除按钮操作 */ From 19f38c4a9ea29a36e22a48ae79123201cf91c8e2 Mon Sep 17 00:00:00 2001 From: z95813 <61101985+MurphyZX@users.noreply.github.com> Date: Mon, 15 Dec 2025 14:27:49 +0800 Subject: [PATCH 143/161] =?UTF-8?q?=E6=89=8B=E7=BB=AD=E8=B4=B9=E6=AF=94?= =?UTF-8?q?=E4=BE=8B=E4=B8=8D=E9=9C=80=E8=A6=81=E9=99=A4100?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/pay/order/OrderDetail.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/pay/order/OrderDetail.vue b/src/views/pay/order/OrderDetail.vue index 895bc1601..90d4ccbce 100644 --- a/src/views/pay/order/OrderDetail.vue +++ b/src/views/pay/order/OrderDetail.vue @@ -21,7 +21,7 @@ - {{ (detailData.channelFeeRate / 100.0).toFixed(2) }}% + {{ detailData.channelFeeRate.toFixed(2) }}% {{ formatDate(detailData.successTime) }} From b261ecf90f54997e92d135a7249fcecb83abaa0f Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 20 Dec 2025 09:23:41 +0800 Subject: [PATCH 144/161] =?UTF-8?q?fix=EF=BC=9A=E3=80=90system=E3=80=91?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E6=97=A5=E5=BF=97=E7=9A=84=E2=80=9C=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E7=B1=BB=E5=9E=8B=E2=80=9D=E6=94=B9=E4=B8=BA=E2=80=9C?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E7=B1=BB=E5=9E=8B=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/system/loginlog/LoginLogDetail.vue | 2 +- src/views/system/loginlog/index.vue | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/views/system/loginlog/LoginLogDetail.vue b/src/views/system/loginlog/LoginLogDetail.vue index ff494534a..c6deb11de 100644 --- a/src/views/system/loginlog/LoginLogDetail.vue +++ b/src/views/system/loginlog/LoginLogDetail.vue @@ -4,7 +4,7 @@ {{ detailData.id }} - + diff --git a/src/views/system/loginlog/index.vue b/src/views/system/loginlog/index.vue index 2e269ffb9..a22ebc02a 100644 --- a/src/views/system/loginlog/index.vue +++ b/src/views/system/loginlog/index.vue @@ -59,7 +59,7 @@ - + From fe0364c3e246b7b5887eb665e89c6c766da0b3b1 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 20 Dec 2025 10:16:03 +0800 Subject: [PATCH 145/161] =?UTF-8?q?fix:=20=E3=80=90mall=E3=80=91=E9=97=A8?= =?UTF-8?q?=E5=BA=97=E6=8F=90=E6=8F=90=E4=B8=AD=EF=BC=8C=E7=A7=BB=E9=99=A4?= =?UTF-8?q?=E5=91=98=E5=B7=A5=E9=80=89=E6=8B=A9=E8=A1=A8=E5=8D=95=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E7=9A=84=20roleId=20=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../delivery/pickUpStore/components/StoreStaffTableSelect.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/src/views/mall/trade/delivery/pickUpStore/components/StoreStaffTableSelect.vue b/src/views/mall/trade/delivery/pickUpStore/components/StoreStaffTableSelect.vue index 4256fbc28..c5acda31e 100644 --- a/src/views/mall/trade/delivery/pickUpStore/components/StoreStaffTableSelect.vue +++ b/src/views/mall/trade/delivery/pickUpStore/components/StoreStaffTableSelect.vue @@ -160,7 +160,6 @@ const queryParams = reactive({ mobile: undefined, status: undefined, deptId: undefined, - roleId: 5, createTime: [] }) const queryFormRef = ref() // 搜索的表单 From d492aeb56d004884b18980c7a87fca4cac018648 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B0=B4=E4=BA=BA?= <417693680@qq.com> Date: Sat, 20 Dec 2025 03:22:34 +0000 Subject: [PATCH 146/161] =?UTF-8?q?update=20src/views/bpm/processInstance/?= =?UTF-8?q?detail/ProcessInstanceOperationButton.vue.=20=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E5=B0=8F=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 水人 <417693680@qq.com> --- .../processInstance/detail/ProcessInstanceOperationButton.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/bpm/processInstance/detail/ProcessInstanceOperationButton.vue b/src/views/bpm/processInstance/detail/ProcessInstanceOperationButton.vue index 1b7d5c73d..53b10bdfc 100644 --- a/src/views/bpm/processInstance/detail/ProcessInstanceOperationButton.vue +++ b/src/views/bpm/processInstance/detail/ProcessInstanceOperationButton.vue @@ -582,7 +582,7 @@ const approveReasonForm = reactive({ const approveReasonRule = computed(() => { return { reason: [ - { required: reasonRequire.value, message: nodeTypeName + '意见不能为空', trigger: 'blur' } + { required: reasonRequire.value, message: nodeTypeName.value + '意见不能为空', trigger: 'blur' } ], signPicUrl: [{ required: true, message: '签名不能为空', trigger: 'change' }], nextAssignees: [{ required: true, message: '审批人不能为空', trigger: 'blur' }] From 932255bd140144cd3d2ae8c06f0ea2bd18458f2c Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 20 Dec 2025 20:48:34 +0800 Subject: [PATCH 147/161] =?UTF-8?q?fix=EF=BC=9A=E3=80=90system=E3=80=91?= =?UTF-8?q?=E9=82=AE=E7=AE=B1=E7=A7=BB=E9=99=A4=E6=97=A0=E7=94=A8=E7=9A=84?= =?UTF-8?q?=20remark=20=E5=AD=97=E6=AE=B5=E5=8F=8A=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E8=A1=A8=E5=8D=95=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/system/mail/template/index.ts | 4 +--- src/views/system/mail/template/MailTemplateForm.vue | 11 +++-------- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/src/api/system/mail/template/index.ts b/src/api/system/mail/template/index.ts index 6e1d083f2..d340f8a24 100644 --- a/src/api/system/mail/template/index.ts +++ b/src/api/system/mail/template/index.ts @@ -1,16 +1,14 @@ import request from '@/config/axios' export interface MailTemplateVO { - id: number + id?: number name: string code: string accountId: number nickname: string title: string content: string - params: string status: number - remark: string } export interface MailSendReqVO { diff --git a/src/views/system/mail/template/MailTemplateForm.vue b/src/views/system/mail/template/MailTemplateForm.vue index faf2020b4..cae5f9d53 100644 --- a/src/views/system/mail/template/MailTemplateForm.vue +++ b/src/views/system/mail/template/MailTemplateForm.vue @@ -43,9 +43,6 @@ - - - From 46602fec26bb2bf10ba852ad01f4f28bdaf6040b Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 27 Dec 2025 11:39:24 +0800 Subject: [PATCH 150/161] =?UTF-8?q?feat=EF=BC=9A=E3=80=90bpm=E3=80=91?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=B8=9A=E5=8A=A1=E8=A1=A8=E5=8D=95=E6=B5=81?= =?UTF-8?q?=E7=A8=8B=E6=B7=BB=E5=8A=A0=E9=87=8D=E6=96=B0=E5=8F=91=E8=B5=B7?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/bpm/oa/leave/create.vue | 4 ++-- src/views/bpm/processInstance/index.vue | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/views/bpm/oa/leave/create.vue b/src/views/bpm/oa/leave/create.vue index 4c7b336e4..b64f4ca7b 100644 --- a/src/views/bpm/oa/leave/create.vue +++ b/src/views/bpm/oa/leave/create.vue @@ -192,7 +192,7 @@ const daysDifference = () => { } /** 获取请假数据,用于重新发起时自动填充 */ -const getLeaveData = async (id: number) => { +const getDetail = async (id: number) => { try { formLoading.value = true const data = await LeaveApi.getLeave(id) @@ -228,7 +228,7 @@ onMounted(async () => { // 如果有业务编号,说明是重新发起,需要加载原有数据 if (query.id) { - await getLeaveData(Number(query.id)) + await getDetail(Number(query.id)) } // 审批相关:加载最新的审批详情,主要用于节点预测 diff --git a/src/views/bpm/processInstance/index.vue b/src/views/bpm/processInstance/index.vue index 9d7d6cc72..1a8ef8900 100644 --- a/src/views/bpm/processInstance/index.vue +++ b/src/views/bpm/processInstance/index.vue @@ -279,7 +279,7 @@ const handleCreate = async (row?: ProcessInstanceVO) => { const processDefinitionDetail = await DefinitionApi.getProcessDefinition( row.processDefinitionId ) - //如果是【业务表单】,跳转到对应的发起界面 + // 如果是【业务表单】,跳转到对应的发起界面 if (processDefinitionDetail.formType === 20) { await router.push({ path: processDefinitionDetail.formCustomCreatePath, From 678f3c60cf37fc23716b05e94194b6efe04bd5fd Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 28 Dec 2025 11:09:56 +0800 Subject: [PATCH 151/161] =?UTF-8?q?(=E3=80=83'=E2=96=BD'=E3=80=83)=20v2025?= =?UTF-8?q?.12=20=E5=8F=91=E5=B8=83=EF=BC=9A=E6=9E=81=E5=A4=A7=E6=9E=81?= =?UTF-8?q?=E5=A4=A7=E5=AE=8C=E5=96=84=20vben5=20=E7=9A=84=20antd=E3=80=81?= =?UTF-8?q?vben=20=E7=89=88=E6=9C=AC=E7=9A=84=E5=8A=9F=E8=83=BD=EF=BC=8C?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=20admin=20uniapp=20vue3=20=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index daad2678a..1a12256e9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "yudao-ui-admin-vue3", - "version": "2025.11-snapshot", + "version": "2025.12-snapshot", "description": "基于vue3、vite4、element-plus、typesScript", "author": "xingyu", "private": false, From 2a9d07f514f45227c7ba1241322880ab3c89c8f0 Mon Sep 17 00:00:00 2001 From: preschooler Date: Sun, 28 Dec 2025 20:40:06 +0800 Subject: [PATCH 152/161] =?UTF-8?q?=F0=9F=90=9E=20fix:=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E5=AF=8C=E6=96=87=E6=9C=AC=E7=BC=96=E8=BE=91=E5=99=A8?= =?UTF-8?q?=E4=B8=8D=E8=83=BD=E4=B8=8A=E4=BC=A0=E5=90=8C=E4=B8=80=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E9=97=AE=E9=A2=98=E3=80=81=E6=B7=BB=E5=8A=A0=E5=AD=98?= =?UTF-8?q?=E5=82=A8=E7=9B=AE=E5=BD=95=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Editor/src/Editor.vue | 35 ++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/src/components/Editor/src/Editor.vue b/src/components/Editor/src/Editor.vue index 36fe1650f..30146be37 100644 --- a/src/components/Editor/src/Editor.vue +++ b/src/components/Editor/src/Editor.vue @@ -28,7 +28,8 @@ const props = defineProps({ default: () => undefined }, readonly: propTypes.bool.def(false), - modelValue: propTypes.string.def('') + modelValue: propTypes.string.def(''), + directory: propTypes.string.def('editor-default') }) const emit = defineEmits(['change', 'update:modelValue']) @@ -115,9 +116,9 @@ const editorConfig = computed((): IEditorConfig => { ['uploadImage']: { server: getUploadUrl(), // 单个文件的最大体积限制,默认为 2M - maxFileSize: 5 * 1024 * 1024, + maxFileSize: 10 * 1024 * 1024, // 最多可上传几个文件,默认为 100 - maxNumberOfFiles: 10, + maxNumberOfFiles: 100, // 选择文件时的类型限制,默认为 ['image/*'] 。如不想限制,则设置为 [] allowedFileTypes: ['image/*'], @@ -133,6 +134,19 @@ const editorConfig = computed((): IEditorConfig => { // form-data fieldName,后端接口参数名称,默认值wangeditor-uploaded-image fieldName: 'file', + // 附加参数 + meta: { + directory: `${props.directory}-image` + }, + metaWithUrl: false, + + // uppy 配置项 + uppyConfig: { + onBeforeFileAdded: (newFile: any) => { + newFile.id = `${newFile.id}-${Date.now()}` + return newFile + } + }, // 上传之前触发 onBeforeUpload(file: File) { @@ -163,7 +177,7 @@ const editorConfig = computed((): IEditorConfig => { ['uploadVideo']: { server: getUploadUrl(), // 单个文件的最大体积限制,默认为 10M - maxFileSize: 10 * 1024 * 1024, + maxFileSize: 1024 * 1024 * 1024, // 最多可上传几个文件,默认为 100 maxNumberOfFiles: 10, // 选择文件时的类型限制,默认为 ['video/*'] 。如不想限制,则设置为 [] @@ -181,6 +195,19 @@ const editorConfig = computed((): IEditorConfig => { // form-data fieldName,后端接口参数名称,默认值wangeditor-uploaded-image fieldName: 'file', + // 附加参数 + meta: { + directory: `${props.directory}-video` + }, + metaWithUrl: false, + + // uppy 配置项 + uppyConfig: { + onBeforeFileAdded: (newFile: any) => { + newFile.id = `${newFile.id}-${Date.now()}` + return newFile + } + }, // 上传之前触发 onBeforeUpload(file: File) { From 9af4cad55246c416f4b40adb0e5a5e120e97ba50 Mon Sep 17 00:00:00 2001 From: preschooler Date: Sun, 28 Dec 2025 21:15:44 +0800 Subject: [PATCH 153/161] =?UTF-8?q?=F0=9F=90=9E=20fix:=20=E7=A1=AE?= =?UTF-8?q?=E4=BF=9D=E6=96=87=E4=BB=B6=E4=B8=8A=E4=BC=A0=E6=97=B6=E5=AD=98?= =?UTF-8?q?=E5=9C=A8=20Content-Type=EF=BC=8C=E5=90=A6=E5=88=99=E4=BC=9A?= =?UTF-8?q?=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/UploadFile/src/useUpload.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/components/UploadFile/src/useUpload.ts b/src/components/UploadFile/src/useUpload.ts index 8f316eb59..dddd15961 100644 --- a/src/components/UploadFile/src/useUpload.ts +++ b/src/components/UploadFile/src/useUpload.ts @@ -1,5 +1,9 @@ import * as FileApi from '@/api/infra/file' -import { UploadRawFile, UploadRequestOptions, UploadProgressEvent } from 'element-plus/es/components/upload/src/upload' +import { + UploadRawFile, + UploadRequestOptions, + UploadProgressEvent +} from 'element-plus/es/components/upload/src/upload' import axios, { AxiosProgressEvent } from 'axios' /** @@ -19,7 +23,7 @@ export const useUpload = (directory?: string) => { // 文件上传进度监听 const uploadProgressHandler = (evt: AxiosProgressEvent) => { const upEvt: UploadProgressEvent = Object.assign(evt.event) - upEvt.percent = evt.progress ? (evt.progress * 100) : 0 + upEvt.percent = evt.progress ? evt.progress * 100 : 0 options.onProgress(upEvt) // 触发 el-upload 的 on-progress } @@ -33,7 +37,7 @@ export const useUpload = (directory?: string) => { return axios .put(presignedInfo.uploadUrl, options.file, { headers: { - 'Content-Type': options.file.type + 'Content-Type': options.file.type || 'application/octet-stream' }, onUploadProgress: uploadProgressHandler }) @@ -80,7 +84,7 @@ function createFile(vo: FileApi.FilePresignedUrlRespVO, file: UploadRawFile, fil url: vo.url, path: vo.path, name: fileName, - type: file.type, + type: file.type || 'application/octet-stream', size: file.size } FileApi.createFile(fileVo) From ee7c73b4751f341a3c91388f781a227e83fe0d82 Mon Sep 17 00:00:00 2001 From: preschooler Date: Sun, 28 Dec 2025 21:18:03 +0800 Subject: [PATCH 154/161] =?UTF-8?q?=F0=9F=8E=88=20perf:=20=E6=96=B0?= =?UTF-8?q?=E5=BC=80=E6=A0=87=E7=AD=BE=E6=97=B6=E3=80=81=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=E6=A0=87=E7=AD=BE=E6=97=B6=EF=BC=8C=E6=BB=9A=E5=8A=A8=E6=9D=A1?= =?UTF-8?q?=E5=9B=9E=E5=88=B0=E9=A1=B6=E9=83=A8=EF=BC=8C=E5=90=A6=E5=88=99?= =?UTF-8?q?=E4=BC=9A=E4=BF=9D=E7=95=99=E4=B8=8A=E6=AC=A1=E6=A0=87=E7=AD=BE?= =?UTF-8?q?=E7=9A=84=E6=BB=9A=E5=8A=A8=E4=BD=8D=E7=BD=AE=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/router/index.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/router/index.ts b/src/router/index.ts index e80dae08e..4e861c6c5 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -8,7 +8,15 @@ const router = createRouter({ history: createWebHistory(import.meta.env.VITE_BASE_PATH), // createWebHashHistory URL带#,createWebHistory URL不带# strict: true, routes: remainingRouter as RouteRecordRaw[], - scrollBehavior: () => ({ left: 0, top: 0 }) + scrollBehavior: () => { + // 新开标签时、返回标签时,滚动条回到顶部,否则会保留上次标签的滚动位置。 + const scrollbarWrap = document.querySelector('.v-layout-content-scrollbar .el-scrollbar__wrap') + if (scrollbarWrap) { + // scrollbarWrap.scrollTo({ left: 0, top: 0, behavior: 'auto' }) + scrollbarWrap.scrollTop = 0 + } + return { left: 0, top: 0 } + } }) export const resetRouter = (): void => { From 394c94b67c07fb3065ccef22378e2b5c1042118d Mon Sep 17 00:00:00 2001 From: preschooler Date: Sun, 28 Dec 2025 22:14:42 +0800 Subject: [PATCH 155/161] =?UTF-8?q?=F0=9F=8E=88=20perf:=20=E4=BC=98?= =?UTF-8?q?=E5=8C=96=20copy=20=E5=85=BC=E5=AE=B9=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/MarkdownView/index.vue | 2 +- src/layout/components/Setting/src/Setting.vue | 3 +- .../index/components/message/MessageList.vue | 2 +- src/views/ai/write/index/components/Right.vue | 2 +- src/views/infra/build/index.vue | 2 +- src/views/infra/codegen/PreviewCode.vue | 2 +- src/views/infra/file/index.vue | 33 ++++++------------- .../device/detail/DeviceDetailsHeader.vue | 15 ++++++--- .../device/detail/DeviceDetailsInfo.vue | 15 ++++++--- .../product/detail/ProductDetailsHeader.vue | 15 ++++++--- 10 files changed, 47 insertions(+), 44 deletions(-) diff --git a/src/components/MarkdownView/index.vue b/src/components/MarkdownView/index.vue index 74764d592..86fc93917 100644 --- a/src/components/MarkdownView/index.vue +++ b/src/components/MarkdownView/index.vue @@ -17,7 +17,7 @@ const props = defineProps({ }) const message = useMessage() // 消息弹窗 -const { copy } = useClipboard() // 初始化 copy 到粘贴板 +const { copy } = useClipboard({ legacy: true }) // 初始化 copy 到粘贴板 const contentRef = ref() const md = new MarkdownIt({ diff --git a/src/layout/components/Setting/src/Setting.vue b/src/layout/components/Setting/src/Setting.vue index 2973674ba..92ecf4149 100644 --- a/src/layout/components/Setting/src/Setting.vue +++ b/src/layout/components/Setting/src/Setting.vue @@ -109,6 +109,7 @@ watch( // 拷贝 const copyConfig = async () => { const { copy, copied, isSupported } = useClipboard({ + legacy: true, source: ` // 面包屑 breadcrumb: ${appStore.getBreadcrumb}, @@ -296,7 +297,7 @@ const clear = () => { $prefix-cls: #{$namespace}-setting; .#{$prefix-cls} { + z-index: 1200; /* 修正没有z-index会被表格层覆盖,值不要超过4000 */ border-radius: 6px 0 0 6px; - z-index: 1200;/*修正没有z-index会被表格层覆盖,值不要超过4000*/ } diff --git a/src/views/ai/chat/index/components/message/MessageList.vue b/src/views/ai/chat/index/components/message/MessageList.vue index 77b41c796..da5c338a6 100644 --- a/src/views/ai/chat/index/components/message/MessageList.vue +++ b/src/views/ai/chat/index/components/message/MessageList.vue @@ -126,7 +126,7 @@ import userAvatarDefaultImg from '@/assets/imgs/avatar.gif' import roleAvatarDefaultImg from '@/assets/ai/gpt.svg' const message = useMessage() // 消息弹窗 -const { copy } = useClipboard() // 初始化 copy 到粘贴板 +const { copy } = useClipboard({ legacy: true }) // 初始化 copy 到粘贴板 const userStore = useUserStore() // 判断“消息列表”滚动的位置(用于判断是否需要滚动到消息最下方) diff --git a/src/views/ai/write/index/components/Right.vue b/src/views/ai/write/index/components/Right.vue index d0aada5df..1eb66a077 100644 --- a/src/views/ai/write/index/components/Right.vue +++ b/src/views/ai/write/index/components/Right.vue @@ -45,7 +45,7 @@ import { useClipboard } from '@vueuse/core' const message = useMessage() // 消息弹窗 -const { copied, copy } = useClipboard() // 粘贴板 +const { copied, copy } = useClipboard({ legacy: true }) // 粘贴板 const props = defineProps({ content: { diff --git a/src/views/infra/build/index.vue b/src/views/infra/build/index.vue index 260b8b7a0..191fc90fe 100644 --- a/src/views/infra/build/index.vue +++ b/src/views/infra/build/index.vue @@ -136,7 +136,7 @@ const makeTemplate = () => { /** 复制 **/ const copy = async (text: string) => { const textToCopy = JSON.stringify(text, null, 2) - const { copy, copied, isSupported } = useClipboard({ source: textToCopy }) + const { copy, copied, isSupported } = useClipboard({ legacy: true, source: textToCopy }) if (!isSupported) { message.error(t('common.copyError')) } else { diff --git a/src/views/infra/codegen/PreviewCode.vue b/src/views/infra/codegen/PreviewCode.vue index b6a307d23..819fca6c0 100644 --- a/src/views/infra/codegen/PreviewCode.vue +++ b/src/views/infra/codegen/PreviewCode.vue @@ -180,7 +180,7 @@ const handleFiles = (datas: CodegenApi.CodegenPreviewVO[]) => { /** 复制 **/ const copy = async (text: string) => { - const { copy, copied, isSupported } = useClipboard({ source: text }) + const { copy, copied, isSupported } = useClipboard({ legacy: true, source: text }) if (!isSupported) { message.error(t('common.copyError')) return diff --git a/src/views/infra/file/index.vue b/src/views/infra/file/index.vue index a0c9e258b..e431218da 100644 --- a/src/views/infra/file/index.vue +++ b/src/views/infra/file/index.vue @@ -136,6 +136,7 @@ import { fileSizeFormatter } from '@/utils' import { dateFormatter } from '@/utils/formatTime' import * as FileApi from '@/api/infra/file' import FileForm from './FileForm.vue' +import { useClipboard } from '@vueuse/core' defineOptions({ name: 'InfraFile' }) @@ -186,29 +187,15 @@ const openForm = () => { } /** 复制到剪贴板方法 */ -const copyToClipboard = (text: string) => { - if (navigator.clipboard && window.isSecureContext) { - navigator.clipboard - .writeText(text) - .then(() => { - message.success('复制成功') - }) - .catch(() => { - message.error('复制失败') - }) - } else { - // 兼容不支持 clipboard 的情况 - try { - const textarea = document.createElement('textarea') - textarea.value = text - document.body.appendChild(textarea) - textarea.select() - document.execCommand('copy') - document.body.removeChild(textarea) - message.success('复制成功') - } catch (error) { - message.error('复制失败') - } +const copyToClipboard = async (text: string) => { + const { copy, copied, isSupported } = useClipboard({ legacy: true, source: text }) + if (!isSupported) { + message.error(t('common.copyError')) + return + } + await copy() + if (unref(copied)) { + message.success(t('common.copySuccess')) } } diff --git a/src/views/iot/device/device/detail/DeviceDetailsHeader.vue b/src/views/iot/device/device/detail/DeviceDetailsHeader.vue index 6fc876bc8..c6d031fdb 100644 --- a/src/views/iot/device/device/detail/DeviceDetailsHeader.vue +++ b/src/views/iot/device/device/detail/DeviceDetailsHeader.vue @@ -39,8 +39,10 @@ import DeviceForm from '@/views/iot/device/device/DeviceForm.vue' import { ProductVO } from '@/api/iot/product/product' import { DeviceVO } from '@/api/iot/device/device' +import { useClipboard } from '@vueuse/core' const message = useMessage() +const { t } = useI18n() // 国际化 const router = useRouter() const { product, device } = defineProps<{ product: ProductVO; device: DeviceVO }>() @@ -54,11 +56,14 @@ const openForm = (type: string, id?: number) => { /** 复制到剪贴板方法 */ const copyToClipboard = async (text: string) => { - try { - await navigator.clipboard.writeText(text) - message.success('复制成功') - } catch (error) { - message.error('复制失败') + const { copy, copied, isSupported } = useClipboard({ legacy: true, source: text }) + if (!isSupported) { + message.error(t('common.copyError')) + return + } + await copy() + if (unref(copied)) { + message.success(t('common.copySuccess')) } } diff --git a/src/views/iot/device/device/detail/DeviceDetailsInfo.vue b/src/views/iot/device/device/detail/DeviceDetailsInfo.vue index 930adb678..e3beda752 100644 --- a/src/views/iot/device/device/detail/DeviceDetailsInfo.vue +++ b/src/views/iot/device/device/detail/DeviceDetailsInfo.vue @@ -140,8 +140,10 @@ import { DeviceVO } from '@/api/iot/device/device' import { DeviceApi, IotDeviceAuthInfoVO } from '@/api/iot/device/device' import Map from '@/components/Map/index.vue' import { ref, computed } from 'vue' +import { useClipboard } from '@vueuse/core' const message = useMessage() // 消息提示 +const { t } = useI18n() // 国际化 const { product, device } = defineProps<{ product: ProductVO; device: DeviceVO }>() // 定义 Props const emit = defineEmits(['refresh']) // 定义 Emits @@ -165,11 +167,14 @@ const getLocationString = () => { /** 复制到剪贴板方法 */ const copyToClipboard = async (text: string) => { - try { - await navigator.clipboard.writeText(text) - message.success('复制成功') - } catch (error) { - message.error('复制失败') + const { copy, copied, isSupported } = useClipboard({ legacy: true, source: text }) + if (!isSupported) { + message.error(t('common.copyError')) + return + } + await copy() + if (unref(copied)) { + message.success(t('common.copySuccess')) } } diff --git a/src/views/iot/product/product/detail/ProductDetailsHeader.vue b/src/views/iot/product/product/detail/ProductDetailsHeader.vue index 3eb999fa4..311900c2a 100644 --- a/src/views/iot/product/product/detail/ProductDetailsHeader.vue +++ b/src/views/iot/product/product/detail/ProductDetailsHeader.vue @@ -54,18 +54,23 @@
发起人{{ printData.startUser.nickname }}{{ printData.processInstance.startUser.nickname }} 发起时间{{ printData.startTime }}{{ formatDate(printData.processInstance.startTime) }}
所属部门{{ printData.startUser.deptName }}{{ printData.processInstance.startUser.deptName }} 流程状态 - {{ getDictLabel(DICT_TYPE.BPM_PROCESS_INSTANCE_STATUS, printData.processStatus) }} + {{ + getDictLabel( + DICT_TYPE.BPM_PROCESS_INSTANCE_STATUS, + printData.processInstance.status + ) + }}
- {{ item.name }} - -
+
+
- {{ item.nodeName }} + {{ item.name }} - {{ item.nodeDesc }} + {{ item.description }}
@@ -185,7 +258,7 @@ const printObj = ref({ From cf357cb1a29a51c7ff90ec4b04feac90ca8c6700 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 6 Sep 2025 10:39:43 +0800 Subject: [PATCH 054/161] =?UTF-8?q?fix=EF=BC=9A=E3=80=90system=20=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F=E7=AE=A1=E7=90=86=E3=80=91=E9=82=AE=E7=AE=B1=E6=A8=A1?= =?UTF-8?q?=E7=89=88=E7=9A=84=E5=88=97=E8=A1=A8=E5=AE=BD=E5=BA=A6=E5=A4=AA?= =?UTF-8?q?=E5=B0=8F=EF=BC=8C=E6=A0=B7=E5=BC=8F=E4=B8=91=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/system/mail/template/index.vue | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/views/system/mail/template/index.vue b/src/views/system/mail/template/index.vue index 03ea34ede..5913f3013 100644 --- a/src/views/system/mail/template/index.vue +++ b/src/views/system/mail/template/index.vue @@ -61,7 +61,6 @@ From bfd918271f30d3a33aa4c6fbdc2a57cbb8512853 Mon Sep 17 00:00:00 2001 From: LesanOuO <1960681385@qq.com> Date: Sat, 6 Sep 2025 12:02:12 +0800 Subject: [PATCH 055/161] =?UTF-8?q?fix:=20=E4=BB=A3=E7=A0=81=E8=AF=84?= =?UTF-8?q?=E5=AE=A1=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model/form/PrintTemplate/MentionModal.vue | 2 +- .../processInstance/detail/PrintDialog.vue | 98 ++++--------------- 2 files changed, 22 insertions(+), 78 deletions(-) diff --git a/src/views/bpm/model/form/PrintTemplate/MentionModal.vue b/src/views/bpm/model/form/PrintTemplate/MentionModal.vue index 598867e2f..badeb420e 100644 --- a/src/views/bpm/model/form/PrintTemplate/MentionModal.vue +++ b/src/views/bpm/model/form/PrintTemplate/MentionModal.vue @@ -13,7 +13,7 @@ const list = ref([ { id: 'startTime', name: '发起时间' }, { id: 'endTime', name: '结束时间' }, { id: 'processStatus', name: '流程状态' }, - { id: 'printUsername', name: '打印人' }, + { id: 'printUser', name: '打印人' }, { id: 'printTime', name: '打印时间' } ]) const searchedList = computed(() => { diff --git a/src/views/bpm/processInstance/detail/PrintDialog.vue b/src/views/bpm/processInstance/detail/PrintDialog.vue index 37ce48a04..4be26eed6 100644 --- a/src/views/bpm/processInstance/detail/PrintDialog.vue +++ b/src/views/bpm/processInstance/detail/PrintDialog.vue @@ -3,9 +3,7 @@ import * as ProcessInstanceApi from '@/api/bpm/processInstance' import { useUserStore } from '@/store/modules/user' import { formatDate } from '@/utils/formatTime' import { DICT_TYPE, getDictLabel } from '@/utils/dict' -import { decodeFields, setConfAndFields2 } from '@/utils/formCreate' -import type { ApiAttrs } from '@form-create/element-ui/types/config' -import formCreate from "@form-create/element-ui"; +import { decodeFields } from '@/utils/formCreate' const userStore = useUserStore() @@ -18,21 +16,6 @@ const printTime = ref(formatDate(new Date(), 'YYYY-MM-DD HH:mm')) const formFields = ref() const printDataMap = ref({}) -const fApi = ref() -const detailForm = ref({ - rule: [], - option: {}, - value: {} -}) - -const fApiH = ref() -const detailFormH = ref({ - rule: [], - option: {}, - value: {} -}) -const fcRef = ref() - const open = async (id: string) => { loading.value = true try { @@ -47,37 +30,9 @@ const open = async (id: string) => { defineExpose({ open }) const parseFormFields = () => { - const processInstance = printData.value.processInstance - const processDefinition = processInstance.processDefinition - setConfAndFields2( - detailForm, - processDefinition.formConf, - processDefinition.formFields, - processInstance.formVariables - ) - detailForm.value.option = { - submitBtn: false, - resetBtn: false, - form: { - disabled: true - } - } - setConfAndFields2( - detailFormH, - processDefinition.formConf, - processDefinition.formFields, - processInstance.formVariables - ) - detailFormH.value.option = { - submitBtn: false, - resetBtn: false, - form: { - disabled: true - } - } - return // TODO @lesan:form field 有可能基于 form-create 什么 api 生成么?好像也挺难的 = = - const formFieldsObj = decodeFields(printData.value.formFields) + // TODO @芋艿:默认打印可以直接用form-create的预览表单模式,但是自定义模板打印就没法这么做 + const formFieldsObj = decodeFields(printData.value.processInstance.processDefinition.formFields) const processVariables = printData.value.processInstance.formVariables let res: any = [] for (const item of formFieldsObj) { @@ -109,7 +64,7 @@ const initPrintDataMap = () => { DICT_TYPE.BPM_PROCESS_INSTANCE_STATUS, printData.value.processInstance.status ) - printDataMap.value['printUsername'] = userName.value + printDataMap.value['printUser'] = userName.value printDataMap.value['printTime'] = printTime.value } @@ -161,25 +116,6 @@ const getPrintTemplateHTML = () => { return doc.body.innerHTML } -const html = ref('') -const handleDialogOpened = async () => { - const processInstance = printData.value.processInstance - const processDefinition = processInstance.processDefinition - let fcData = { - rule: [], - option: {}, - value: {} - } - setConfAndFields2( - fcData, - processDefinition.formConf, - processDefinition.formFields, - processInstance.formVariables - ) - const api = formCreate.create(fcData.rule,fcData.option) - console.log(api) -} - const printObj = ref({ id: 'printDivTag', popTitle: ' ', @@ -226,14 +162,22 @@ const printObj = ref({

表单内容

- + + + + + + + + + + +
+ {{ item.name }} + +
{{ item.description }} -
- +
+