Merge remote-tracking branch 'remotes/origin/dev' into dev-sugx20250509

# Conflicts:
#	.env.development
#	.env.production
#	src/utils/env.ts
#	src/views/secondDev/LoginForm.vue
This commit is contained in:
suguangxu
2025-06-06 15:20:51 +08:00
38 changed files with 683 additions and 309 deletions

6
.env
View File

@ -4,11 +4,13 @@ VITE_PORT = 3100
# spa-title # spa-title
VITE_GLOB_APP_TITLE = 全代码平台 VITE_GLOB_APP_TITLE = 全代码平台
# spa shortname # spa shortname(英文缩写)
VITE_GLOB_APP_SHORT_NAME = 全代码平台 VITE_GLOB_APP_SHORT_NAME = 全代码平台
# 应用名称 # 应用名称仅展示在登录页和左上角logo旁其他情况用VITE_GLOB_APP_TITLE
VITE_SYSTEM_NAME = 全代码平台 VITE_SYSTEM_NAME = 全代码平台
# 应用名称简写用于空间不足的界面显示左上角logo旁7个字以内超出变成...
# VITE_SYSTEM_SHORT_NAME = 全代码平台
# 响应式布局的表单宽度分界 # 响应式布局的表单宽度分界
VITE_RESP_LG_WIDTH = 1280 VITE_RESP_LG_WIDTH = 1280

View File

@ -17,7 +17,9 @@ VITE_DROP_CONSOLE = false
# 接口地址 # 接口地址
# 如果没有跨域问题,直接在这里配置即可 # 如果没有跨域问题,直接在这里配置即可
VITE_GLOB_API_URL=http://10.133.96.105:8077 VITE_GLOB_API_URL=http://10.133.96.137:8090
# VITE_GLOB_API_URL=http://10.4.126.67:30000
# VITE_GLOB_API_URL=http://10.0.252.25:8090
#VITE_GLOB_REQUEST_TIMEOUT=20000 #VITE_GLOB_REQUEST_TIMEOUT=20000
# 报表系统地址 # 报表系统地址
VITE_GLOB_REPORT_URL=http://10.133.96.105:3100 VITE_GLOB_REPORT_URL=http://10.133.96.105:3100
@ -38,11 +40,11 @@ VITE_GLOB_PRINT_BASE_URL = http://114.116.210.204:3300
VITE_GLOB_API_URL_PREFIX = VITE_GLOB_API_URL_PREFIX =
#租户开关 #租户开关
# VITE_TENANT_ENABLED = true # VITE_GLOB_TENANT_ENABLED = true
#是否需要输入租户 #是否需要输入租户
# VITE_TENANT_INPUT_REQUIRED = true # VITE_GLOB_TENANT_INPUT_REQUIRED = true
# 屏蔽通知消息的轮询 # 屏蔽通知消息的轮询
VITE_DISABLE_NEWS=false VITE_GLOB_DISABLE_NEWS=false
# 禁用关闭页面提示 # 禁用关闭页面提示
# VITE_CLOSE_ALERT_DISABLED=true # VITE_GLOB_CLOSE_ALERT_DISABLED=true

View File

@ -35,4 +35,4 @@ VITE_GLOB_PRINT_BASE_URL = http://114.116.210.204:3300
VITE_GLOB_API_URL_PREFIX = VITE_GLOB_API_URL_PREFIX =
# 屏蔽通知消息的轮询 # 屏蔽通知消息的轮询
VITE_DISABLE_NEWS = true VITE_GLOB_DISABLE_NEWS = true

View File

@ -36,8 +36,12 @@ VITE_GLOB_API_URL_PREFIX =
# 打包是否开启pwa功能 # 打包是否开启pwa功能
VITE_USE_PWA = false VITE_USE_PWA = false
#租户开关 #租户开关
VITE_TENANT_ENABLED = true VITE_GLOB_TENANT_ENABLED = true
#是否需要输入租户 #是否需要输入租户
# VITE_TENANT_INPUT_REQUIRED = true # VITE_GLOB_TENANT_INPUT_REQUIRED = true
# 屏蔽通知消息的轮询
VITE_GLOB_DISABLE_NEWS=false
# 禁用关闭页面提示
# VITE_GLOB_CLOSE_ALERT_DISABLED=true

280
.vscode/settings.json vendored
View File

@ -1,144 +1,142 @@
{ {
"typescript.tsdk": "./node_modules/typescript/lib", "typescript.tsdk": "./node_modules/typescript/lib",
"volar.tsPlugin": true, "volar.tsPlugin": true,
"volar.tsPluginStatus": false, "volar.tsPluginStatus": false,
"npm.packageManager": "pnpm", "npm.packageManager": "pnpm",
"editor.tabSize": 2, "editor.tabSize": 2,
"editor.defaultFormatter": "esbenp.prettier-vscode", "editor.defaultFormatter": "esbenp.prettier-vscode",
"files.eol": "\n", "files.eol": "\n",
"search.exclude": { "search.exclude": {
"**/node_modules": true, "**/node_modules": true,
"**/*.log": true, "**/*.log": true,
"**/*.log*": true, "**/*.log*": true,
"**/bower_components": true, "**/bower_components": true,
"**/dist": true, "**/dist": true,
"**/elehukouben": true, "**/elehukouben": true,
"**/.git": true, "**/.git": true,
"**/.gitignore": true, "**/.gitignore": true,
"**/.svn": true, "**/.svn": true,
"**/.DS_Store": true, "**/.DS_Store": true,
"**/.idea": true, "**/.idea": true,
"**/.vscode": false, "**/.vscode": false,
"**/yarn.lock": true, "**/yarn.lock": true,
"**/tmp": true, "**/tmp": true,
"out": true, "out": true,
"dist": true, "dist": true,
"node_modules": true, "node_modules": true,
"CHANGELOG.md": true, "CHANGELOG.md": true,
"examples": true, "examples": true,
"res": true, "res": true,
"screenshots": true, "screenshots": true,
"yarn-error.log": true, "yarn-error.log": true,
"**/.yarn": true "**/.yarn": true
},
"files.exclude": {
"**/.cache": true,
"**/.editorconfig": true,
"**/.eslintcache": true,
"**/bower_components": true,
"**/.idea": true,
"**/tmp": true,
"**/.git": true,
"**/.svn": true,
"**/.hg": true,
"**/CVS": true,
"**/.DS_Store": true
},
"files.watcherExclude": {
"**/.git/objects/**": true,
"**/.git/subtree-cache/**": true,
"**/.vscode/**": true,
"**/node_modules/**": true,
"**/tmp/**": true,
"**/bower_components/**": true,
"**/dist/**": true,
"**/yarn.lock": true
},
"stylelint.enable": true,
"stylelint.validate": ["css", "less", "postcss", "scss", "vue", "sass"],
"path-intellisense.mappings": {
"/@/": "${workspaceRoot}/src"
},
"[javascriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[html]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[css]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[less]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[scss]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[markdown]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
},
"[vue]": {
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit",
"source.fixAll.stylelint": "explicit"
}, },
"editor.defaultFormatter": "esbenp.prettier-vscode" "files.exclude": {
}, "**/.cache": true,
"i18n-ally.localesPaths": ["src/locales/lang"], "**/.editorconfig": true,
"i18n-ally.keystyle": "nested", "**/.eslintcache": true,
"i18n-ally.sortKeys": true, "**/bower_components": true,
"i18n-ally.namespace": true, "**/.idea": true,
"i18n-ally.pathMatcher": "{locale}/{namespaces}.{ext}", "**/tmp": true,
"i18n-ally.enabledParsers": ["ts"], "**/.git": true,
"i18n-ally.sourceLanguage": "en", "**/.svn": true,
"i18n-ally.displayLanguage": "zh-CN", "**/.hg": true,
"i18n-ally.enabledFrameworks": ["vue", "react"], "**/CVS": true,
"cSpell.words": [ "**/.DS_Store": true
"vben", },
"windi", "files.watcherExclude": {
"browserslist", "**/.git/objects/**": true,
"tailwindcss", "**/.git/subtree-cache/**": true,
"esnext", "**/.vscode/**": true,
"antv", "**/node_modules/**": true,
"tinymce", "**/tmp/**": true,
"qrcode", "**/bower_components/**": true,
"sider", "**/dist/**": true,
"pinia", "**/yarn.lock": true
"sider", },
"nprogress", "stylelint.enable": true,
"INTLIFY", "stylelint.validate": ["css", "less", "postcss", "scss", "vue", "sass"],
"stylelint", "path-intellisense.mappings": {
"esno", "/@/": "${workspaceRoot}/src"
"vitejs", },
"sortablejs", "[javascriptreact]": {
"mockjs", "editor.defaultFormatter": "esbenp.prettier-vscode"
"codemirror", },
"iconify", "[typescript]": {
"commitlint", "editor.defaultFormatter": "esbenp.prettier-vscode"
"vditor", },
"echarts", "[typescriptreact]": {
"cropperjs", "editor.defaultFormatter": "esbenp.prettier-vscode"
"logicflow", },
"vueuse", "[html]": {
"zxcvbn", "editor.defaultFormatter": "esbenp.prettier-vscode"
"lintstagedrc", },
"brotli", "[css]": {
"tailwindcss", "editor.defaultFormatter": "esbenp.prettier-vscode"
"sider", },
"pnpm", "[less]": {
"antd" "editor.defaultFormatter": "esbenp.prettier-vscode"
], },
"files.autoSave": "onFocusChange", "[scss]": {
"editor.formatOnSave": true, "editor.defaultFormatter": "esbenp.prettier-vscode"
"eslint.codeActionsOnSave.rules": null, },
"vue3snippets.enable-compile-vue-file-on-did-save-code": false "[markdown]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
},
"[vue]": {
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit",
"source.fixAll.stylelint": "explicit"
},
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"i18n-ally.localesPaths": ["src/locales/lang"],
"i18n-ally.keystyle": "nested",
"i18n-ally.sortKeys": true,
"i18n-ally.namespace": true,
"i18n-ally.pathMatcher": "{locale}/{namespaces}.{ext}",
"i18n-ally.enabledParsers": ["ts"],
"i18n-ally.sourceLanguage": "en",
"i18n-ally.displayLanguage": "zh-CN",
"i18n-ally.enabledFrameworks": ["vue", "react"],
"cSpell.words": [
"vben",
"windi",
"browserslist",
"tailwindcss",
"esnext",
"antv",
"tinymce",
"qrcode",
"sider",
"pinia",
"sider",
"nprogress",
"INTLIFY",
"stylelint",
"esno",
"vitejs",
"sortablejs",
"mockjs",
"codemirror",
"iconify",
"commitlint",
"vditor",
"echarts",
"cropperjs",
"logicflow",
"vueuse",
"zxcvbn",
"lintstagedrc",
"brotli",
"tailwindcss",
"sider",
"pnpm",
"antd"
],
"eslint.codeActionsOnSave.rules": null,
"vue3snippets.enable-compile-vue-file-on-did-save-code": false
} }

View File

@ -33,9 +33,11 @@
const { data } = await responseStream.json(); const { data } = await responseStream.json();
if (data.shortName) { if (data.shortName) {
document.title = data.shortName; document.title = data.shortName;
document.getElementById('app-loading-title').innerText = data.shortName; if(document.getElementById('app-loading-title')){
document.getElementById('app-loading-title').innerText = data.shortName;
}
} }
if (data.refreshLogoUrl) { if (data.refreshLogoUrl&&document.getElementById('app-loading-logo')) {
document.getElementById('app-loading-logo').setAttribute('src', data.refreshLogoUrl); document.getElementById('app-loading-logo').setAttribute('src', data.refreshLogoUrl);
} }
} catch { } catch {

View File

@ -55,7 +55,7 @@
return '关闭提示'; return '关闭提示';
}; };
if(!getAppEnvConfig().VITE_CLOSE_ALERT_DISABLED){ if(!getAppEnvConfig().VITE_GLOB_CLOSE_ALERT_DISABLED){
window.addEventListener('beforeunload', beforeUnloadHandler); window.addEventListener('beforeunload', beforeUnloadHandler);
} }

View File

@ -3,12 +3,12 @@ import { defHttp } from '/@/utils/http/axios';
import { ErrorMessageMode } from '/#/axios'; import { ErrorMessageMode } from '/#/axios';
enum Api { enum Api {
Page = '/auditOpt/auditRecord/page', Page = '/workflow/workflowApproveRecord/page',
List = '/auditOpt/auditRecord/list', List = '/workflow/workflowApproveRecord/list',
Info = '/auditOpt/auditRecord/info', Info = '/workflow/workflowApproveRecord/info',
XjrWorkflowApproveRecord = '/auditOpt/auditRecord', XjrWorkflowApproveRecord = '/workflow/workflowApproveRecord',
GetApproveRecord = '/workflow/adminOperation/getAllApproveRecord', GetApproveRecord = '/workflow/adminOperation/getAllApproveRecord',
DelApproveRecord = '/auditOpt/auditRecord', DelApproveRecord = '/workflow/workflowApproveRecord',
AddApproveRcord = '/workflow/adminOperation/addApproveRecord', AddApproveRcord = '/workflow/adminOperation/addApproveRecord',
UpdateApproveRcord = '/workflow/adminOperation/updateApproveRecord', UpdateApproveRcord = '/workflow/adminOperation/updateApproveRecord',
} }

View File

@ -4,10 +4,10 @@
--> -->
<template> <template>
<div class="anticon" :class="getAppLogoClass" @click="goHome"> <div class="anticon" :class="getAppLogoClass" @click="goHome">
<a href="https://fcdma.gdyditc.com/" target="_blank"> <a :href="sysImgGotoUrl" target="_blank">
<img :src="logoConfig.menuLogoUrl || logo" width="24" style="height: 36px" /> <img :src="logoConfig.menuLogoUrl || logo" width="24" style="height: 36px" />
<div class="truncate md:opacity-100" :class="getTitleClass" v-show="showTitle"> <div class="truncate md:opacity-100" :class="getTitleClass" v-show="showTitle" :title="sysShortName || sysName">
{{ sysName }} {{ sysShortName || sysName }}
</div> </div>
</a> </a>
</div> </div>
@ -42,7 +42,9 @@
const go = useGo(); const go = useGo();
const appStore = useAppStore(); const appStore = useAppStore();
const logoConfig = appStore.getLogoConfig; const logoConfig = appStore.getLogoConfig;
const sysShortName = ref(import.meta.env.VITE_SYSTEM_SHORT_NAME);
const sysName = ref(import.meta.env.VITE_SYSTEM_NAME); const sysName = ref(import.meta.env.VITE_SYSTEM_NAME);
const sysImgGotoUrl = ref(import.meta.env.VITE_SYSTEM_IMG_GOTO_URL);
const getAppLogoClass = computed(() => [prefixCls, props.theme, { 'collapsed-show-title': unref(getCollapsedShowTitle) }]); const getAppLogoClass = computed(() => [prefixCls, props.theme, { 'collapsed-show-title': unref(getCollapsedShowTitle) }]);
const getTitleClass = computed(() => [ const getTitleClass = computed(() => [

View File

@ -14,7 +14,7 @@
:height="200" :height="200"
:preview="false" :preview="false"
:src="sourceValue" :src="sourceValue"
fallback="src/assets/images/header.jpg" :fallback="headerImg"
/> />
</div> </div>
<a-button <a-button
@ -52,6 +52,7 @@
import { useI18n } from '/@/hooks/web/useI18n'; import { useI18n } from '/@/hooks/web/useI18n';
import type { ButtonProps } from '/@/components/Button'; import type { ButtonProps } from '/@/components/Button';
import Icon from '/@/components/Icon'; import Icon from '/@/components/Icon';
import headerImg from '/@/assets/images/header.jpg';
const props = { const props = {
width: { type: [String, Number], default: '200px' }, width: { type: [String, Number], default: '200px' },
@ -116,6 +117,7 @@
getImageWrapperStyle, getImageWrapperStyle,
getStyle, getStyle,
handleUploadSuccess, handleUploadSuccess,
headerImg
}; };
}, },
}); });

View File

@ -192,7 +192,7 @@
} }
function displayText() { function displayText() {
const _checked = checked.value;; const _checked = checked.value || [];
const labelArr = []; const labelArr = [];
(getOptions.value || []).forEach((opt) => { (getOptions.value || []).forEach((opt) => {
if (_checked.includes(opt.value)) { if (_checked.includes(opt.value)) {

View File

@ -117,6 +117,10 @@
justCompany: { justCompany: {
type: Boolean, type: Boolean,
default: false default: false
},
isOnlyCurrentDepartment: { // 仅当前部门,无下级部门
type: Boolean,
default: true
} }
}); });
let timeoutId = null; let timeoutId = null;
@ -205,14 +209,14 @@
limit: 1, limit: 1,
size: 10000, size: 10000,
departmentId: '', departmentId: '',
departmentIds: defaultDepts.value departmentIds: defaultDepts.value,
isOnlyCurrentDepartment: props.isOnlyCurrentDepartment,
}); });
const searchDepartMemberTotal = ref(0); const searchDepartMemberTotal = ref(0);
const searchDepartMemberList = ref([]); const searchDepartMemberList = ref([]);
const searchAllMemberParams = ref({ const searchAllMemberParams = ref({
limit: 1, limit: 1,
size: 25, size: 25,
isSearchAll: true,
keyword: '', keyword: '',
departmentIds: defaultDepts.value departmentIds: defaultDepts.value
}); });

View File

@ -438,9 +438,14 @@
if (schema.componentProps?.['events']) { if (schema.componentProps?.['events']) {
for (const eventKey in schema.componentProps['events']) { for (const eventKey in schema.componentProps['events']) {
if (eventKey !== 'change') return; if (eventKey !== 'change') return;
const handler = schema.componentProps['events'][eventKey];
try { try {
const event = new Function('schema', 'formModel', 'formActionType', 'extParams', `${schema.componentProps['events'][eventKey]}`); if (typeof handler === 'string') {
event(schema, formModel, formApi, { formData }); const event = new Function('schema', 'formModel', 'formActionType', 'extParams', handler);
event(schema, formModel, formApi, { formData, allSchemas });
} else if (typeof handler === 'function') {
handler(schema, formModel, formApi, { formData, allSchemas });
}
} catch (error) { } catch (error) {
console.log('error', error); console.log('error', error);
notification.error({ notification.error({

View File

@ -438,9 +438,14 @@
if (schema.componentProps?.['events']) { if (schema.componentProps?.['events']) {
for (const eventKey in schema.componentProps['events']) { for (const eventKey in schema.componentProps['events']) {
if (eventKey !== 'change') return; if (eventKey !== 'change') return;
const handler = schema.componentProps['events'][eventKey];
try { try {
const event = new Function('schema', 'formModel', 'formActionType', 'extParams', `${schema.componentProps['events'][eventKey]}`); if (typeof handler === 'string') {
event(schema, formModel, formApi, { formData }); const event = new Function('schema', 'formModel', 'formActionType', 'extParams', handler);
event(schema, formModel, formApi, { formData, allSchemas });
} else if (typeof handler === 'function') {
handler(schema, formModel, formApi, { formData, allSchemas });
}
} catch (error) { } catch (error) {
console.log('error', error); console.log('error', error);
notification.error({ notification.error({

View File

@ -219,8 +219,7 @@
const tabActiveKey = inject<Ref<number>>('tabActiveKey', ref(0)); const tabActiveKey = inject<Ref<number>>('tabActiveKey', ref(0));
const activeKey = ref<number>(0); const activeKey = ref<number>(0);
const isCamelCase = inject<boolean>('isCamelCase', false); const isCamelCase = inject<boolean>('isCamelCase', false);
// 注入整个表单的配置formProps是个计算属性不能修改formData则来自每个业务的表单页面。
const formData = inject('formData', { noInject: true });
watch( watch(
() => tabActiveKey?.value, () => tabActiveKey?.value,
(val) => { (val) => {
@ -240,35 +239,6 @@
} }
); );
// watch(
// () => props.value,
// (val) => {
// if (!val) return;
// let { componentProps = {} } = props.schema;
// if (componentProps['events']) {
// for (const eventKey in componentProps['events']) {
// try {
// const event = new Function(
// 'schema',
// 'formModel',
// 'formActionType',
// `${componentProps['events'][eventKey]}`,
// );
// event(props.schema, formModel, props.formApi);
// } catch (error) {
// notification.error({
// message: 'Tip',
// description: '触发事件填写有误!',
// });
// }
// }
// }
// },
// {
// immediate: true,
// },
// );
const { notification } = useMessage(); const { notification } = useMessage();
const getSchema = computed(() => { const getSchema = computed(() => {
return props.schema as FormSchema; return props.schema as FormSchema;
@ -305,6 +275,7 @@
}) ?? {}; }) ?? {};
} else { } else {
if (componentProps['events']) { if (componentProps['events']) {
const allSchemas = formProps.value.schemas;
for (const eventKey in componentProps['events']) { for (const eventKey in componentProps['events']) {
try { try {
const fun = componentProps['events'][eventKey]; const fun = componentProps['events'][eventKey];
@ -320,7 +291,7 @@
let field = camelCaseString(item); let field = camelCaseString(item);
if (field) cloneFormModel[field] = cloneFormModel[item]; if (field) cloneFormModel[field] = cloneFormModel[item];
} }
event(props.schema, isCamelCase ? cloneFormModel : formModel, props.formApi, { formData, value, selectedOptions }); event(props.schema, isCamelCase ? cloneFormModel : formModel, props.formApi, {formData, value, selectedOptions, allSchemas: allSchemas});
if (isCamelCase) { if (isCamelCase) {
for (let item in formModel) { for (let item in formModel) {

View File

@ -53,8 +53,6 @@
const tabActiveKey = inject<Ref<number>>('tabActiveKey', ref(0)); const tabActiveKey = inject<Ref<number>>('tabActiveKey', ref(0));
const activeKey = ref<number>(0); const activeKey = ref<number>(0);
const isCamelCase = inject<boolean>('isCamelCase', false); const isCamelCase = inject<boolean>('isCamelCase', false);
// 注入整个表单的配置formProps是个计算属性不能修改formData则来自每个业务的表单页面。
const formData = inject('formData', { noInject: true });
watch( watch(
() => tabActiveKey?.value, () => tabActiveKey?.value,
(val) => { (val) => {
@ -124,7 +122,7 @@
let field = camelCaseString(item); let field = camelCaseString(item);
if (field) cloneFormModel[field] = cloneFormModel[item]; if (field) cloneFormModel[field] = cloneFormModel[item];
} }
event(props.schema, isCamelCase ? cloneFormModel : formModel, props.formApi, { formData }); event(props.schema, isCamelCase ? cloneFormModel : formModel, props.formApi, {});
if (isCamelCase) { if (isCamelCase) {
for (let item in formModel) { for (let item in formModel) {

View File

@ -383,7 +383,7 @@
); );
createTableContext({ ...tableAction, wrapRef, getBindValues }); createTableContext({ ...tableAction, wrapRef, getBindValues });
expose(tableAction); expose({...tableAction, beforeSearchInfoChange});
emit("register", tableAction, formActions); emit("register", tableAction, formActions);

View File

@ -11,7 +11,7 @@ import { REDIRECT_NAME } from '/@/router/constant';
* Listening to page changes and dynamically changing site titles * Listening to page changes and dynamically changing site titles
*/ */
export function useTitle() { export function useTitle() {
const title = import.meta.env.VITE_SYSTEM_NAME; const title = import.meta.env.VITE_GLOB_APP_TITLE;
const { t } = useI18n(); const { t } = useI18n();
const { currentRoute } = useRouter(); const { currentRoute } = useRouter();
const localeStore = useLocaleStore(); const localeStore = useLocaleStore();

View File

@ -196,7 +196,7 @@
if (o.read) o.read = []; if (o.read) o.read = [];
}); });
try { try {
let res = import.meta.env.VITE_DISABLE_NEWS ? [] : await getOaNews(1); let res = import.meta.env.VITE_GLOB_DISABLE_NEWS ? [] : await getOaNews(1);
res.list.forEach((o) => { res.list.forEach((o) => {
if (!o.readId) listData.value[0].unreadNum += 1; if (!o.readId) listData.value[0].unreadNum += 1;
listData.value[0].list.push({ listData.value[0].list.push({
@ -210,7 +210,7 @@
read: o.isRead, read: o.isRead,
}); });
}); });
let res1 = import.meta.env.VITE_DISABLE_NEWS ? [] : await getOaNews(2); let res1 = import.meta.env.VITE_GLOB_DISABLE_NEWS ? [] : await getOaNews(2);
res1.list.forEach((o) => { res1.list.forEach((o) => {
if (!o.readId) listData.value[1].unreadNum += 1; if (!o.readId) listData.value[1].unreadNum += 1;
listData.value[1].list.push({ listData.value[1].list.push({
@ -224,7 +224,7 @@
read: o.isRead, read: o.isRead,
}); });
}); });
let res2 = import.meta.env.VITE_DISABLE_NEWS ? [] : await getOaMessage(); let res2 = import.meta.env.VITE_GLOB_DISABLE_NEWS ? [] : await getOaMessage();
res2.forEach((o) => { res2.forEach((o) => {
if (o.messageType === 0) { if (o.messageType === 0) {
if (!o.isRead) listData.value[2].unreadNum += 1; if (!o.isRead) listData.value[2].unreadNum += 1;

View File

@ -3,7 +3,7 @@
<span :class="[prefixCls, `${prefixCls}--${theme}`]" class="flex"> <span :class="[prefixCls, `${prefixCls}--${theme}`]" class="flex">
<span style="border-left: 1px solid rgb(255 255 255 / 30%); height: 30px; padding-right: 15px"></span> <span style="border-left: 1px solid rgb(255 255 255 / 30%); height: 30px; padding-right: 15px"></span>
<div style="margin-right: 12px; height: 30px; margin-top: -10px"> <div style="margin-right: 12px; height: 30px; margin-top: -10px">
<a-image :height="24" :src="getUserInfo.avatar" :width="24" fallback="src/assets/images/header.jpg" /> <a-image :height="24" :src="getUserInfo.avatar" :width="24" :fallback="headerImg" />
</div> </div>
<span :class="`${prefixCls}__info hidden md:block`"> <span :class="`${prefixCls}__info hidden md:block`">
<span :class="`${prefixCls}__name `" class="truncate"> <span :class="`${prefixCls}__name `" class="truncate">
@ -117,7 +117,8 @@
getUserInfo, getUserInfo,
handleMenuClick, handleMenuClick,
register, register,
getUseLockPage getUseLockPage,
headerImg
}; };
}, },
methods: { methods: {

View File

@ -25,7 +25,7 @@
<Notify v-if="getShowNotice" :class="`${prefixCls}-action__item notify-item`" /> <Notify v-if="getShowNotice" :class="`${prefixCls}-action__item notify-item`" />
<UserTenantChange v-if="getAppEnvConfig().VITE_TENANT_ENABLED" /> <UserTenantChange v-if="getAppEnvConfig().VITE_GLOB_TENANT_ENABLED" />
<SettingDrawer v-if="getShowSetting" :class="`${prefixCls}-action__item`" ref="drawer" /> <SettingDrawer v-if="getShowSetting" :class="`${prefixCls}-action__item`" ref="drawer" />
<UserDropDown @menu-click="onMenuClick" :theme="getHeaderTheme" :show-settings="getShowSetting" /> <UserDropDown @menu-click="onMenuClick" :theme="getHeaderTheme" :show-settings="getShowSetting" />
</div> </div>

View File

@ -90,6 +90,10 @@ export interface ProcessConfig {
parentId: string; //父节点流程id parentId: string; //父节点流程id
remark: string; //节点描述 remark: string; //节点描述
code: string; //模板编码 code: string; //模板编码
minApprover: string; //最少审批人
maxApprover: string; //最多审批人
maxCirculate: string; //最多传阅人
minCirculate: string; //最少传阅人
category: undefined | string; //分类 category: undefined | string; //分类
nameRule?: string; //命名规则 nameRule?: string; //命名规则
nameRuleConfigs?: NameRule; // 命名规则列表 nameRuleConfigs?: NameRule; // 命名规则列表

View File

@ -22,7 +22,7 @@ export function getAppEnvConfig() {
(import.meta.env as unknown as GlobEnvConfig) (import.meta.env as unknown as GlobEnvConfig)
: window[ENV_NAME as any]) as unknown as GlobEnvConfig; : window[ENV_NAME as any]) as unknown as GlobEnvConfig;
const { VITE_GLOB_APP_TITLE, VITE_GLOB_API_URL, VITE_GLOB_APP_SHORT_NAME, VITE_GLOB_API_URL_PREFIX, VITE_GLOB_REQUEST_TIMEOUT, VITE_GLOB_UPLOAD_URL, VITE_GLOB_UPLOAD_PREVIEW, VITE_GLOB_OUT_LINK_URL, VITE_GLOB_REPORT_URL, VITE_GLOB_PRINT_BASE_URL, VITE_TENANT_ENABLED, VITE_TENANT_INPUT_REQUIRED } = ENV; const { VITE_GLOB_APP_TITLE, VITE_GLOB_API_URL, VITE_GLOB_APP_SHORT_NAME, VITE_GLOB_API_URL_PREFIX, VITE_GLOB_REQUEST_TIMEOUT, VITE_GLOB_UPLOAD_URL, VITE_GLOB_UPLOAD_PREVIEW, VITE_GLOB_OUT_LINK_URL, VITE_GLOB_REPORT_URL, VITE_GLOB_PRINT_BASE_URL, VITE_GLOB_TENANT_ENABLED,VITE_GLOB_TENANT_INPUT_REQUIRED } = ENV;
if (!/^[a-zA-Z\_]*$/.test(VITE_GLOB_APP_SHORT_NAME)) { if (!/^[a-zA-Z\_]*$/.test(VITE_GLOB_APP_SHORT_NAME)) {
warn(`VITE_GLOB_APP_SHORT_NAME Variables can only be characters/underscores, please modify in the environment variables and re-running.`); warn(`VITE_GLOB_APP_SHORT_NAME Variables can only be characters/underscores, please modify in the environment variables and re-running.`);
@ -39,8 +39,8 @@ export function getAppEnvConfig() {
VITE_GLOB_OUT_LINK_URL, VITE_GLOB_OUT_LINK_URL,
VITE_GLOB_REPORT_URL, VITE_GLOB_REPORT_URL,
VITE_GLOB_PRINT_BASE_URL, VITE_GLOB_PRINT_BASE_URL,
VITE_TENANT_ENABLED, VITE_GLOB_TENANT_ENABLED,
VITE_TENANT_INPUT_REQUIRED VITE_GLOB_TENANT_INPUT_REQUIRED
}; };
} }

View File

@ -25,6 +25,7 @@
import { useUserStore } from '/@/store/modules/user'; import { useUserStore } from '/@/store/modules/user';
import { useTabs } from '/@/hooks/web/useTabs'; import { useTabs } from '/@/hooks/web/useTabs';
import { useTitle } from '@vueuse/core'; import { useTitle } from '@vueuse/core';
import {useGlobSetting} from "/@/hooks/setting";
const loading = ref(true); const loading = ref(true);
const desktop = reactive({ hasCustomDesktop: false, list: [] }); const desktop = reactive({ hasCustomDesktop: false, list: [] });
@ -39,6 +40,7 @@
const userStore = useUserStore(); const userStore = useUserStore();
const userInfo = userStore.getUserInfo; const userInfo = userStore.getUserInfo;
const { setTitle } = useTabs(); const { setTitle } = useTabs();
const { title } = useGlobSetting();
watch( watch(
() => userInfo.desktopSchema, () => userInfo.desktopSchema,
@ -56,7 +58,7 @@
//设置Tab标题 //设置Tab标题
setTitle(desktopSchema.name); setTitle(desktopSchema.name);
//设置浏览器标题 //设置浏览器标题
useTitle(` ${desktopSchema.name} `); useTitle(` ${desktopSchema.name} - ${title} `);
desktop.hasCustomDesktop = true; desktop.hasCustomDesktop = true;
} }
} }

View File

@ -8,7 +8,6 @@
:clickRowToExpand="true" :clickRowToExpand="true"
:treeData="treeData" :treeData="treeData"
:fieldNames="fieldNames" :fieldNames="fieldNames"
@row-dbClick="dbClickRow"
:row-selection="rowSelection" :row-selection="rowSelection"
> >
<template #title="item"> <template #title="item">
@ -202,6 +201,7 @@
import { InputParamItem } from '/@/components/ApiConfig/src/interface'; import { InputParamItem } from '/@/components/ApiConfig/src/interface';
import { getDraftInfo } from '/@/api/workflow/process'; import { getDraftInfo } from '/@/api/workflow/process';
import FlowRecord from '/@/views/workflow/task/components/flow/FlowRecord.vue'; import FlowRecord from '/@/views/workflow/task/components/flow/FlowRecord.vue';
import {de} from "@fullcalendar/core/internal-common";
interface SearchDate { interface SearchDate {
fieldName: string; fieldName: string;
format: string; format: string;
@ -578,26 +578,23 @@
} }
function handleView(record: Recordable) { function handleView(record: Recordable) {
if (record.workflowData?.taskIds && record.workflowData.taskIds.length) { const { processId, taskIds, schemaId } = record.workflowData || {};
const { processId, taskIds, schemaId } = record.workflowData; if (taskIds && taskIds.length) {
router.push({ router.push({
path: '/flow/' + schemaId + '/' + (processId || '') + '/approveFlow', path: '/flow/' + schemaId + '/' + (processId || '') + '/approveFlow',
query: { query: {
taskId: taskIds[0], taskId: taskIds[0],
rtId: currentRoute.value.query.rtId
} }
}); });
} else if (record.workflowData?.schemaId && !record.workflowData.taskIds) { } else if (schemaId && !taskIds && processId) {
const { processId, schemaId } = record.workflowData;
router.push({ router.push({
path: '/flow/' + schemaId + '/' + (processId || '') + '/approveFlow', path: '/flow/' + schemaId + '/' + processId + '/approveFlow',
query: { query: {
readonly: 1, readonly: 1,
taskId: '', taskId: '',
rtId: currentRoute.value.query.rtId
} }
}); });
} else { }else {
const info = { const info = {
id: record[pkField.value], id: record[pkField.value],
releaseId: menuId.value, releaseId: menuId.value,
@ -758,6 +755,7 @@
} }
} }
async function handleLaunchProcess(record: Recordable) { async function handleLaunchProcess(record: Recordable) {
debugger
if (record.workflowData) { if (record.workflowData) {
if (record.workflowData.draftId) { if (record.workflowData.draftId) {
let res = await getDraftInfo(record.workflowData.draftId); let res = await getDraftInfo(record.workflowData.draftId);
@ -783,10 +781,14 @@
} }
} }
function handleApproveProcess(record: Recordable) { function handleApproveProcess(record: Recordable) {
visibleApproveProcessRef.value = true; const { processId, taskIds, schemaId } = record.workflowData;
schemaIdRef.value = record.workflowData.schemaId; router.push({
processIdRef.value = record.workflowData.processId; path: '/flow/' + schemaId + '/' + (processId || '') + '/approveFlow',
taskIdRef.value = record.workflowData.taskIds[0]; query: {
taskId: taskIds[0],
rtId: currentRoute.value.query.rtId
}
});
} }
function handleCloseLaunch() { function handleCloseLaunch() {
visibleLaunchProcessRef.value = false; visibleLaunchProcessRef.value = false;
@ -948,35 +950,6 @@
} }
}); });
} }
function dbClickRow(record) {
if (record.workflowData?.taskIds && record.workflowData.taskIds.length) {
const { processId, taskIds, schemaId } = record.workflowData;
router.push({
path: '/flow/' + schemaId + '/' + (processId || '') + '/approveFlow',
query: {
taskId: taskIds[0],
rtId: currentRoute.value.query.rtId
}
});
} else if (record.workflowData?.schemaId && !record.workflowData.taskIds) {
const { processId, schemaId } = record.workflowData;
router.push({
path: '/flow/' + schemaId + '/' + (processId || '') + '/approveFlow',
query: {
readonly: 1,
taskId: '',
rtId: currentRoute.value.query.rtId
}
});
} else {
router.push({
path: '/form/infoTaskManageItem/' + record.id + '/viewForm',
query: {
formPath: 'infoManage/infoTaskManageItem'
}
});
}
}
const rowSelection: TableProps['rowSelection'] = { const rowSelection: TableProps['rowSelection'] = {
onChange: (selectedRowKeys: string[], selectedRows: DataType[]) => { onChange: (selectedRowKeys: string[], selectedRows: DataType[]) => {

View File

@ -34,7 +34,7 @@
</Input> </Input>
</FormItem> </FormItem>
<FormItem v-if="getAppEnvConfig().VITE_TENANT_ENABLED && getAppEnvConfig().VITE_TENANT_INPUT_REQUIRED &&loginType =='pw'" name="tenantCode" class="enter-x"> <FormItem v-if="getAppEnvConfig().VITE_GLOB_TENANT_ENABLED && getAppEnvConfig().VITE_GLOB_TENANT_INPUT_REQUIRED && loginType =='pw'" name="tenantCode" class="enter-x">
<label class="form-title"> {{ t('租户码') }}</label> <label class="form-title"> {{ t('租户码') }}</label>
<Input <Input
size="large" size="large"
@ -458,13 +458,16 @@
:deep(.ant-input-affix-wrapper-lg) { :deep(.ant-input-affix-wrapper-lg) {
padding-left: 0; padding-left: 0;
} }
.login-modal-content { .login-modal-content {
text-align: center; text-align: center;
.refresh { .refresh {
text-align: right; text-align: right;
cursor: pointer; cursor: pointer;
} }
} }
:deep(.captcha-image) { :deep(.captcha-image) {
cursor: pointer; cursor: pointer;
border: 1px solid #ddd; border: 1px solid #ddd;

View File

@ -35,7 +35,7 @@
</InputPassword> </InputPassword>
</FormItem> </FormItem>
<FormItem v-if="getAppEnvConfig().VITE_TENANT_ENABLED" name="tenantCode" class="enter-x"> <FormItem v-if="getAppEnvConfig().VITE_GLOB_TENANT_ENABLED" name="tenantCode" class="enter-x">
<label class="form-title"> {{ t('租户码') }}</label> <label class="form-title"> {{ t('租户码') }}</label>
<Input <Input
size="large" size="large"

View File

@ -26,35 +26,59 @@
@change="changeDesignatedApprover" @change="changeDesignatedApprover"
/> />
</FormItem> </FormItem>
<FormItem <FormItem
:tip=" :tip="
t( t(
'临时审批人是指由上一节点审批人指定下一节点审批人过程中,是否允许在审批人基础上添加组织架构人员。', '临时审批人是指由上一节点审批人指定下一节点审批人过程中,是否允许在审批人基础上添加组织架构人员。',
) )
" "
:label="t('临时审批人:')" :label="t('临时审批人:')"
v-if="props.provisionalApprover == true || props.provisionalApprover == false" >
> <a-switch :checked="props.provisionalApprover" @change="changeProvisionalApprover" />
<a-switch :checked="props.provisionalApprover" @change="changeProvisionalApprover" /> </FormItem>
</FormItem>
<!-- 多选 / --> <!-- 多选 / -->
<FormItem <FormItem :label="t('多选:')">
:label="t('多选:')" <a-switch :checked="props.isChooseMulti" @change="changeIsChooseMulti" />
> </FormItem>
<a-switch :checked="props.isChooseMulti" @change="changeIsChooseMulti" /> <FormItem :label="t('全选:')">
</FormItem> <a-switch :checked="props.isChooseAll" @change="changeIsChooseAll" />
<!-- 全选 / --> </FormItem>
<FormItem <FormItem :label="t('只读:')">
:label="t('全选:')" <a-switch :checked="props.isReadOnly" @change="changeIsReadOnly" />
> </FormItem>
<a-switch :checked="props.isChooseAll" @change="changeIsChooseAll" /> <FormItem :label="t('审批人最多:')" >
</FormItem> <a-input-number
<!-- 只读 / --> v-model:value="props.maxApprover"
<FormItem :min="0"
:label="t('只读:')" :max="100"
> @change="changeMaxApprover"
<a-switch :checked="props.isReadOnly" @change="changeIsReadOnly" /> />
</FormItem> </FormItem>
<FormItem :label="t('审批人最少:')">
<a-input-number
v-model:value="props.minApprover"
:min="0"
:max="100"
@change="changeMinApprover"
/>
</FormItem>
<FormItem :label="t('传阅人最多:')">
<a-input-number
v-model:value="props.maxCirculate"
:min="0"
:max="100"
@change="changeMaxCirculate"
/>
</FormItem>
<FormItem :label="t('传阅人最少:')">
<a-input-number
v-model:value="props.minCirculate"
:min="0"
:max="100"
@change="changeMinCirculate"
/>
</FormItem>
</template> </template>
<script setup lang="ts" name="ProcessBasic"> <script setup lang="ts" name="ProcessBasic">
@ -70,26 +94,46 @@
'update:isChooseMulti', 'update:isChooseMulti',
'update:isChooseAll', 'update:isChooseAll',
'update:isReadOnly', 'update:isReadOnly',
'update:minApprover',
'update:maxApprover',
'update:maxCirculate',
'update:minCirculate'
]); ]);
const props = defineProps({ const props = defineProps({
autoAgreeRule: Array, autoAgreeRule: Array,
noHandler: Number || String || Boolean, noHandler: Number || String || Boolean,
isPrevChooseNext: Number || String || Boolean, isPrevChooseNext: Number || String || Boolean,
isChooseMulti: { isChooseMulti: {
type: Boolean, type: Boolean,
default: true, default: true,
}, },
isChooseAll: { isChooseAll: {
type: Boolean, type: Boolean,
default: false, default: false,
}, },
isReadOnly: { isReadOnly: {
type: Boolean, type: Boolean,
default: false, default: false,
}, },
provisionalApprover: { provisionalApprover: {
type: Boolean || undefined, type: Boolean || undefined,
default: undefined, default: undefined,
},
minApprover: {
type: Number,
default: null,
},
maxApprover: {
type: Number,
default: null,
},
maxCirculate: {
type: Number,
default: null,
},
minCirculate: {
type: Number,
default: null,
}, },
}); });
@ -155,19 +199,34 @@
} }
// 临时审批人 // 临时审批人
function changeProvisionalApprover(val: Boolean) { function changeProvisionalApprover(val: Boolean) {
emits('update:provisionalApprover', val); emits('update:provisionalApprover', val);
} }
// 多选 // 多选
function changeIsChooseMulti(val: Boolean) { function changeIsChooseMulti(val: Boolean) {
emits('update:isChooseMulti', val); emits('update:isChooseMulti', val);
} }
// 全选 // 全选
function changeIsChooseAll(val: Boolean) { function changeIsChooseAll(val: Boolean) {
emits('update:isChooseAll', val); emits('update:isChooseAll', val);
} }
// 只读 // 只读
function changeIsReadOnly(val: Boolean) { function changeIsReadOnly(val: Boolean) {
emits('update:isReadOnly', val); emits('update:isReadOnly', val);
}
function changeMaxCirculate(val: number) {
emits('update:maxCirculate', val);
}
//最少传阅人
function changeMinCirculate(val: number) {
emits('update:minCirculate', val);
}
// 最少审批人
function changeMinApprover(val: number) {
emits('update:minApprover', val);
}
// 最多审批人
function changeMaxApprover(val: number) {
emits('update:maxApprover', val);
} }
</script> </script>

View File

@ -0,0 +1,200 @@
<template>
<FormItem :label="t('自动同意:')">
<a-tree-select
:value="props.autoAgreeRule"
style="width: 100%"
:tree-data="autoAgreeRuleOptions"
tree-checkable
allow-clear
:placeholder="t('请选择自动同意规则')"
@change="changeAutoAgreeRule"
/>
</FormItem>
<FormItem :label="t('无处理人:')">
<a-select
:value="props.noHandler"
style="width: 100%"
:options="noHandlerOptions"
@change="changeNoHandler"
/>
</FormItem>
<FormItem :label="t('指定审批人:')">
<a-select
:value="props.isPrevChooseNext"
style="width: 100%"
:options="designatedApproverOptions"
@change="changeDesignatedApprover"
/>
</FormItem>
<FormItem
:tip="
t(
'临时审批人是指由上一节点审批人指定下一节点审批人过程中,是否允许在审批人基础上添加组织架构人员。',
)
"
:label="t('临时审批人:')"
>
<a-switch :checked="props.provisionalApprover" @change="changeProvisionalApprover" />
</FormItem>
<!-- 多选 / -->
<FormItem :label="t('多选:')">
<a-switch :checked="props.isChooseMulti" @change="changeIsChooseMulti" />
</FormItem>
<FormItem :label="t('全选:')">
<a-switch :checked="props.isChooseAll" @change="changeIsChooseAll" />
</FormItem>
<FormItem :label="t('只读:')">
<a-switch :checked="props.isReadOnly" @change="changeIsReadOnly" />
</FormItem>
<FormItem :label="t('审批人最多:')" >
<a-input-number
:value="maxApprover"
:min="0"
:max="100"
@change="changeMaxApprover"
/>
</FormItem>
<FormItem :label="t('审批人最少:')">
<a-input-number
:value="minApprover"
:min="0"
:max="100"
@change="changeMinApprover"
/>
</FormItem>
</template>
<script setup lang="ts" name="ProcessBasic">
import FormItem from '/@bpmn/layout/FormItem.vue';
import { AutoAgreeRule, DesignatedApprover, NoHandler } from '/@/enums/workflowEnum';
import { useI18n } from '/@/hooks/web/useI18n';
const { t } = useI18n();
const emits = defineEmits([
'update:autoAgreeRule',
'update:noHandler',
'update:isPrevChooseNext',
'update:provisionalApprover',
'update:isChooseMulti',
'update:isChooseAll',
'update:isReadOnly',
'update:minApprover',
'update:maxApprover',
]);
const props = defineProps({
autoAgreeRule: Array,
noHandler: Number || String || Boolean,
isPrevChooseNext: Number || String || Boolean,
isChooseMulti: {
type: Boolean,
default: true,
},
isChooseAll: {
type: Boolean,
default: false,
},
isReadOnly: {
type: Boolean,
default: false,
},
provisionalApprover: {
type: Boolean || undefined,
default: undefined,
},
minApprover: {
type: Number,
default: null,
},
maxApprover: {
type: Number,
default: null,
},
});
// 自动同意规则
const autoAgreeRuleOptions = [
{
value: AutoAgreeRule.ORIGINATOR,
label: t('候选审批人包含流程任务发起人'),
},
{
value: AutoAgreeRule.PREVIOUS_NODE,
label: t('候选审批人包含上一节点审批人'),
},
{
value: AutoAgreeRule.APPROVED,
label: t('候选审批人在此流程中审批过'),
},
];
function changeAutoAgreeRule(val: Array<AutoAgreeRule>) {
let autoAgreeRule = val;
if (val.length > 0) {
// 选择了自动同意规则后,无处理人 只能由 超级管理员处理 且 指定审批人 只能 不指定审批人
emits('update:noHandler', NoHandler.ADMIN);
emits('update:isPrevChooseNext', DesignatedApprover.NOT_SPECIFIED);
}
emits('update:autoAgreeRule', autoAgreeRule);
}
// 无处理人
const noHandlerOptions = [
{
value: NoHandler.ADMIN,
label: t('由超级管理员处理'),
},
{
value: NoHandler.PREVIOUS_NODE,
label: t('由上一节点审批人指定审批人'),
},
];
function changeNoHandler(val: NoHandler) {
emits('update:noHandler', val);
if (val == NoHandler.PREVIOUS_NODE) {
// 无处理人 选择了 由上一节点审批人指定审批人;那么自动同意规则必须为空
emits('update:autoAgreeRule', []);
}
}
// 指定审批人
const designatedApproverOptions = [
{
value: DesignatedApprover.NOT_SPECIFIED,
label: t('不指定审批人'),
},
{
value: DesignatedApprover.PREVIOUS_NODE,
label: t('由上一节点审批人指定'),
},
];
function changeDesignatedApprover(val: DesignatedApprover) {
emits('update:isPrevChooseNext', val);
if (val == DesignatedApprover.PREVIOUS_NODE) {
// 指定审批人 选择了 由上一节点审批人指定;那么自动同意规则必须为空
emits('update:autoAgreeRule', []);
}
}
// 临时审批人
function changeProvisionalApprover(val: Boolean) {
emits('update:provisionalApprover', val);
}
// 多选
function changeIsChooseMulti(val: Boolean) {
emits('update:isChooseMulti', val);
}
// 全选
function changeIsChooseAll(val: Boolean) {
emits('update:isChooseAll', val);
}
// 只读
function changeIsReadOnly(val: Boolean) {
emits('update:isReadOnly', val);
}
// 最少审批人
function changeMinApprover(val: number) {
emits('update:minApprover', val);
}
// 最多审批人
function changeMaxApprover(val: number) {
emits('update:maxApprover', val);
}
</script>
<style lang="less" scoped></style>

View File

@ -0,0 +1,76 @@
<template>
<FormItem
:tip="
t(
'临时传阅人是指由上一节点审批人指定下一节点传阅人过程中,是否允许在传阅人基础上添加组织架构人员。',
)
"
:label="t('临时传阅人:')"
>
<a-switch :checked="provisionalDistributor" @change="changeProvisionalDistributor" />
</FormItem>
<FormItem :label="t('传阅人最多:')">
<a-input-number
:value="maxCirculate"
:min="0"
:max="100"
@change="changeMaxCirculate"
/>
</FormItem>
<FormItem :label="t('传阅人最少:')">
<a-input-number
:value="minCirculate"
:min="0"
:max="100"
@change="changeMinCirculate"
/>
</FormItem>
</template>
<script setup lang="ts" name="ProcessBasic">
import FormItem from '/@bpmn/layout/FormItem.vue';
import { useI18n } from '/@/hooks/web/useI18n';
const { t } = useI18n();
const emits = defineEmits([
'update:provisionalDistributor',
'update:maxCirculate',
'update:minCirculate'
]);
const props = defineProps({
isChooseMulti: {
type: Boolean,
default: true,
},
isChooseAll: {
type: Boolean,
default: false,
},
provisionalDistributor: {
type: Boolean || undefined,
default: undefined,
},
maxCirculate: {
type: Number,
default: null,
},
minCirculate: {
type: Number,
default: null,
},
});
// 临时传阅人
function changeProvisionalDistributor(val: Boolean) {
emits('update:provisionalDistributor', val);
}
//最多传阅人
function changeMaxCirculate(val: number) {
emits('update:maxCirculate', val);
}
//最少传阅人
function changeMinCirculate(val: number) {
emits('update:minCirculate', val);
}
</script>
<style lang="less" scoped></style>

View File

@ -75,6 +75,10 @@ export const initProperties = (id: InfoId, type: InfoType, name: string, parentI
properties.autoAgreeRule = processInfo.autoAgreeRule; properties.autoAgreeRule = processInfo.autoAgreeRule;
properties.noHandler = processInfo.noHandler; properties.noHandler = processInfo.noHandler;
properties.isPrevChooseNext = processInfo.isPrevChooseNext; properties.isPrevChooseNext = processInfo.isPrevChooseNext;
properties.minApprover = processInfo.minApprover;
properties.maxApprover = processInfo.maxApprover;
properties.maxCirculate = processInfo.maxCirculate;
properties.minCirculate = processInfo.minCirculate;
} }
if (id === 'Activity_draft') { if (id === 'Activity_draft') {
// 将草稿节点的审批人设置为流程发起者 // 将草稿节点的审批人设置为流程发起者

View File

@ -46,6 +46,10 @@ export const processConfig: ProcessConfig = {
nameRule: '', //命名规则 nameRule: '', //命名规则
nameRuleConfigs: [], // 命名规则列表 nameRuleConfigs: [], // 命名规则列表
autoAgreeRule: [], //自动同意规则 autoAgreeRule: [], //自动同意规则
minApprover: '', //最少审批人
maxApprover: '', //最多审批人
maxCirculate: '', //最多传阅人
minCirculate: '', //最少传阅人
isPrevChooseNext: DesignatedApprover.NOT_SPECIFIED, //是否上一节点审批人指定下一节点审批人 isPrevChooseNext: DesignatedApprover.NOT_SPECIFIED, //是否上一节点审批人指定下一节点审批人
noHandler: NoHandler.ADMIN, //无对应处理人 noHandler: NoHandler.ADMIN, //无对应处理人
appShow: false, //移动端是否显示 appShow: false, //移动端是否显示
@ -144,9 +148,14 @@ const UserProperties: UserTaskConfig = {
autoAgreeRule: [], //自动同意规则 autoAgreeRule: [], //自动同意规则
isPrevChooseNext: DesignatedApprover.NOT_SPECIFIED, //是否上一节点审批人指定下一节点审批人 isPrevChooseNext: DesignatedApprover.NOT_SPECIFIED, //是否上一节点审批人指定下一节点审批人
provisionalApprover: false, //临时审批人 provisionalApprover: false, //临时审批人
provisionalDistributor: false, //临时传阅人
isChooseMulti: true, //是否多选 isChooseMulti: true, //是否多选
isChooseAll: false, //是否全选 isChooseAll: false, //是否全选
isReadOnly: false, //是否只读 isReadOnly: false, //是否只读
minApprover: '', //最少审批人
maxApprover: '', //最多审批人
maxCirculate: '', //最多传阅人
minCirculate: '', //最少传阅人
noHandler: NoHandler.ADMIN, //无对应处理人 noHandler: NoHandler.ADMIN, //无对应处理人
countersignConfig: { countersignConfig: {
multipleInstancesType: MultipleInstancesType.NONE, //多实例类型 multipleInstancesType: MultipleInstancesType.NONE, //多实例类型

View File

@ -18,7 +18,7 @@
</FormItem> </FormItem>
</template> </template>
<a-tab-pane key="2" :tab="t('审批人')"> <a-tab-pane key="2" :tab="t('审批人')">
<ApproveRules <ApproveUserRules
v-model:autoAgreeRule="formInfo.autoAgreeRule" v-model:autoAgreeRule="formInfo.autoAgreeRule"
v-model:noHandler="formInfo.noHandler" v-model:noHandler="formInfo.noHandler"
v-model:isPrevChooseNext="formInfo.isPrevChooseNext" v-model:isPrevChooseNext="formInfo.isPrevChooseNext"
@ -26,6 +26,8 @@
v-model:isChooseMulti="formInfo.isChooseMulti" v-model:isChooseMulti="formInfo.isChooseMulti"
v-model:isChooseAll="formInfo.isChooseAll" v-model:isChooseAll="formInfo.isChooseAll"
v-model:isReadOnly="formInfo.isReadOnly" v-model:isReadOnly="formInfo.isReadOnly"
v-model:minApprover="formInfo.minApprover"
v-model:maxApprover="formInfo.maxApprover"
/> />
<MemberTable <MemberTable
v-model:memberList="formInfo.approverConfigs" v-model:memberList="formInfo.approverConfigs"
@ -34,6 +36,11 @@
/> />
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="3" :tab="t('传阅人')"> <a-tab-pane key="3" :tab="t('传阅人')">
<MemberUserTable
v-model:provisionalDistributor="formInfo.provisionalDistributor"
v-model:maxCirculate="formInfo.maxCirculate"
v-model:minCirculate="formInfo.minCirculate"
/>
<MemberTable <MemberTable
v-model:memberList="formInfo.circulateConfigs" v-model:memberList="formInfo.circulateConfigs"
:is-common-type="false" :is-common-type="false"
@ -56,7 +63,8 @@
import NoticePolicyConfig from '/@bpmn/components/NoticePolicyConfig.vue'; import NoticePolicyConfig from '/@bpmn/components/NoticePolicyConfig.vue';
import SettingList from '/@bpmn/components/formSettings/SettingList.vue'; import SettingList from '/@bpmn/components/formSettings/SettingList.vue';
import MemberTable from '/@bpmn/components/member/MemberTable.vue'; import MemberTable from '/@bpmn/components/member/MemberTable.vue';
import ApproveRules from '/@bpmn/components/ApproveRules.vue'; import MemberUserTable from '/@bpmn/components/member/MemberUserTable.vue';
import ApproveUserRules from '/@bpmn/components/ApproveUserRules.vue';
import Countersign from './user/Countersign.vue'; import Countersign from './user/Countersign.vue';
import ButtonSetting from './user/ButtonSetting.vue'; import ButtonSetting from './user/ButtonSetting.vue';
import OpinionConfig from './user/OpinionConfig.vue'; import OpinionConfig from './user/OpinionConfig.vue';

View File

@ -28,6 +28,14 @@
v-model:autoAgreeRule="processInfo.autoAgreeRule" v-model:autoAgreeRule="processInfo.autoAgreeRule"
v-model:noHandler="processInfo.noHandler" v-model:noHandler="processInfo.noHandler"
v-model:isPrevChooseNext="processInfo.isPrevChooseNext" v-model:isPrevChooseNext="processInfo.isPrevChooseNext"
v-model:provisionalApprover="processInfo.provisionalApprover"
v-model:isChooseMulti="processInfo.isChooseMulti"
v-model:isChooseAll="processInfo.isChooseAll"
v-model:isReadOnly="processInfo.isReadOnly"
v-model:minApprover="processInfo.minApprover"
v-model:maxApprover="processInfo.maxApprover"
v-model:maxCirculate="processInfo.maxCirculate"
v-model:minCirculate="processInfo.minCirculate"
/> />
<FormItem :tip="t('配置默认表单后,用户任务节点均会包含该表单')" :label="t('默认表单:')"> <FormItem :tip="t('配置默认表单后,用户任务节点均会包含该表单')" :label="t('默认表单:')">
<SettingDefaultForm /> <SettingDefaultForm />

View File

@ -168,7 +168,7 @@ if (props.canClick) {
.flow-record-box { .flow-record-box {
width: 100%; width: 100%;
height: 80vh; height: 65vh;
position: relative; position: relative;
margin-top: 50px; margin-top: 50px;
} }

View File

@ -43,16 +43,32 @@
const { t } = useI18n(); const { t } = useI18n();
const configColumns: BasicColumn[] = [ const configColumns: BasicColumn[] = [
{ {
title: t('流程名称'), title: t('流程定义名称'),
dataIndex: 'schemaName', dataIndex: 'schemaName',
align: 'left', align: 'left',
}, },
{ {
title: t('发起者'), title: t('任务名称'),
dataIndex: 'taskName',
align: 'left',
},
{
title: t('流程待办名称'),
dataIndex: 'processName',
align: 'left',
},
{
title: t('流程发起者'),
dataIndex: 'originator', dataIndex: 'originator',
sorter: true, sorter: true,
align: 'left', align: 'left',
}, },
{
title: t('创建人'),
dataIndex: 'createUserName',
sorter: true,
align: 'left',
},
{ {
title: t('发起时间'), title: t('发起时间'),
dataIndex: 'createDate', dataIndex: 'createDate',

View File

@ -27,16 +27,32 @@ const { t } = useI18n();
const router = useRouter(); const router = useRouter();
const configColumns = [ const configColumns = [
{ {
title: t('流程名称'), title: t('流程定义名称'),
dataIndex: 'schemaName', dataIndex: 'schemaName',
align: 'left' align: 'left'
}, },
{ {
title: t('发起者'), title: t('任务名称'),
dataIndex: 'taskName',
align: 'left',
},
{
title: t('流程待办名称'),
dataIndex: 'processName',
align: 'left',
},
{
title: t('流程发起者'),
dataIndex: 'originator', dataIndex: 'originator',
sorter: true, sorter: true,
align: 'left' align: 'left'
}, },
{
title: t('创建人'),
dataIndex: 'createUserName',
sorter: true,
align: 'left',
},
{ {
title: t('发起时间'), title: t('发起时间'),
dataIndex: 'createDate', dataIndex: 'createDate',

4
types/config.d.ts vendored
View File

@ -163,8 +163,8 @@ export interface GlobEnvConfig {
//file preview //file preview
VITE_GLOB_UPLOAD_PREVIEW?: string; VITE_GLOB_UPLOAD_PREVIEW?: string;
VITE_GLOB_REPORT_URL: string; VITE_GLOB_REPORT_URL: string;
VITE_TENANT_ENABLED: boolean; VITE_GLOB_TENANT_ENABLED: boolean;
VITE_CLOSE_ALERT_DISABLED: boolean; VITE_GLOB_CLOSE_ALERT_DISABLED: boolean;
} }
export interface LogoConfig { export interface LogoConfig {