!195 发布 5.3.1-BETA_2.3.0-BETA 公测版本
Merge pull request !195 from 疯狂的狮子Li/dev
This commit is contained in:
commit
b23b123613
@ -1,46 +1,25 @@
|
||||
{
|
||||
"globals": {
|
||||
"ComponentInternalInstance": true,
|
||||
"TransferKey": true,
|
||||
"ElFormRules": true,
|
||||
"CheckboxValueType": true,
|
||||
"PropType": true,
|
||||
"DateModelType": true,
|
||||
"UploadFile": true,
|
||||
"ElFormInstance": true,
|
||||
"ElTableInstance": true,
|
||||
"ElTreeInstance": true,
|
||||
"ElTreeSelectInstance": true,
|
||||
"ElSelectInstance": true,
|
||||
"ElUploadInstance": true,
|
||||
"ElCardInstance": true,
|
||||
"ElDialogInstance": true,
|
||||
"ElInputInstance": true,
|
||||
"ElInputNumberInstance": true,
|
||||
"ElRadioInstance": true,
|
||||
"ElRadioGroupInstance": true,
|
||||
"ElRadioButtonInstance": true,
|
||||
"ElCheckboxInstance": true,
|
||||
"ElCheckboxGroupInstance": true,
|
||||
"ElSwitchInstance": true,
|
||||
"ElDatePickerInstance": true,
|
||||
"ElTimePickerInstance": true,
|
||||
"ElTimeSelectInstance": true,
|
||||
"ElScrollbarInstance": true,
|
||||
"ElCascaderInstance": true,
|
||||
"ElColorPickerInstance": true,
|
||||
"ElRateInstance": true,
|
||||
"ElSliderInstance": true,
|
||||
"useRouter": true,
|
||||
"useRoute": true,
|
||||
"Component": true,
|
||||
"ComponentPublicInstance": true,
|
||||
"ComputedRef": true,
|
||||
"DirectiveBinding": true,
|
||||
"EffectScope": true,
|
||||
"ElTable": true,
|
||||
"ElSelect": true,
|
||||
"ElUpload": true,
|
||||
"ElForm": true,
|
||||
"ElTree": true,
|
||||
"ElLoading": true,
|
||||
"ElMessage": true,
|
||||
"ElMessageBox": true,
|
||||
"ElNotification": true,
|
||||
"ExtractDefaultPropTypes": true,
|
||||
"ExtractPropTypes": true,
|
||||
"ExtractPublicPropTypes": true,
|
||||
"InjectionKey": true,
|
||||
"MaybeRef": true,
|
||||
"MaybeRefOrGetter": true,
|
||||
"PropType": true,
|
||||
"Ref": true,
|
||||
"VNode": true,
|
||||
"WritableComputedRef": true,
|
||||
"acceptHMRUpdate": true,
|
||||
"asyncComputed": true,
|
||||
"autoResetRef": true,
|
||||
"computed": true,
|
||||
@ -54,36 +33,50 @@
|
||||
"createEventHook": true,
|
||||
"createGlobalState": true,
|
||||
"createInjectionState": true,
|
||||
"createPinia": true,
|
||||
"createReactiveFn": true,
|
||||
"createReusableTemplate": true,
|
||||
"createSharedComposable": true,
|
||||
"createTemplatePromise": true,
|
||||
"createUnrefFn": true,
|
||||
"customRef": true,
|
||||
"debouncedRef": true,
|
||||
"debouncedWatch": true,
|
||||
"defineAsyncComponent": true,
|
||||
"defineComponent": true,
|
||||
"defineStore": true,
|
||||
"eagerComputed": true,
|
||||
"effectScope": true,
|
||||
"extendRef": true,
|
||||
"getActivePinia": true,
|
||||
"getCurrentInstance": true,
|
||||
"getCurrentScope": true,
|
||||
"h": true,
|
||||
"ignorableWatch": true,
|
||||
"inject": true,
|
||||
"injectLocal": true,
|
||||
"isDefined": true,
|
||||
"isProxy": true,
|
||||
"isReactive": true,
|
||||
"isReadonly": true,
|
||||
"isRef": true,
|
||||
"makeDestructurable": true,
|
||||
"mapActions": true,
|
||||
"mapGetters": true,
|
||||
"mapState": true,
|
||||
"mapStores": true,
|
||||
"mapWritableState": true,
|
||||
"markRaw": true,
|
||||
"nextTick": true,
|
||||
"onActivated": true,
|
||||
"onBeforeMount": true,
|
||||
"onBeforeRouteLeave": true,
|
||||
"onBeforeRouteUpdate": true,
|
||||
"onBeforeUnmount": true,
|
||||
"onBeforeUpdate": true,
|
||||
"onClickOutside": true,
|
||||
"onDeactivated": true,
|
||||
"onElementRemoval": true,
|
||||
"onErrorCaptured": true,
|
||||
"onKeyStroke": true,
|
||||
"onLongPress": true,
|
||||
@ -95,8 +88,10 @@
|
||||
"onStartTyping": true,
|
||||
"onUnmounted": true,
|
||||
"onUpdated": true,
|
||||
"onWatcherCleanup": true,
|
||||
"pausableWatch": true,
|
||||
"provide": true,
|
||||
"provideLocal": true,
|
||||
"reactify": true,
|
||||
"reactifyObject": true,
|
||||
"reactive": true,
|
||||
@ -111,12 +106,14 @@
|
||||
"refThrottled": true,
|
||||
"refWithControl": true,
|
||||
"resolveComponent": true,
|
||||
"resolveDirective": true,
|
||||
"resolveRef": true,
|
||||
"resolveUnref": true,
|
||||
"setActivePinia": true,
|
||||
"setMapStoreSuffix": true,
|
||||
"shallowReactive": true,
|
||||
"shallowReadonly": true,
|
||||
"shallowRef": true,
|
||||
"storeToRefs": true,
|
||||
"syncRef": true,
|
||||
"syncRefs": true,
|
||||
"templateRef": true,
|
||||
@ -126,6 +123,7 @@
|
||||
"toReactive": true,
|
||||
"toRef": true,
|
||||
"toRefs": true,
|
||||
"toValue": true,
|
||||
"triggerRef": true,
|
||||
"tryOnBeforeMount": true,
|
||||
"tryOnBeforeUnmount": true,
|
||||
@ -136,11 +134,14 @@
|
||||
"unrefElement": true,
|
||||
"until": true,
|
||||
"useActiveElement": true,
|
||||
"useAnimate": true,
|
||||
"useArrayDifference": true,
|
||||
"useArrayEvery": true,
|
||||
"useArrayFilter": true,
|
||||
"useArrayFind": true,
|
||||
"useArrayFindIndex": true,
|
||||
"useArrayFindLast": true,
|
||||
"useArrayIncludes": true,
|
||||
"useArrayJoin": true,
|
||||
"useArrayMap": true,
|
||||
"useArrayReduce": true,
|
||||
@ -157,9 +158,11 @@
|
||||
"useBrowserLocation": true,
|
||||
"useCached": true,
|
||||
"useClipboard": true,
|
||||
"useClipboardItems": true,
|
||||
"useCloned": true,
|
||||
"useColorMode": true,
|
||||
"useConfirmDialog": true,
|
||||
"useCountdown": true,
|
||||
"useCounter": true,
|
||||
"useCssModule": true,
|
||||
"useCssVar": true,
|
||||
@ -198,6 +201,7 @@
|
||||
"useFullscreen": true,
|
||||
"useGamepad": true,
|
||||
"useGeolocation": true,
|
||||
"useId": true,
|
||||
"useIdle": true,
|
||||
"useImage": true,
|
||||
"useInfiniteScroll": true,
|
||||
@ -206,6 +210,7 @@
|
||||
"useIntervalFn": true,
|
||||
"useKeyModifier": true,
|
||||
"useLastChanged": true,
|
||||
"useLink": true,
|
||||
"useLocalStorage": true,
|
||||
"useMagicKeys": true,
|
||||
"useManualRefHistory": true,
|
||||
@ -213,6 +218,7 @@
|
||||
"useMediaQuery": true,
|
||||
"useMemoize": true,
|
||||
"useMemory": true,
|
||||
"useModel": true,
|
||||
"useMounted": true,
|
||||
"useMouse": true,
|
||||
"useMouseInElement": true,
|
||||
@ -226,6 +232,8 @@
|
||||
"useOnline": true,
|
||||
"usePageLeave": true,
|
||||
"useParallax": true,
|
||||
"useParentElement": true,
|
||||
"usePerformanceObserver": true,
|
||||
"usePermission": true,
|
||||
"usePointer": true,
|
||||
"usePointerLock": true,
|
||||
@ -235,10 +243,14 @@
|
||||
"usePreferredDark": true,
|
||||
"usePreferredLanguages": true,
|
||||
"usePreferredReducedMotion": true,
|
||||
"usePreferredReducedTransparency": true,
|
||||
"usePrevious": true,
|
||||
"useRafFn": true,
|
||||
"useRefHistory": true,
|
||||
"useResizeObserver": true,
|
||||
"useRoute": true,
|
||||
"useRouter": true,
|
||||
"useSSRWidth": true,
|
||||
"useScreenOrientation": true,
|
||||
"useScreenSafeArea": true,
|
||||
"useScriptTag": true,
|
||||
@ -256,6 +268,7 @@
|
||||
"useStyleTag": true,
|
||||
"useSupported": true,
|
||||
"useSwipe": true,
|
||||
"useTemplateRef": true,
|
||||
"useTemplateRefsList": true,
|
||||
"useTextDirection": true,
|
||||
"useTextSelection": true,
|
||||
@ -291,8 +304,10 @@
|
||||
"watchArray": true,
|
||||
"watchAtMost": true,
|
||||
"watchDebounced": true,
|
||||
"watchDeep": true,
|
||||
"watchEffect": true,
|
||||
"watchIgnorable": true,
|
||||
"watchImmediate": true,
|
||||
"watchOnce": true,
|
||||
"watchPausable": true,
|
||||
"watchPostEffect": true,
|
||||
@ -300,13 +315,6 @@
|
||||
"watchThrottled": true,
|
||||
"watchTriggerable": true,
|
||||
"watchWithFilter": true,
|
||||
"whenever": true,
|
||||
"ImportOption": true,
|
||||
"TreeType": true,
|
||||
"FieldOption": true,
|
||||
"PageData": true,
|
||||
"storeToRefs": true,
|
||||
"DictDataOption": true,
|
||||
"UploadOption": true
|
||||
"whenever": true
|
||||
}
|
||||
}
|
||||
|
@ -1,86 +0,0 @@
|
||||
import globals from 'globals';
|
||||
import pluginJs from '@eslint/js';
|
||||
import tseslint from 'typescript-eslint';
|
||||
import pluginVue from 'eslint-plugin-vue';
|
||||
import { readFile } from 'node:fs/promises';
|
||||
import prettier from 'eslint-plugin-prettier';
|
||||
|
||||
/**
|
||||
* https://blog.csdn.net/sayUonly/article/details/123482912
|
||||
* 自动导入的配置
|
||||
*/
|
||||
const autoImportFile = new URL('./.eslintrc-auto-import.json', import.meta.url);
|
||||
const autoImportGlobals = JSON.parse(await readFile(autoImportFile, 'utf8'));
|
||||
|
||||
/** @type {import('eslint').Linter.Config[]} */
|
||||
export default [
|
||||
{
|
||||
/**
|
||||
* 不需要.eslintignore文件 而是在这里配置
|
||||
*/
|
||||
ignores: [
|
||||
'*.sh',
|
||||
'node_modules',
|
||||
'*.md',
|
||||
'*.woff',
|
||||
'*.ttf',
|
||||
'.vscode',
|
||||
'.idea',
|
||||
'dist',
|
||||
'/public',
|
||||
'/docs',
|
||||
'.husky',
|
||||
'.local',
|
||||
'/bin',
|
||||
'.eslintrc.cjs',
|
||||
'prettier.config.js',
|
||||
'src/assets',
|
||||
'tailwind.config.js'
|
||||
]
|
||||
},
|
||||
{ files: ['**/*.{js,mjs,cjs,ts,vue}'] },
|
||||
{
|
||||
languageOptions: {
|
||||
globals: globals.browser
|
||||
}
|
||||
},
|
||||
pluginJs.configs.recommended,
|
||||
...tseslint.configs.recommended,
|
||||
...pluginVue.configs['flat/essential'],
|
||||
{
|
||||
files: ['**/*.vue'],
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
parser: tseslint.parser
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
languageOptions: {
|
||||
globals: {
|
||||
// 自动导入的配置 undef
|
||||
...autoImportGlobals.globals,
|
||||
DialogOption: 'readonly',
|
||||
LayoutSetting: 'readonly'
|
||||
}
|
||||
},
|
||||
plugins: { prettier },
|
||||
rules: {
|
||||
'@typescript-eslint/no-empty-function': 'off',
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'@typescript-eslint/no-unused-vars': 'off',
|
||||
'@typescript-eslint/no-this-alias': 'off',
|
||||
|
||||
// vue
|
||||
'vue/multi-word-component-names': 'off',
|
||||
'vue/valid-define-props': 'off',
|
||||
'vue/no-v-model-argument': 'off',
|
||||
'prefer-rest-params': 'off',
|
||||
// prettier
|
||||
'prettier/prettier': 'error',
|
||||
// 允许使用空Object类型 {}
|
||||
'@typescript-eslint/no-empty-object-type': 'off',
|
||||
'@typescript-eslint/no-unused-expressions': 'off'
|
||||
}
|
||||
}
|
||||
];
|
44
eslint.config.ts
Normal file
44
eslint.config.ts
Normal file
@ -0,0 +1,44 @@
|
||||
import pluginVue from 'eslint-plugin-vue';
|
||||
import globals from 'globals';
|
||||
import prettier from 'eslint-plugin-prettier';
|
||||
import { defineConfigWithVueTs, vueTsConfigs } from '@vue/eslint-config-typescript';
|
||||
import skipFormatting from '@vue/eslint-config-prettier/skip-formatting';
|
||||
|
||||
export default defineConfigWithVueTs(
|
||||
{
|
||||
name: 'app/files-to-lint',
|
||||
files: ['**/*.{js,cjs,ts,mts,tsx,vue}']
|
||||
},
|
||||
|
||||
{
|
||||
name: 'app/files-to-ignore',
|
||||
ignores: ['**/dist/**', '**/dist-ssr/**', '**/coverage/**']
|
||||
},
|
||||
{
|
||||
languageOptions: {
|
||||
globals: globals.browser
|
||||
}
|
||||
},
|
||||
pluginVue.configs['flat/essential'],
|
||||
vueTsConfigs.recommended,
|
||||
skipFormatting,
|
||||
{
|
||||
plugins: { prettier },
|
||||
rules: {
|
||||
'@typescript-eslint/no-empty-function': 'off',
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'@typescript-eslint/no-unused-vars': 'off',
|
||||
'@typescript-eslint/no-this-alias': 'off',
|
||||
// vue
|
||||
'vue/multi-word-component-names': 'off',
|
||||
'vue/valid-define-props': 'off',
|
||||
'vue/no-v-model-argument': 'off',
|
||||
'prefer-rest-params': 'off',
|
||||
// prettier
|
||||
'prettier/prettier': 'error',
|
||||
// 允许使用空Object类型 {}
|
||||
'@typescript-eslint/no-empty-object-type': 'off',
|
||||
'@typescript-eslint/no-unused-expressions': 'off'
|
||||
}
|
||||
}
|
||||
);
|
63
package.json
63
package.json
@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"$schema": "https://json.schemastore.org/package",
|
||||
"name": "ruoyi-vue-plus",
|
||||
"version": "5.3.0",
|
||||
"version": "5.3.1-BETA_2.3.0-BETA",
|
||||
"description": "RuoYi-Vue-Plus多租户管理系统",
|
||||
"author": "LionLi",
|
||||
"license": "MIT",
|
||||
@ -23,13 +23,11 @@
|
||||
"@element-plus/icons-vue": "2.3.1",
|
||||
"@highlightjs/vue-plugin": "2.1.0",
|
||||
"@vueup/vue-quill": "1.2.0",
|
||||
"@vueuse/core": "11.3.0",
|
||||
"@vueuse/core": "12.7.0",
|
||||
"animate.css": "4.1.1",
|
||||
"await-to-js": "3.0.0",
|
||||
"axios": "1.7.8",
|
||||
"crypto-js": "4.2.0",
|
||||
"diagram-js": "12.3.0",
|
||||
"didi": "9.0.2",
|
||||
"echarts": "5.5.0",
|
||||
"element-plus": "2.8.8",
|
||||
"file-saver": "2.0.5",
|
||||
@ -50,38 +48,47 @@
|
||||
"vxe-table": "4.5.22"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "9.15.0",
|
||||
"@iconify/json": "2.2.276",
|
||||
"@types/crypto-js": "4.2.2",
|
||||
"@types/file-saver": "2.0.7",
|
||||
"@types/js-cookie": "3.0.6",
|
||||
"@types/node": "18.18.2",
|
||||
"@types/node": "^22.13.4",
|
||||
"@types/nprogress": "0.2.3",
|
||||
"@unocss/preset-attributify": "0.64.1",
|
||||
"@unocss/preset-icons": "0.64.1",
|
||||
"@unocss/preset-uno": "0.64.1",
|
||||
"@vitejs/plugin-vue": "5.0.4",
|
||||
"@unocss/preset-attributify": "66.0.0",
|
||||
"@unocss/preset-icons": "66.0.0",
|
||||
"@unocss/preset-uno": "66.0.0",
|
||||
"@vitejs/plugin-vue": "5.2.1",
|
||||
"@vue/compiler-sfc": "3.4.23",
|
||||
"autoprefixer": "10.4.18",
|
||||
"eslint": "9.15.0",
|
||||
"eslint-plugin-prettier": "^5.2.1",
|
||||
"eslint-plugin-vue": "9.31.0",
|
||||
"fast-glob": "3.3.2",
|
||||
"globals": "15.12.0",
|
||||
"postcss": "8.4.36",
|
||||
"prettier": "3.2.5",
|
||||
"sass": "1.72.0",
|
||||
"typescript": "5.7.2",
|
||||
"typescript-eslint": "8.16.0",
|
||||
"unocss": "0.64.1",
|
||||
"@vue/eslint-config-prettier": "10.2.0",
|
||||
"@vue/eslint-config-typescript": "14.4.0",
|
||||
"autoprefixer": "10.4.20",
|
||||
"eslint": "9.21.0",
|
||||
"eslint-plugin-prettier": "5.2.3",
|
||||
"eslint-plugin-vue": "9.32.0",
|
||||
"globals": "16.0.0",
|
||||
"prettier": "3.5.2",
|
||||
"sass": "1.84.0",
|
||||
"typescript": "~5.7.3",
|
||||
"unocss": "66.0.0",
|
||||
"unplugin-auto-import": "0.17.5",
|
||||
"unplugin-icons": "0.18.5",
|
||||
"unplugin-vue-components": "0.26.0",
|
||||
"unplugin-vue-components": "28.0.0",
|
||||
"unplugin-vue-setup-extend-plus": "1.0.1",
|
||||
"vite": "5.4.11",
|
||||
"vite-plugin-compression": "0.5.1",
|
||||
"vite-plugin-svg-icons": "2.0.1",
|
||||
"vitest": "1.5.0",
|
||||
"vue-tsc": "2.0.13"
|
||||
}
|
||||
"vite-plugin-svg-icons-ng": "^1.2.2",
|
||||
"vite-plugin-vue-devtools": "7.7.1",
|
||||
"vitest": "3.0.5",
|
||||
"vue-tsc": "^2.2.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.18.0",
|
||||
"npm": ">=8.9.0"
|
||||
},
|
||||
"browserslist": [
|
||||
"Chrome >= 87",
|
||||
"Edge >= 88",
|
||||
"Safari >= 14",
|
||||
"Firefox >= 78"
|
||||
]
|
||||
}
|
||||
|
@ -5,9 +5,9 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import useSettingsStore from '@/store/modules/settings';
|
||||
import { useSettingsStore } from '@/store/modules/settings';
|
||||
import { handleThemeStyle } from '@/utils/theme';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
import { useAppStore } from '@/store/modules/app';
|
||||
|
||||
const appStore = useAppStore();
|
||||
|
||||
|
@ -19,6 +19,7 @@ export interface UserQuery extends PageQuery {
|
||||
status?: string;
|
||||
deptId?: string | number;
|
||||
roleId?: string | number;
|
||||
userIds?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -6,7 +6,6 @@ export interface CategoryTreeVO {
|
||||
children: CategoryTreeVO[];
|
||||
}
|
||||
export interface CategoryVO {
|
||||
|
||||
/**
|
||||
* 流程分类ID
|
||||
*/
|
||||
@ -39,7 +38,6 @@ export interface CategoryVO {
|
||||
}
|
||||
|
||||
export interface CategoryForm extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 流程分类ID
|
||||
*/
|
||||
@ -59,14 +57,11 @@ export interface CategoryForm extends BaseEntity {
|
||||
* 显示顺序
|
||||
*/
|
||||
orderNum?: number;
|
||||
|
||||
}
|
||||
|
||||
export interface CategoryQuery {
|
||||
|
||||
/**
|
||||
* 流程分类名称
|
||||
*/
|
||||
categoryName?: string;
|
||||
|
||||
}
|
||||
|
@ -178,3 +178,16 @@ export const currentTaskAllUser = (taskId: string | number) => {
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取下一节点写
|
||||
* @param data参数
|
||||
* @returns
|
||||
*/
|
||||
export const getNextNodeList = (data: any): any => {
|
||||
return request({
|
||||
url: '/workflow/task/getNextNodeList',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
@ -29,8 +29,14 @@ export interface FlowTaskVO {
|
||||
nodeType: number;
|
||||
nodeRatio: string | number;
|
||||
version?: string;
|
||||
applyNode?: boolean;
|
||||
buttonList?: buttonList[];
|
||||
}
|
||||
|
||||
export interface buttonList {
|
||||
code: string;
|
||||
show: boolean;
|
||||
}
|
||||
export interface VariableVo {
|
||||
key: string;
|
||||
value: string;
|
||||
|
@ -1 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1588670460195" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1314" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M230.4 307.712c13.824 0 25.088-11.264 25.088-25.088 0-100.352 81.92-182.272 182.272-182.272s182.272 81.408 182.272 182.272c0 13.824 11.264 25.088 25.088 25.088s25.088-11.264 24.576-25.088c0-127.488-103.936-231.936-231.936-231.936S205.824 154.624 205.824 282.624c-0.512 14.336 10.752 25.088 24.576 25.088z m564.736 234.496c-11.264 0-21.504 2.048-31.232 6.144 0-44.544-40.448-81.92-88.064-81.92-14.848 0-28.16 3.584-39.936 10.24-13.824-28.16-44.544-48.128-78.848-48.128-12.288 0-24.576 2.56-35.328 7.68V284.16c0-45.568-37.888-81.92-84.48-81.92s-84.48 36.864-84.48 81.92v348.672l-69.12-112.64c-18.432-28.16-58.368-36.864-91.136-19.968-26.624 14.336-46.592 47.104-30.208 88.064 3.072 8.192 76.8 205.312 171.52 311.296 0 0 28.16 24.576 43.008 58.88 4.096 9.728 13.312 15.36 22.528 15.36 3.072 0 6.656-0.512 9.728-2.048 12.288-5.12 18.432-19.968 12.8-32.256-19.456-44.544-53.76-74.752-53.76-74.752C281.6 768 209.408 573.44 208.384 570.88c-5.12-12.8-2.56-20.992 7.168-26.112 9.216-4.608 21.504-4.608 26.112 2.56l113.152 184.32c4.096 8.704 12.8 14.336 22.528 14.336 13.824 0 25.088-10.752 25.088-25.088V284.16c0-17.92 15.36-32.256 34.816-32.256s34.816 14.336 34.816 32.256v284.16c0 13.824 10.24 25.088 24.576 25.088 13.824 0 25.088-11.264 25.088-25.088v-57.344c0-17.92 15.36-32.768 34.816-32.768 19.968 0 37.376 15.36 37.376 32.768v95.232c0 7.168 3.072 13.312 7.68 17.92 4.608 4.608 10.752 7.168 17.92 7.168 13.824 0 24.576-11.264 24.576-25.088V547.84c0-18.432 13.824-32.256 32.256-32.256 20.48 0 38.912 15.36 38.912 32.256v95.232c0 13.824 11.264 25.088 25.088 25.088s24.576-11.264 25.088-25.088v-18.944c0-18.944 12.8-32.256 30.72-32.256 18.432 0 22.528 18.944 22.528 31.744 0 1.024-11.776 99.84-50.688 173.056-30.72 58.368-45.056 112.128-51.2 146.944-2.56 13.312 6.656 26.112 19.968 28.672 1.536 0 3.072 0.512 4.608 0.512 11.776 0 22.016-8.192 24.064-20.48 5.632-31.232 18.432-79.36 46.08-132.608 43.52-81.92 55.808-186.88 56.32-193.536-0.512-50.688-29.696-83.968-72.704-83.968z"></path></path></svg>
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1588670460195" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1314" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M230.4 307.712c13.824 0 25.088-11.264 25.088-25.088 0-100.352 81.92-182.272 182.272-182.272s182.272 81.408 182.272 182.272c0 13.824 11.264 25.088 25.088 25.088s25.088-11.264 24.576-25.088c0-127.488-103.936-231.936-231.936-231.936S205.824 154.624 205.824 282.624c-0.512 14.336 10.752 25.088 24.576 25.088z m564.736 234.496c-11.264 0-21.504 2.048-31.232 6.144 0-44.544-40.448-81.92-88.064-81.92-14.848 0-28.16 3.584-39.936 10.24-13.824-28.16-44.544-48.128-78.848-48.128-12.288 0-24.576 2.56-35.328 7.68V284.16c0-45.568-37.888-81.92-84.48-81.92s-84.48 36.864-84.48 81.92v348.672l-69.12-112.64c-18.432-28.16-58.368-36.864-91.136-19.968-26.624 14.336-46.592 47.104-30.208 88.064 3.072 8.192 76.8 205.312 171.52 311.296 0 0 28.16 24.576 43.008 58.88 4.096 9.728 13.312 15.36 22.528 15.36 3.072 0 6.656-0.512 9.728-2.048 12.288-5.12 18.432-19.968 12.8-32.256-19.456-44.544-53.76-74.752-53.76-74.752C281.6 768 209.408 573.44 208.384 570.88c-5.12-12.8-2.56-20.992 7.168-26.112 9.216-4.608 21.504-4.608 26.112 2.56l113.152 184.32c4.096 8.704 12.8 14.336 22.528 14.336 13.824 0 25.088-10.752 25.088-25.088V284.16c0-17.92 15.36-32.256 34.816-32.256s34.816 14.336 34.816 32.256v284.16c0 13.824 10.24 25.088 24.576 25.088 13.824 0 25.088-11.264 25.088-25.088v-57.344c0-17.92 15.36-32.768 34.816-32.768 19.968 0 37.376 15.36 37.376 32.768v95.232c0 7.168 3.072 13.312 7.68 17.92 4.608 4.608 10.752 7.168 17.92 7.168 13.824 0 24.576-11.264 24.576-25.088V547.84c0-18.432 13.824-32.256 32.256-32.256 20.48 0 38.912 15.36 38.912 32.256v95.232c0 13.824 11.264 25.088 25.088 25.088s24.576-11.264 25.088-25.088v-18.944c0-18.944 12.8-32.256 30.72-32.256 18.432 0 22.528 18.944 22.528 31.744 0 1.024-11.776 99.84-50.688 173.056-30.72 58.368-45.056 112.128-51.2 146.944-2.56 13.312 6.656 26.112 19.968 28.672 1.536 0 3.072 0.512 4.608 0.512 11.776 0 22.016-8.192 24.064-20.48 5.632-31.232 18.432-79.36 46.08-132.608 43.52-81.92 55.808-186.88 56.32-193.536-0.512-50.688-29.696-83.968-72.704-83.968z"></path></svg>
|
||||
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
@ -1,4 +1,4 @@
|
||||
@import './variables.module.scss';
|
||||
@use './variables.module.scss' as *;
|
||||
|
||||
@mixin colorBtn($color) {
|
||||
background: $color;
|
||||
|
@ -1,12 +1,12 @@
|
||||
@import './variables.module.scss';
|
||||
@import './mixin.scss';
|
||||
@import './transition.scss';
|
||||
@import './element-ui.scss';
|
||||
@import './sidebar.scss';
|
||||
@import './btn.scss';
|
||||
@import './ruoyi.scss';
|
||||
@import 'animate.css';
|
||||
@import 'element-plus/dist/index.css';
|
||||
@use './variables.module.scss' as *;
|
||||
@use './mixin.scss';
|
||||
@use './transition.scss';
|
||||
@use './element-ui.scss';
|
||||
@use './sidebar.scss';
|
||||
@use './btn.scss';
|
||||
@use './ruoyi.scss';
|
||||
@use 'animate.css';
|
||||
@use 'element-plus/dist/index.css';
|
||||
|
||||
body {
|
||||
height: 100%;
|
||||
@ -162,10 +162,6 @@ aside {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.pagination-container {
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
@use './variables.module.scss' as *;
|
||||
|
||||
/**
|
||||
* 通用css样式布局处理
|
||||
* Copyright (c) 2019 ruoyi
|
||||
@ -114,10 +116,9 @@ h6 {
|
||||
|
||||
/** 表格布局 **/
|
||||
.pagination-container {
|
||||
// position: relative;
|
||||
height: 25px;
|
||||
margin-bottom: 10px;
|
||||
margin-top: 15px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 20px;
|
||||
padding: 10px 20px !important;
|
||||
}
|
||||
|
||||
@ -130,11 +131,6 @@ h6 {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.pagination-container .el-pagination {
|
||||
//right: 0;
|
||||
//position: absolute;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.pagination-container .el-pagination > .el-pagination__jump {
|
||||
display: none !important;
|
||||
@ -201,8 +197,6 @@ h6 {
|
||||
}
|
||||
|
||||
.card-box {
|
||||
padding-right: 15px;
|
||||
padding-left: 15px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
@use './variables.module.scss' as *;
|
||||
|
||||
#app {
|
||||
.main-container {
|
||||
height: 100%;
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { RouteLocationMatched } from 'vue-router';
|
||||
import usePermissionStore from '@/store/modules/permission';
|
||||
import { usePermissionStore } from '@/store/modules/permission';
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
@ -87,7 +87,7 @@ const handleArray = (array: Array<string | number>) => {
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
<style lang="scss" scoped>
|
||||
.el-tag + .el-tag {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
@ -7,18 +7,20 @@
|
||||
:before-upload="handleBeforeUpload"
|
||||
:file-list="fileList"
|
||||
:limit="limit"
|
||||
:accept="fileAccept"
|
||||
:on-error="handleUploadError"
|
||||
:on-exceed="handleExceed"
|
||||
:on-success="handleUploadSuccess"
|
||||
:show-file-list="false"
|
||||
:headers="headers"
|
||||
class="upload-file-uploader"
|
||||
v-if="!disabled"
|
||||
>
|
||||
<!-- 上传按钮 -->
|
||||
<el-button type="primary">选取文件</el-button>
|
||||
</el-upload>
|
||||
<!-- 上传提示 -->
|
||||
<div v-if="showTip" class="el-upload__tip">
|
||||
<div v-if="showTip && !disabled" class="el-upload__tip">
|
||||
请上传
|
||||
<template v-if="fileSize">
|
||||
大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b>
|
||||
@ -35,7 +37,7 @@
|
||||
<span class="el-icon-document"> {{ getFileName(file.name) }} </span>
|
||||
</el-link>
|
||||
<div class="ele-upload-list__item-content-action">
|
||||
<el-button type="danger" link @click="handleDelete(index)">删除</el-button>
|
||||
<el-button type="danger" v-if="!disabled" link @click="handleDelete(index)">删除</el-button>
|
||||
</div>
|
||||
</li>
|
||||
</transition-group>
|
||||
@ -57,9 +59,11 @@ const props = defineProps({
|
||||
// 大小限制(MB)
|
||||
fileSize: propTypes.number.def(5),
|
||||
// 文件类型, 例如['png', 'jpg', 'jpeg']
|
||||
fileType: propTypes.array.def(['doc', 'xls', 'ppt', 'txt', 'pdf']),
|
||||
fileType: propTypes.array.def(['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt', 'pdf']),
|
||||
// 是否显示提示
|
||||
isShowTip: propTypes.bool.def(true)
|
||||
isShowTip: propTypes.bool.def(true),
|
||||
// 禁用组件(仅查看文件)
|
||||
disabled: propTypes.bool.def(false)
|
||||
});
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
@ -76,6 +80,9 @@ const showTip = computed(() => props.isShowTip && (props.fileType || props.fileS
|
||||
|
||||
const fileUploadRef = ref<ElUploadInstance>();
|
||||
|
||||
// 监听 fileType 变化,更新 fileAccept
|
||||
const fileAccept = computed(() => props.fileType.map((type) => `.${type}`).join(','));
|
||||
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
async (val) => {
|
||||
@ -209,7 +216,7 @@ const listToString = (list: any[], separator?: string) => {
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
<style lang="scss" scoped>
|
||||
.upload-file-uploader {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
@ -21,7 +21,7 @@
|
||||
import Fuse from 'fuse.js';
|
||||
import { getNormalPath } from '@/utils/ruoyi';
|
||||
import { isHttp } from '@/utils/validate';
|
||||
import usePermissionStore from '@/store/modules/permission';
|
||||
import { usePermissionStore } from '@/store/modules/permission';
|
||||
import { RouteRecordRaw } from 'vue-router';
|
||||
|
||||
type Router = Array<{
|
||||
@ -36,7 +36,7 @@ const show = ref(false);
|
||||
const fuse = ref();
|
||||
const headerSearchSelectRef = ref<ElSelectInstance>();
|
||||
const router = useRouter();
|
||||
const routes = computed(() => usePermissionStore().getRoutes());
|
||||
const routes = computed(() => usePermissionStore().getDefaultRoutes());
|
||||
|
||||
const click = () => {
|
||||
show.value = !show.value;
|
||||
|
@ -65,7 +65,7 @@ const selectedIcon = (iconName: string) => {
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
<style lang="scss" scoped>
|
||||
.el-scrollbar {
|
||||
max-height: calc(50vh - 100px) !important;
|
||||
overflow-y: auto;
|
||||
|
@ -1,13 +1,14 @@
|
||||
<template>
|
||||
<div class="component-upload-image">
|
||||
<el-upload
|
||||
ref="imageUpload"
|
||||
ref="imageUploadRef"
|
||||
multiple
|
||||
:action="uploadImgUrl"
|
||||
list-type="picture-card"
|
||||
:on-success="handleUploadSuccess"
|
||||
:before-upload="handleBeforeUpload"
|
||||
:limit="limit"
|
||||
:accept="fileAccept"
|
||||
:on-error="handleUploadError"
|
||||
:on-exceed="handleExceed"
|
||||
:before-remove="handleDelete"
|
||||
@ -87,6 +88,9 @@ const showTip = computed(() => props.isShowTip && (props.fileType || props.fileS
|
||||
|
||||
const imageUploadRef = ref<ElUploadInstance>();
|
||||
|
||||
// 监听 fileType 变化,更新 fileAccept
|
||||
const fileAccept = computed(() => props.fileType.map((type) => `.${type}`).join(','));
|
||||
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
async (val: string) => {
|
||||
@ -230,7 +234,7 @@ const listToString = (list: any[], separator?: string) => {
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
<style lang="scss" scoped>
|
||||
// .el-upload--picture-card 控制加号部分
|
||||
:deep(.hide .el-upload--picture-card) {
|
||||
display: none;
|
||||
|
@ -14,13 +14,7 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'Pagination'
|
||||
};
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
<script setup name="Pagination" lang="ts">
|
||||
import { scrollTo } from '@/utils/scroll-to';
|
||||
import { propTypes } from '@/utils/propTypes';
|
||||
|
||||
@ -28,10 +22,7 @@ const props = defineProps({
|
||||
total: propTypes.number,
|
||||
page: propTypes.number.def(1),
|
||||
limit: propTypes.number.def(20),
|
||||
pageSizes: {
|
||||
type: Array,
|
||||
default: () => [10, 20, 30, 50]
|
||||
},
|
||||
pageSizes: { type: Array<number>, default: () => [10, 20, 30, 50] },
|
||||
// 移动端页码按钮的数量端默认值5
|
||||
pagerCount: propTypes.number.def(document.body.clientWidth < 992 ? 5 : 7),
|
||||
layout: propTypes.string.def('total, sizes, prev, pager, next, jumper'),
|
||||
@ -77,7 +68,6 @@ function handleCurrentChange(val: number) {
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.pagination-container {
|
||||
padding: 32px 16px;
|
||||
.el-pagination {
|
||||
float: v-bind(float);
|
||||
}
|
||||
|
@ -72,7 +72,7 @@
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
<script setup lang="ts">
|
||||
import { flowImage } from '@/api/workflow/instance';
|
||||
import { propTypes } from '@/utils/propTypes';
|
||||
import { listByIds } from '@/api/system/oss';
|
||||
|
@ -49,7 +49,7 @@
|
||||
</el-dialog>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
<script setup lang="ts">
|
||||
import { propTypes } from '@/utils/propTypes';
|
||||
import { FlowTaskVO, TaskOperationBo } from '@/api/workflow/task/types';
|
||||
import UserSelect from '@/components/UserSelect';
|
||||
|
@ -11,12 +11,23 @@
|
||||
<el-form-item v-if="task.flowStatus === 'waiting'" label="附件">
|
||||
<fileUpload v-model="form.fileId" :file-type="['png', 'jpg', 'jpeg', 'doc', 'docx', 'xlsx', 'xls', 'ppt', 'txt', 'pdf']" :file-size="20" />
|
||||
</el-form-item>
|
||||
<el-form-item label="抄送">
|
||||
<el-form-item label="抄送" v-if="task.flowStatus === 'waiting' && buttonObj.copy">
|
||||
<el-button type="primary" icon="Plus" circle @click="openUserSelectCopy" />
|
||||
<el-tag v-for="user in selectCopyUserList" :key="user.userId" closable style="margin: 2px" @close="handleCopyCloseTag(user)">
|
||||
{{ user.nickName }}
|
||||
</el-tag>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="buttonObj.pop && nestNodeList && nestNodeList.length > 0" label="下一步审批人" prop="assigneeMap">
|
||||
<div v-for="(item, index) in nestNodeList" :key="index" style="margin-bottom: 5px; width: 500px">
|
||||
<span>【{{ item.nodeName }}】:</span>
|
||||
<el-input v-if="false" v-model="form.assigneeMap[item.nodeCode]" />
|
||||
<el-input placeholder="请选择审批人" readonly v-model="nickName[item.nodeCode]">
|
||||
<template v-slot:append>
|
||||
<el-button @click="choosePeople(item)" icon="search">选择</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="task.flowStatus === 'waiting'" label="审批意见">
|
||||
<el-input v-model="form.message" type="textarea" resize="none" />
|
||||
</el-form-item>
|
||||
@ -24,10 +35,14 @@
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button :disabled="buttonDisabled" type="primary" @click="handleCompleteTask"> 提交 </el-button>
|
||||
<el-button v-if="task.flowStatus === 'waiting'" :disabled="buttonDisabled" type="primary" @click="openDelegateTask"> 委托 </el-button>
|
||||
<el-button v-if="task.flowStatus === 'waiting'" :disabled="buttonDisabled" type="primary" @click="openTransferTask"> 转办 </el-button>
|
||||
<el-button v-if="task.flowStatus === 'waiting' && buttonObj.trust" :disabled="buttonDisabled" type="primary" @click="openDelegateTask">
|
||||
委托
|
||||
</el-button>
|
||||
<el-button v-if="task.flowStatus === 'waiting' && buttonObj.transfer" :disabled="buttonDisabled" type="primary" @click="openTransferTask">
|
||||
转办
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="task.flowStatus === 'waiting' && Number(task.nodeRatio) > 0"
|
||||
v-if="task.flowStatus === 'waiting' && Number(task.nodeRatio) > 0 && buttonObj.addSign"
|
||||
:disabled="buttonDisabled"
|
||||
type="primary"
|
||||
@click="openMultiInstanceUser"
|
||||
@ -35,15 +50,24 @@
|
||||
加签
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="task.flowStatus === 'waiting' && Number(task.nodeRatio) > 0"
|
||||
v-if="task.flowStatus === 'waiting' && Number(task.nodeRatio) > 0 && buttonObj.subSign"
|
||||
:disabled="buttonDisabled"
|
||||
type="primary"
|
||||
@click="handleTaskUser"
|
||||
>
|
||||
减签
|
||||
</el-button>
|
||||
<el-button v-if="task.flowStatus === 'waiting'" :disabled="buttonDisabled" type="danger" @click="handleTerminationTask"> 终止 </el-button>
|
||||
<el-button v-if="task.flowStatus === 'waiting'" :disabled="buttonDisabled" type="danger" @click="handleBackProcessOpen"> 退回 </el-button>
|
||||
<el-button
|
||||
v-if="task.flowStatus === 'waiting' && buttonObj.termination"
|
||||
:disabled="buttonDisabled"
|
||||
type="danger"
|
||||
@click="handleTerminationTask"
|
||||
>
|
||||
终止
|
||||
</el-button>
|
||||
<el-button v-if="task.flowStatus === 'waiting' && buttonObj.back" :disabled="buttonDisabled" type="danger" @click="handleBackProcessOpen">
|
||||
退回
|
||||
</el-button>
|
||||
<el-button :disabled="buttonDisabled" @click="cancel">取消</el-button>
|
||||
</span>
|
||||
</template>
|
||||
@ -55,6 +79,8 @@
|
||||
<UserSelect ref="delegateTaskRef" :multiple="false" @confirm-call-back="handleDelegateTask"></UserSelect>
|
||||
<!-- 加签组件 -->
|
||||
<UserSelect ref="multiInstanceUserRef" :multiple="true" @confirm-call-back="addMultiInstanceUser"></UserSelect>
|
||||
<!-- 弹窗选人 -->
|
||||
<UserSelect ref="porUserRef" :multiple="true" :userIds="popUserIds" @confirm-call-back="handlePopUser"></UserSelect>
|
||||
|
||||
<!-- 驳回开始 -->
|
||||
<el-dialog v-model="backVisible" draggable title="驳回" width="40%" :close-on-click-modal="false">
|
||||
@ -72,7 +98,11 @@
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="task.flowStatus === 'waiting'" label="附件">
|
||||
<fileUpload v-model="backForm.fileId" :file-type="['png', 'jpg', 'jpeg', 'doc', 'docx', 'xlsx', 'xls', 'ppt', 'txt', 'pdf']" :file-size="20" />
|
||||
<fileUpload
|
||||
v-model="backForm.fileId"
|
||||
:file-type="['png', 'jpg', 'jpeg', 'doc', 'docx', 'xlsx', 'xls', 'ppt', 'txt', 'pdf']"
|
||||
:file-size="20"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="审批意见">
|
||||
<el-input v-model="backForm.message" type="textarea" resize="none" />
|
||||
@ -102,11 +132,20 @@
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { ComponentInternalInstance } from 'vue';
|
||||
import { ElForm } from 'element-plus';
|
||||
import { completeTask, backProcess, getTask, taskOperation, terminationTask, getBackTaskNode, currentTaskAllUser } from '@/api/workflow/task';
|
||||
import {
|
||||
completeTask,
|
||||
backProcess,
|
||||
getTask,
|
||||
taskOperation,
|
||||
terminationTask,
|
||||
getBackTaskNode,
|
||||
currentTaskAllUser,
|
||||
getNextNodeList
|
||||
} from '@/api/workflow/task';
|
||||
import UserSelect from '@/components/UserSelect';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
@ -117,6 +156,7 @@ const userSelectCopyRef = ref<InstanceType<typeof UserSelect>>();
|
||||
const transferTaskRef = ref<InstanceType<typeof UserSelect>>();
|
||||
const delegateTaskRef = ref<InstanceType<typeof UserSelect>>();
|
||||
const multiInstanceUserRef = ref<InstanceType<typeof UserSelect>>();
|
||||
const porUserRef = ref<InstanceType<typeof UserSelect>>();
|
||||
|
||||
const props = defineProps({
|
||||
taskVariables: {
|
||||
@ -136,12 +176,28 @@ const selectCopyUserList = ref<UserVO[]>([]);
|
||||
const selectCopyUserIds = ref<string>(undefined);
|
||||
//可减签的人员
|
||||
const deleteUserList = ref<any>([]);
|
||||
//弹窗可选择的人员id
|
||||
const popUserIds = ref<any>([]);
|
||||
//驳回是否显示
|
||||
const backVisible = ref(false);
|
||||
const backLoading = ref(true);
|
||||
const backButtonDisabled = ref(true);
|
||||
// 可驳回得任务节点
|
||||
const taskNodeList = ref([]);
|
||||
const nickName = ref({});
|
||||
//节点编码
|
||||
const nodeCode = ref<string>('');
|
||||
const buttonObj = ref<any>({
|
||||
pop: false,
|
||||
trust: false,
|
||||
transfer: false,
|
||||
addSign: false,
|
||||
subSign: false,
|
||||
termination: false,
|
||||
back: false
|
||||
});
|
||||
//下一节点列表
|
||||
const nestNodeList = ref([]);
|
||||
//任务
|
||||
const task = ref<FlowTaskVO>({
|
||||
id: undefined,
|
||||
@ -159,7 +215,9 @@ const task = ref<FlowTaskVO>({
|
||||
formCustom: undefined,
|
||||
formPath: undefined,
|
||||
nodeType: undefined,
|
||||
nodeRatio: undefined
|
||||
nodeRatio: undefined,
|
||||
applyNode: false,
|
||||
buttonList: []
|
||||
});
|
||||
const dialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
@ -170,6 +228,7 @@ const deleteSignatureVisible = ref(false);
|
||||
const form = ref<Record<string, any>>({
|
||||
taskId: undefined,
|
||||
message: undefined,
|
||||
assigneeMap: {},
|
||||
variables: {},
|
||||
messageType: ['1'],
|
||||
flowCopyList: []
|
||||
@ -181,8 +240,9 @@ const backForm = ref<Record<string, any>>({
|
||||
variables: {},
|
||||
messageType: ['1']
|
||||
});
|
||||
|
||||
//打开弹窗
|
||||
const openDialog = (id?: string) => {
|
||||
const openDialog = async (id?: string) => {
|
||||
selectCopyUserIds.value = undefined;
|
||||
selectCopyUserList.value = [];
|
||||
form.value.fileId = undefined;
|
||||
@ -191,13 +251,20 @@ const openDialog = (id?: string) => {
|
||||
dialog.visible = true;
|
||||
loading.value = true;
|
||||
buttonDisabled.value = true;
|
||||
nextTick(() => {
|
||||
getTask(taskId.value).then((response) => {
|
||||
const response = await getTask(taskId.value);
|
||||
task.value = response.data;
|
||||
loading.value = false;
|
||||
buttonObj.value = {};
|
||||
task.value.buttonList.forEach((e) => {
|
||||
buttonObj.value[e.code] = e.show;
|
||||
});
|
||||
buttonDisabled.value = false;
|
||||
});
|
||||
});
|
||||
const data = {
|
||||
taskId: taskId.value,
|
||||
variables: props.taskVariables
|
||||
};
|
||||
const nextData = await getNextNodeList(data);
|
||||
nestNodeList.value = nextData.data;
|
||||
loading.value = false;
|
||||
};
|
||||
|
||||
onMounted(() => {});
|
||||
@ -207,10 +274,29 @@ const emits = defineEmits(['submitCallback', 'cancelCallback']);
|
||||
const handleCompleteTask = async () => {
|
||||
form.value.taskId = taskId.value;
|
||||
form.value.taskVariables = props.taskVariables;
|
||||
let verify = false;
|
||||
if (buttonObj.value.pop && nestNodeList.value && nestNodeList.value.length > 0) {
|
||||
nestNodeList.value.forEach((e) => {
|
||||
if (
|
||||
Object.keys(form.value.assigneeMap).length === 0 ||
|
||||
form.value.assigneeMap[e.nodeCode] === '' ||
|
||||
form.value.assigneeMap[e.nodeCode] === null ||
|
||||
form.value.assigneeMap[e.nodeCode] === undefined
|
||||
) {
|
||||
verify = true;
|
||||
}
|
||||
});
|
||||
if (verify) {
|
||||
proxy?.$modal.msgWarning('请选择审批人!');
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
form.value.assigneeMap = {};
|
||||
}
|
||||
if (selectCopyUserList.value && selectCopyUserList.value.length > 0) {
|
||||
let flowCopyList = [];
|
||||
const flowCopyList = [];
|
||||
selectCopyUserList.value.forEach((e) => {
|
||||
let copyUser = {
|
||||
const copyUser = {
|
||||
userId: e.userId,
|
||||
userName: e.nickName
|
||||
};
|
||||
@ -239,7 +325,7 @@ const handleBackProcessOpen = async () => {
|
||||
backVisible.value = true;
|
||||
backLoading.value = true;
|
||||
backButtonDisabled.value = true;
|
||||
let data = await getBackTaskNode(task.value.definitionId, task.value.nodeCode);
|
||||
const data = await getBackTaskNode(task.value.definitionId, task.value.nodeCode);
|
||||
taskNodeList.value = data.data;
|
||||
backLoading.value = false;
|
||||
backButtonDisabled.value = false;
|
||||
@ -266,6 +352,8 @@ const handleBackProcess = async () => {
|
||||
const cancel = async () => {
|
||||
dialog.visible = false;
|
||||
buttonDisabled.value = false;
|
||||
nickName.value = {};
|
||||
form.value.assigneeMap = {};
|
||||
emits('cancelCallback');
|
||||
};
|
||||
//打开抄送人员
|
||||
@ -386,7 +474,7 @@ const handleDelegateTask = async (data) => {
|
||||
};
|
||||
//终止任务
|
||||
const handleTerminationTask = async () => {
|
||||
let params = {
|
||||
const params = {
|
||||
taskId: taskId.value,
|
||||
comment: form.value.message
|
||||
};
|
||||
@ -402,7 +490,7 @@ const handleTerminationTask = async () => {
|
||||
proxy?.$modal.msgSuccess('操作成功');
|
||||
};
|
||||
const handleTaskUser = async () => {
|
||||
let data = await currentTaskAllUser(taskId.value);
|
||||
const data = await currentTaskAllUser(taskId.value);
|
||||
deleteUserList.value = data.data;
|
||||
if (deleteUserList.value && deleteUserList.value.length > 0) {
|
||||
deleteUserList.value.forEach((e) => {
|
||||
@ -411,6 +499,26 @@ const handleTaskUser = async () => {
|
||||
}
|
||||
deleteSignatureVisible.value = true;
|
||||
};
|
||||
// 选择人员
|
||||
const choosePeople = async (data) => {
|
||||
if (!data.permissionFlag) {
|
||||
proxy?.$modal.msgError('没有可选择的人员,请联系管理员!');
|
||||
}
|
||||
popUserIds.value = data.permissionFlag;
|
||||
nodeCode.value = data.nodeCode;
|
||||
porUserRef.value.open();
|
||||
};
|
||||
//确认选择
|
||||
const handlePopUser = async (userList) => {
|
||||
const userIds = userList.map((item) => {
|
||||
return item.userId;
|
||||
});
|
||||
const nickNames = userList.map((item) => {
|
||||
return item.nickName;
|
||||
});
|
||||
form.value.assigneeMap[nodeCode.value] = userIds.join(',');
|
||||
nickName.value[nodeCode.value] = nickNames.join(',');
|
||||
};
|
||||
|
||||
/**
|
||||
* 对外暴露子组件方法
|
||||
|
@ -16,7 +16,7 @@
|
||||
:data="columns"
|
||||
show-checkbox
|
||||
node-key="key"
|
||||
:props="{ label: 'label', children: 'children' }"
|
||||
:props="{ label: 'label', children: 'children' } as any"
|
||||
@check="columnChange"
|
||||
></el-tree>
|
||||
<template #reference>
|
||||
|
@ -4,7 +4,7 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup lang="ts">
|
||||
const url = ref('https://plus-doc.dromara.org/');
|
||||
|
||||
function goto() {
|
||||
|
@ -4,7 +4,7 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup lang="ts">
|
||||
const url = ref('https://gitee.com/dromara/RuoYi-Vue-Plus');
|
||||
|
||||
function goto() {
|
||||
|
@ -16,7 +16,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import useAppStore from '@/store/modules/app';
|
||||
import { useAppStore } from '@/store/modules/app';
|
||||
|
||||
const appStore = useAppStore();
|
||||
const size = computed(() => appStore.size);
|
||||
|
@ -21,7 +21,7 @@ const svgClass = computed(() => {
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scope lang="scss">
|
||||
<style lang="scss" scoped>
|
||||
.sub-el-icon,
|
||||
.nav-icon {
|
||||
display: inline-block;
|
||||
|
@ -22,9 +22,9 @@
|
||||
<script setup lang="ts">
|
||||
import { constantRoutes } from '@/router';
|
||||
import { isHttp } from '@/utils/validate';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
import useSettingsStore from '@/store/modules/settings';
|
||||
import usePermissionStore from '@/store/modules/permission';
|
||||
import { useAppStore } from '@/store/modules/app';
|
||||
import { useSettingsStore } from '@/store/modules/settings';
|
||||
import { usePermissionStore } from '@/store/modules/permission';
|
||||
import { RouteRecordRaw } from 'vue-router';
|
||||
|
||||
// 顶部栏初始数
|
||||
|
@ -6,7 +6,7 @@
|
||||
style="width: 100%"
|
||||
:filterable="true"
|
||||
:clearable="true"
|
||||
:filter-method="selectFilterData"
|
||||
:filter-method="selectFilterData as any"
|
||||
:placeholder="placeholder"
|
||||
@clear="clearHandle"
|
||||
>
|
||||
@ -16,7 +16,7 @@
|
||||
ref="selectTree"
|
||||
:accordion="accordion"
|
||||
:data="options"
|
||||
:props="objMap"
|
||||
:props="objMap as any"
|
||||
:node-key="objMap.value"
|
||||
:expand-on-click-node="false"
|
||||
:default-expanded-keys="defaultExpandedKey"
|
||||
|
@ -11,7 +11,7 @@
|
||||
class="mt-2"
|
||||
node-key="id"
|
||||
:data="deptOptions"
|
||||
:props="{ label: 'label', children: 'children' }"
|
||||
:props="{ label: 'label', children: 'children' } as any"
|
||||
:expand-on-click-node="false"
|
||||
:filter-node-method="filterNode"
|
||||
highlight-current
|
||||
@ -108,11 +108,13 @@ interface PropType {
|
||||
modelValue?: UserVO[] | UserVO | undefined;
|
||||
multiple?: boolean;
|
||||
data?: string | number | (string | number)[] | undefined;
|
||||
userIds?: string | number | (string | number)[] | undefined;
|
||||
}
|
||||
const prop = withDefaults(defineProps<PropType>(), {
|
||||
multiple: true,
|
||||
modelValue: undefined,
|
||||
data: undefined
|
||||
data: undefined,
|
||||
userIds: undefined
|
||||
});
|
||||
const emit = defineEmits(['update:modelValue', 'confirmCallBack']);
|
||||
|
||||
@ -143,7 +145,8 @@ const queryParams = ref<UserQuery>({
|
||||
phonenumber: '',
|
||||
status: '',
|
||||
deptId: '',
|
||||
roleId: ''
|
||||
roleId: '',
|
||||
userIds: ''
|
||||
});
|
||||
|
||||
const defaultSelectUserIds = computed(() => computedIds(prop.data));
|
||||
@ -166,7 +169,7 @@ const confirm = () => {
|
||||
|
||||
const computedIds = (data) => {
|
||||
if (data instanceof Array) {
|
||||
return data.map(item => String(item));
|
||||
return data.map((item) => String(item));
|
||||
} else if (typeof data === 'string') {
|
||||
return data.split(',');
|
||||
} else if (typeof data === 'number') {
|
||||
@ -192,6 +195,7 @@ const getTreeSelect = async () => {
|
||||
/** 查询用户列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
queryParams.value.userIds = prop.userIds;
|
||||
const res = await api.listUser(proxy?.addDateRange(queryParams.value, dateRange.value));
|
||||
loading.value = false;
|
||||
userList.value = res.rows;
|
||||
@ -302,5 +306,3 @@ defineExpose({
|
||||
close: userDialog.closeDialog
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Directive, DirectiveBinding } from 'vue';
|
||||
import useUserStore from '@/store/modules/user';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
/**
|
||||
* 操作权限处理
|
||||
*/
|
||||
|
@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<section class="app-main">
|
||||
<router-view v-slot="{ Component, route }">
|
||||
<transition v-if="!route.meta.noCache" :enter-active-class="animante" mode="out-in">
|
||||
<transition v-if="!route.meta.noCache" :enter-active-class="animate" mode="out-in">
|
||||
<keep-alive v-if="!route.meta.noCache" :include="tagsViewStore.cachedViews">
|
||||
<component :is="Component" v-if="!route.meta.link" :key="route.path" />
|
||||
</keep-alive>
|
||||
</transition>
|
||||
<transition v-if="route.meta.noCache" :enter-active-class="animante" mode="out-in">
|
||||
<transition v-if="route.meta.noCache" :enter-active-class="animate" mode="out-in">
|
||||
<component :is="Component" v-if="!route.meta.link && route.meta.noCache" :key="route.path" />
|
||||
</transition>
|
||||
</router-view>
|
||||
@ -15,8 +15,8 @@
|
||||
</template>
|
||||
|
||||
<script setup name="AppMain" lang="ts">
|
||||
import useSettingsStore from '@/store/modules/settings';
|
||||
import useTagsViewStore from '@/store/modules/tagsView';
|
||||
import { useSettingsStore } from '@/store/modules/settings';
|
||||
import { useTagsViewStore } from '@/store/modules/tagsView';
|
||||
|
||||
import IframeToggle from './IframeToggle/index.vue';
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
@ -24,16 +24,16 @@ const route = useRoute();
|
||||
const tagsViewStore = useTagsViewStore();
|
||||
|
||||
// 随机动画集合
|
||||
const animante = ref<string>('');
|
||||
const animate = ref<string>('');
|
||||
const animationEnable = ref(useSettingsStore().animationEnable);
|
||||
watch(
|
||||
() => useSettingsStore().animationEnable,
|
||||
(val: boolean) => {
|
||||
animationEnable.value = val;
|
||||
if (val) {
|
||||
animante.value = proxy?.animate.animateList[Math.round(Math.random() * proxy?.animate.animateList.length)] as string;
|
||||
animate.value = proxy?.animate.animateList[Math.round(Math.random() * proxy?.animate.animateList.length)] as string;
|
||||
} else {
|
||||
animante.value = proxy?.animate.defaultAnimate as string;
|
||||
animate.value = proxy?.animate.defaultAnimate as string;
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
|
@ -11,7 +11,7 @@
|
||||
<script setup lang="ts">
|
||||
import InnerLink from '../InnerLink/index.vue';
|
||||
|
||||
import useTagsViewStore from '@/store/modules/tagsView';
|
||||
import { useTagsViewStore } from '@/store/modules/tagsView';
|
||||
|
||||
const route = useRoute();
|
||||
const tagsViewStore = useTagsViewStore();
|
||||
|
@ -90,15 +90,16 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import SearchMenu from './TopBar/search.vue';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
import useUserStore from '@/store/modules/user';
|
||||
import useSettingsStore from '@/store/modules/settings';
|
||||
import useNoticeStore from '@/store/modules/notice';
|
||||
import { useAppStore } from '@/store/modules/app';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
import { useSettingsStore } from '@/store/modules/settings';
|
||||
import { useNoticeStore } from '@/store/modules/notice';
|
||||
import { getTenantList } from '@/api/login';
|
||||
import { dynamicClear, dynamicTenant } from '@/api/system/tenant';
|
||||
import { TenantVO } from '@/api/types';
|
||||
import notice from './notice/index.vue';
|
||||
import router from '@/router';
|
||||
import {ElMessageBoxOptions} from "element-plus/es/components/message-box/src/message-box.type";
|
||||
|
||||
const appStore = useAppStore();
|
||||
const userStore = useUserStore();
|
||||
@ -128,8 +129,8 @@ const dynamicTenantEvent = async (tenantId: string) => {
|
||||
await dynamicTenant(tenantId);
|
||||
dynamic.value = true;
|
||||
await proxy?.$router.push('/');
|
||||
await proxy?.proxy.$tab.closeAllPage();
|
||||
await proxy?.proxy.$tab.refreshPage();
|
||||
await proxy?.$tab.closeAllPage();
|
||||
await proxy?.$tab.refreshPage();
|
||||
}
|
||||
};
|
||||
|
||||
@ -137,8 +138,8 @@ const dynamicClearEvent = async () => {
|
||||
await dynamicClear();
|
||||
dynamic.value = false;
|
||||
await proxy?.$router.push('/');
|
||||
await proxy?.proxy.$tab.closeAllPage();
|
||||
await proxy?.proxy.$tab.refreshPage();
|
||||
await proxy?.$tab.closeAllPage();
|
||||
await proxy?.$tab.refreshPage();
|
||||
};
|
||||
|
||||
/** 租户列表 */
|
||||
@ -163,7 +164,7 @@ const logout = async () => {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
});
|
||||
} as ElMessageBoxOptions);
|
||||
userStore.logout().then(() => {
|
||||
router.replace({
|
||||
path: '/login',
|
||||
|
@ -89,9 +89,9 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useDynamicTitle } from '@/utils/dynamicTitle';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
import useSettingsStore from '@/store/modules/settings';
|
||||
import usePermissionStore from '@/store/modules/permission';
|
||||
import { useAppStore } from '@/store/modules/app';
|
||||
import { useSettingsStore } from '@/store/modules/settings';
|
||||
import { usePermissionStore } from '@/store/modules/permission';
|
||||
import { handleThemeStyle } from '@/utils/theme';
|
||||
import { SideThemeEnum } from '@/enums/SideThemeEnum';
|
||||
import defaultSettings from '@/settings';
|
||||
|
@ -24,7 +24,7 @@
|
||||
<script setup lang="ts">
|
||||
import variables from '@/assets/styles/variables.module.scss';
|
||||
import logo from '@/assets/logo/logo.png';
|
||||
import useSettingsStore from '@/store/modules/settings';
|
||||
import { useSettingsStore } from '@/store/modules/settings';
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
defineProps({
|
||||
|
@ -24,9 +24,9 @@
|
||||
import Logo from './Logo.vue';
|
||||
import SidebarItem from './SidebarItem.vue';
|
||||
import variables from '@/assets/styles/variables.module.scss';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
import useSettingsStore from '@/store/modules/settings';
|
||||
import usePermissionStore from '@/store/modules/permission';
|
||||
import { useAppStore } from '@/store/modules/app';
|
||||
import { useSettingsStore } from '@/store/modules/settings';
|
||||
import { usePermissionStore } from '@/store/modules/permission';
|
||||
import { RouteRecordRaw } from 'vue-router';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { RouteLocationNormalized } from 'vue-router';
|
||||
import useTagsViewStore from '@/store/modules/tagsView';
|
||||
import { useTagsViewStore } from '@/store/modules/tagsView';
|
||||
|
||||
const tagAndTagSpacing = ref(4);
|
||||
|
||||
|
@ -32,9 +32,9 @@
|
||||
<script setup lang="ts">
|
||||
import ScrollPane from './ScrollPane.vue';
|
||||
import { getNormalPath } from '@/utils/ruoyi';
|
||||
import useSettingsStore from '@/store/modules/settings';
|
||||
import usePermissionStore from '@/store/modules/permission';
|
||||
import useTagsViewStore from '@/store/modules/tagsView';
|
||||
import { useSettingsStore } from '@/store/modules/settings';
|
||||
import { usePermissionStore } from '@/store/modules/permission';
|
||||
import { useTagsViewStore } from '@/store/modules/tagsView';
|
||||
import { RouteRecordRaw, RouteLocationNormalized } from 'vue-router';
|
||||
|
||||
const visible = ref(false);
|
||||
|
@ -28,7 +28,7 @@
|
||||
<script setup lang="ts" name="layoutBreadcrumbSearch">
|
||||
import { getNormalPath } from '@/utils/ruoyi';
|
||||
import { isHttp } from '@/utils/validate';
|
||||
import usePermissionStore from '@/store/modules/permission';
|
||||
import { usePermissionStore } from '@/store/modules/permission';
|
||||
import { RouteRecordRaw } from 'vue-router';
|
||||
type Router = Array<{
|
||||
path: string;
|
||||
@ -130,7 +130,7 @@ defineExpose({
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
<style lang="scss" scoped>
|
||||
.layout-search-dialog {
|
||||
position: relative;
|
||||
:deep(.el-dialog) {
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
<script setup lang="ts" name="layoutBreadcrumbUserNews">
|
||||
import { storeToRefs } from 'pinia';
|
||||
import useNoticeStore from '@/store/modules/notice';
|
||||
import { useNoticeStore } from '@/store/modules/notice';
|
||||
|
||||
const noticeStore = storeToRefs(useNoticeStore());
|
||||
const { readAll } = useNoticeStore();
|
||||
@ -65,7 +65,7 @@ onMounted(() => {
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
<style lang="scss" scoped>
|
||||
.layout-navbars-breadcrumb-user-news {
|
||||
.head-box {
|
||||
display: flex;
|
||||
|
@ -24,8 +24,8 @@
|
||||
<script setup lang="ts">
|
||||
import SideBar from './components/Sidebar/index.vue';
|
||||
import { AppMain, Navbar, Settings, TagsView } from './components';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
import useSettingsStore from '@/store/modules/settings';
|
||||
import { useAppStore } from '@/store/modules/app';
|
||||
import { useSettingsStore } from '@/store/modules/settings';
|
||||
import { initWebSocket } from '@/utils/websocket';
|
||||
import { initSSE } from '@/utils/sse';
|
||||
|
||||
@ -68,7 +68,7 @@ onMounted(() => {
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
let protocol = window.location.protocol === 'https:' ? 'wss://' : 'ws://';
|
||||
const protocol = window.location.protocol === 'https:' ? 'wss://' : 'ws://';
|
||||
initWebSocket(protocol + window.location.host + import.meta.env.VITE_APP_BASE_API + '/resource/websocket');
|
||||
});
|
||||
|
||||
@ -86,11 +86,11 @@ const setLayout = () => {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '@/assets/styles/mixin.scss';
|
||||
@import '@/assets/styles/variables.module.scss';
|
||||
@use '@/assets/styles/mixin.scss';
|
||||
@use '@/assets/styles/variables.module.scss' as *;
|
||||
|
||||
.app-wrapper {
|
||||
@include clearfix;
|
||||
@include mixin.clearfix;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
@ -5,9 +5,10 @@ import 'nprogress/nprogress.css';
|
||||
import { getToken } from '@/utils/auth';
|
||||
import { isHttp, isPathMatch } from '@/utils/validate';
|
||||
import { isRelogin } from '@/utils/request';
|
||||
import useUserStore from '@/store/modules/user';
|
||||
import useSettingsStore from '@/store/modules/settings';
|
||||
import usePermissionStore from '@/store/modules/permission';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
import { useSettingsStore } from '@/store/modules/settings';
|
||||
import { usePermissionStore } from '@/store/modules/permission';
|
||||
import { ElMessage } from 'element-plus/es';
|
||||
|
||||
NProgress.configure({ showSpinner: false });
|
||||
const whiteList = ['/login', '/register', '/social-callback', '/register*', '/register/*'];
|
||||
@ -19,7 +20,7 @@ const isWhiteList = (path: string) => {
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
NProgress.start();
|
||||
if (getToken()) {
|
||||
to.meta.title && useSettingsStore().setTitle(to.meta.title);
|
||||
to.meta.title && useSettingsStore().setTitle(to.meta.title as string);
|
||||
/* has token*/
|
||||
if (to.path === '/login') {
|
||||
next({ path: '/' });
|
||||
|
@ -1,4 +1,4 @@
|
||||
import useUserStore from '@/store/modules/user';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
|
||||
const authPermission = (permission: string): boolean => {
|
||||
const all_permission = '*:*:*';
|
||||
|
@ -1,6 +1,6 @@
|
||||
import router from '@/router';
|
||||
import { RouteLocationMatched, RouteLocationNormalized, RouteLocationRaw } from 'vue-router';
|
||||
import useTagsViewStore from '@/store/modules/tagsView';
|
||||
import { useTagsViewStore } from '@/store/modules/tagsView';
|
||||
|
||||
export default {
|
||||
/**
|
||||
|
@ -50,13 +50,29 @@ const setting: DefaultSettings = {
|
||||
*/
|
||||
errorLog: 'production',
|
||||
|
||||
/**
|
||||
* 是否开启动画 开启随机 关闭渐进渐出
|
||||
*/
|
||||
animationEnable: false,
|
||||
|
||||
/**
|
||||
* 是否暗黑模式
|
||||
*/
|
||||
dark: false,
|
||||
|
||||
/**
|
||||
* 默认语言
|
||||
*/
|
||||
language: LanguageEnum.zh_CN,
|
||||
|
||||
/**
|
||||
* 默认大小
|
||||
*/
|
||||
size: 'default',
|
||||
|
||||
/**
|
||||
* 默认布局
|
||||
*/
|
||||
layout: ''
|
||||
};
|
||||
export default setting;
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { createPinia } from "pinia";
|
||||
|
||||
const store = createPinia();
|
||||
|
||||
export default store;
|
||||
|
@ -1,5 +1,8 @@
|
||||
import zhCN from 'element-plus/es/locale/lang/zh-cn';
|
||||
import enUS from 'element-plus/es/locale/lang/en';
|
||||
import { defineStore } from 'pinia';
|
||||
import { useStorage } from '@vueuse/core';
|
||||
import { ref, reactive, computed } from 'vue';
|
||||
|
||||
export const useAppStore = defineStore('app', () => {
|
||||
const sidebarStatus = useStorage('sidebarStatus', '1');
|
||||
@ -68,5 +71,3 @@ export const useAppStore = defineStore('app', () => {
|
||||
toggleSideBarHide
|
||||
};
|
||||
});
|
||||
|
||||
export default useAppStore;
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { defineStore } from 'pinia';
|
||||
|
||||
export const useDictStore = defineStore('dict', () => {
|
||||
const dict = ref<Map<string, DictDataOption[]>>(new Map());
|
||||
|
||||
@ -61,5 +63,3 @@ export const useDictStore = defineStore('dict', () => {
|
||||
cleanDict
|
||||
};
|
||||
});
|
||||
|
||||
export default useDictStore;
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import { reactive } from 'vue';
|
||||
|
||||
interface NoticeItem {
|
||||
title?: string;
|
||||
@ -38,5 +39,3 @@ export const useNoticeStore = defineStore('notice', () => {
|
||||
clearNotice
|
||||
};
|
||||
});
|
||||
|
||||
export default useNoticeStore;
|
||||
|
@ -4,11 +4,10 @@ import store from '@/store';
|
||||
import { getRouters } from '@/api/menu';
|
||||
import auth from '@/plugins/auth';
|
||||
import { RouteRecordRaw } from 'vue-router';
|
||||
|
||||
import Layout from '@/layout/index.vue';
|
||||
import ParentView from '@/components/ParentView/index.vue';
|
||||
import InnerLink from '@/layout/components/InnerLink/index.vue';
|
||||
|
||||
import { ref } from 'vue';
|
||||
import { createCustomNameComponent } from '@/utils/createCustomNameComponent';
|
||||
|
||||
// 匹配views里面所有的.vue文件
|
||||
@ -23,6 +22,9 @@ export const usePermissionStore = defineStore('permission', () => {
|
||||
const getRoutes = (): RouteRecordRaw[] => {
|
||||
return routes.value as RouteRecordRaw[];
|
||||
};
|
||||
const getDefaultRoutes = (): RouteRecordRaw[] => {
|
||||
return defaultRoutes.value as RouteRecordRaw[];
|
||||
};
|
||||
const getSidebarRoutes = (): RouteRecordRaw[] => {
|
||||
return sidebarRouters.value as RouteRecordRaw[];
|
||||
};
|
||||
@ -97,29 +99,14 @@ export const usePermissionStore = defineStore('permission', () => {
|
||||
};
|
||||
const filterChildren = (childrenMap: RouteRecordRaw[], lastRouter?: RouteRecordRaw): RouteRecordRaw[] => {
|
||||
let children: RouteRecordRaw[] = [];
|
||||
childrenMap.forEach((el) => {
|
||||
if (el.children && el.children.length) {
|
||||
if (el.component?.toString() === 'ParentView' && !lastRouter) {
|
||||
el.children.forEach((c) => {
|
||||
c.path = el.path + '/' + c.path;
|
||||
if (c.children && c.children.length) {
|
||||
children = children.concat(filterChildren(c.children, c));
|
||||
return;
|
||||
}
|
||||
children.push(c);
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (lastRouter) {
|
||||
el.path = lastRouter.path + '/' + el.path;
|
||||
if (el.children && el.children.length) {
|
||||
childrenMap.forEach(el => {
|
||||
el.path = lastRouter ? lastRouter.path + '/' + el.path : el.path;
|
||||
if (el.children && el.children.length && el.component?.toString() === 'ParentView') {
|
||||
children = children.concat(filterChildren(el.children, el));
|
||||
return;
|
||||
} else {
|
||||
children.push(el);
|
||||
}
|
||||
}
|
||||
children = children.concat(el);
|
||||
});
|
||||
})
|
||||
return children;
|
||||
};
|
||||
return {
|
||||
@ -129,6 +116,7 @@ export const usePermissionStore = defineStore('permission', () => {
|
||||
defaultRoutes,
|
||||
|
||||
getRoutes,
|
||||
getDefaultRoutes,
|
||||
getSidebarRoutes,
|
||||
getTopbarRoutes,
|
||||
|
||||
@ -217,5 +205,3 @@ function duplicateRouteChecker(localRoutes: Route[], routes: Route[]) {
|
||||
nameList.push(route.name.toString());
|
||||
});
|
||||
}
|
||||
|
||||
export default usePermissionStore;
|
||||
|
@ -1,8 +1,11 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import defaultSettings from '@/settings';
|
||||
import { useDynamicTitle } from '@/utils/dynamicTitle';
|
||||
import { useStorage } from '@vueuse/core';
|
||||
import { ref } from 'vue';
|
||||
|
||||
export const useSettingsStore = defineStore('setting', () => {
|
||||
// @ts-ignore
|
||||
const storageSetting = useStorage<LayoutSetting>('layout-setting', {
|
||||
topNav: defaultSettings.topNav,
|
||||
tagsView: defaultSettings.tagsView,
|
||||
@ -43,5 +46,3 @@ export const useSettingsStore = defineStore('setting', () => {
|
||||
setTitle
|
||||
};
|
||||
});
|
||||
|
||||
export default useSettingsStore;
|
||||
|
@ -1,4 +1,6 @@
|
||||
import { RouteLocationNormalized } from 'vue-router';
|
||||
import { defineStore } from 'pinia';
|
||||
import { ref } from 'vue';
|
||||
|
||||
export const useTagsViewStore = defineStore('tagsView', () => {
|
||||
const visitedViews = ref<RouteLocationNormalized[]>([]);
|
||||
@ -230,4 +232,3 @@ export const useTagsViewStore = defineStore('tagsView', () => {
|
||||
delIframeView
|
||||
};
|
||||
});
|
||||
export default useTagsViewStore;
|
||||
|
@ -3,7 +3,8 @@ import { getToken, removeToken, setToken } from '@/utils/auth';
|
||||
import { login as loginApi, logout as logoutApi, getInfo as getUserInfo } from '@/api/login';
|
||||
import { LoginData } from '@/api/types';
|
||||
import defAva from '@/assets/images/profile.jpg';
|
||||
import store from '@/store';
|
||||
import { defineStore } from 'pinia';
|
||||
import { ref } from 'vue';
|
||||
|
||||
export const useUserStore = defineStore('user', () => {
|
||||
const token = ref(getToken());
|
||||
@ -83,9 +84,3 @@ export const useUserStore = defineStore('user', () => {
|
||||
setAvatar
|
||||
};
|
||||
});
|
||||
|
||||
export default useUserStore;
|
||||
// 非setup
|
||||
export function useUserStoreHook() {
|
||||
return useUserStore(store);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import useUserStore from '@/store/modules/user';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
|
||||
/**
|
||||
* 字符权限校验
|
||||
|
@ -167,39 +167,21 @@ export const handleTree = <T>(data: any[], id?: string, parentId?: string, child
|
||||
};
|
||||
|
||||
const childrenListMap: any = {};
|
||||
const nodeIds: any = {};
|
||||
const tree: T[] = [];
|
||||
|
||||
for (const d of data) {
|
||||
const parentId = d[config.parentId];
|
||||
if (childrenListMap[parentId] == null) {
|
||||
childrenListMap[parentId] = [];
|
||||
}
|
||||
nodeIds[d[config.id]] = d;
|
||||
childrenListMap[parentId].push(d);
|
||||
const id = d[config.id];
|
||||
childrenListMap[id] = d;
|
||||
}
|
||||
|
||||
for (const d of data) {
|
||||
const parentId = d[config.parentId];
|
||||
if (nodeIds[parentId] == null) {
|
||||
const parentObj = childrenListMap[parentId]
|
||||
if (!parentObj) {
|
||||
tree.push(d);
|
||||
} else {
|
||||
parentObj[config.childrenList].push(d)
|
||||
}
|
||||
}
|
||||
const adaptToChildrenList = (o: any) => {
|
||||
if (childrenListMap[o[config.id]] !== null) {
|
||||
o[config.childrenList] = childrenListMap[o[config.id]];
|
||||
}
|
||||
if (o[config.childrenList]) {
|
||||
for (const c of o[config.childrenList]) {
|
||||
adaptToChildrenList(c);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
for (const t of tree) {
|
||||
adaptToChildrenList(t);
|
||||
}
|
||||
|
||||
return tree;
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { getToken } from '@/utils/auth';
|
||||
import { ElNotification } from 'element-plus';
|
||||
import useNoticeStore from '@/store/modules/notice';
|
||||
import { useNoticeStore } from '@/store/modules/notice';
|
||||
|
||||
// 初始化
|
||||
export const initSSE = (url: any) => {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { getToken } from '@/utils/auth';
|
||||
import { ElNotification } from 'element-plus';
|
||||
import useNoticeStore from '@/store/modules/notice';
|
||||
import { useNoticeStore } from '@/store/modules/notice';
|
||||
|
||||
// 初始化socket
|
||||
export const initWebSocket = (url: any) => {
|
||||
|
@ -62,7 +62,7 @@
|
||||
<el-tree-select
|
||||
v-model="form.parentId"
|
||||
:data="treeOptions"
|
||||
:props="{ value: 'id', label: 'treeName', children: 'children' }"
|
||||
:props="{ value: 'id', label: 'treeName', children: 'children' } as any"
|
||||
value-key="id"
|
||||
placeholder="请选择父id"
|
||||
check-strictly
|
||||
|
@ -33,7 +33,7 @@
|
||||
* 部署方式 Docker 容器编排 一键部署业务集群<br />
|
||||
* 国际化 SpringMessage Spring标准国际化方案<br />
|
||||
</p>
|
||||
<p><b>当前版本:</b> <span>v5.3.0</span></p>
|
||||
<p><b>当前版本:</b> <span>v5.3.1</span></p>
|
||||
<p>
|
||||
<el-tag type="danger">¥免费开源</el-tag>
|
||||
</p>
|
||||
@ -100,7 +100,7 @@ const goTarget = (url: string) => {
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
<style lang="scss" scoped>
|
||||
.home {
|
||||
blockquote {
|
||||
padding: 10px 20px;
|
||||
|
@ -73,7 +73,7 @@
|
||||
</el-form>
|
||||
<!-- 底部 -->
|
||||
<div class="el-login-footer">
|
||||
<span>Copyright © 2018-2024 疯狂的狮子Li All Rights Reserved.</span>
|
||||
<span>Copyright © 2018-2025 疯狂的狮子Li All Rights Reserved.</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
2
src/views/monitor/cache/index.vue
vendored
2
src/views/monitor/cache/index.vue
vendored
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<el-row>
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="24" class="card-box">
|
||||
<el-card shadow="hover">
|
||||
<template #header>
|
||||
|
@ -95,7 +95,7 @@ const typeFormat = (row: OperLogForm) => {
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
<style lang="scss" scoped>
|
||||
/**
|
||||
label宽度固定
|
||||
*/
|
||||
|
@ -2,7 +2,7 @@
|
||||
<div></div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup lang="ts">
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
|
||||
const route = useRoute();
|
||||
|
@ -67,7 +67,7 @@
|
||||
</el-form>
|
||||
<!-- 底部 -->
|
||||
<div class="el-register-footer">
|
||||
<span>Copyright © 2018-2024 疯狂的狮子Li All Rights Reserved.</span>
|
||||
<span>Copyright © 2018-2025 疯狂的狮子Li All Rights Reserved.</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -2,7 +2,7 @@
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="search">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="85px">
|
||||
<el-form-item label="客户端key" prop="clientKey">
|
||||
<el-input v-model="queryParams.clientKey" placeholder="请输入客户端key" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
|
@ -82,7 +82,7 @@
|
||||
<el-tree-select
|
||||
v-model="form.parentId"
|
||||
:data="deptOptions"
|
||||
:props="{ value: 'deptId', label: 'deptName', children: 'children' }"
|
||||
:props="{ value: 'deptId', label: 'deptName', children: 'children' } as any"
|
||||
value-key="deptId"
|
||||
placeholder="选择上级部门"
|
||||
check-strictly
|
||||
|
@ -126,7 +126,7 @@
|
||||
</template>
|
||||
|
||||
<script setup name="Data" lang="ts">
|
||||
import useDictStore from '@/store/modules/dict';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
import { optionselect as getDictOptionselect, getType } from '@/api/system/dict/type';
|
||||
import { listData, getData, delData, addData, updateData } from '@/api/system/dict/data';
|
||||
import { DictTypeVO } from '@/api/system/dict/type/types';
|
||||
|
@ -108,7 +108,7 @@
|
||||
</template>
|
||||
|
||||
<script setup name="Dict" lang="ts">
|
||||
import useDictStore from '@/store/modules/dict';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
import { listType, getType, delType, addType, updateType, refreshCache } from '@/api/system/dict/type';
|
||||
import { DictTypeForm, DictTypeQuery, DictTypeVO } from '@/api/system/dict/type/types';
|
||||
|
||||
|
@ -85,7 +85,7 @@
|
||||
<el-tree-select
|
||||
v-model="form.parentId"
|
||||
:data="menuOptions"
|
||||
:props="{ value: 'menuId', label: 'menuName', children: 'children' }"
|
||||
:props="{ value: 'menuId', label: 'menuName', children: 'children' } as any"
|
||||
value-key="menuId"
|
||||
placeholder="选择上级菜单"
|
||||
check-strictly
|
||||
|
@ -10,7 +10,7 @@
|
||||
class="mt-2"
|
||||
node-key="id"
|
||||
:data="deptOptions"
|
||||
:props="{ label: 'label', children: 'children' }"
|
||||
:props="{ label: 'label', children: 'children' } as any"
|
||||
:expand-on-click-node="false"
|
||||
:filter-node-method="filterNode"
|
||||
highlight-current
|
||||
@ -43,7 +43,7 @@
|
||||
<el-tree-select
|
||||
v-model="queryParams.deptId"
|
||||
:data="deptOptions"
|
||||
:props="{ value: 'id', label: 'label', children: 'children' }"
|
||||
:props="{ value: 'id', label: 'label', children: 'children' } as any"
|
||||
value-key="id"
|
||||
placeholder="请选择部门"
|
||||
check-strictly
|
||||
@ -133,7 +133,7 @@
|
||||
<el-tree-select
|
||||
v-model="form.deptId"
|
||||
:data="deptOptions"
|
||||
:props="{ value: 'id', label: 'label', children: 'children' }"
|
||||
:props="{ value: 'id', label: 'label', children: 'children' } as any"
|
||||
value-key="id"
|
||||
placeholder="请选择部门"
|
||||
check-strictly
|
||||
|
@ -156,5 +156,3 @@ onMounted(() => {
|
||||
getList();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
|
@ -135,7 +135,7 @@
|
||||
node-key="id"
|
||||
:check-strictly="!form.menuCheckStrictly"
|
||||
empty-text="加载中,请稍候"
|
||||
:props="{ label: 'label', children: 'children' }"
|
||||
:props="{ label: 'label', children: 'children' } as any"
|
||||
></el-tree>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注">
|
||||
@ -177,7 +177,7 @@
|
||||
node-key="id"
|
||||
:check-strictly="!form.deptCheckStrictly"
|
||||
empty-text="加载中,请稍候"
|
||||
:props="{ label: 'label', children: 'children' }"
|
||||
:props="{ label: 'label', children: 'children' } as any"
|
||||
></el-tree>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
@ -128,5 +128,3 @@ defineExpose({
|
||||
show
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
|
@ -155,7 +155,7 @@ import {
|
||||
syncTenantDict
|
||||
} from '@/api/system/tenant';
|
||||
import { selectTenantPackage } from '@/api/system/tenantPackage';
|
||||
import useUserStore from '@/store/modules/user';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
import { TenantForm, TenantQuery, TenantVO } from '@/api/system/tenant/types';
|
||||
import { TenantPkgVO } from '@/api/system/tenantPackage/types';
|
||||
|
||||
|
@ -82,7 +82,7 @@
|
||||
node-key="id"
|
||||
:check-strictly="!form.menuCheckStrictly"
|
||||
empty-text="加载中,请稍候"
|
||||
:props="{ label: 'label', children: 'children' }"
|
||||
:props="{ label: 'label', children: 'children' } as any"
|
||||
></el-tree>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
|
@ -10,7 +10,7 @@
|
||||
class="mt-2"
|
||||
node-key="id"
|
||||
:data="deptOptions"
|
||||
:props="{ label: 'label', children: 'children' }"
|
||||
:props="{ label: 'label', children: 'children' } as any"
|
||||
:expand-on-click-node="false"
|
||||
:filter-node-method="filterNode"
|
||||
highlight-current
|
||||
@ -81,8 +81,9 @@
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item icon="Download" @click="importTemplate">下载模板</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permi="['system:user:import']" icon="Top" @click="handleImport">导入数据</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permi="['system:user:export']" icon="Download" @click="handleExport">导出数据</el-dropdown-item>
|
||||
<!-- 注意 由于el-dropdown-item标签是延迟加载的 所以v-has-permi自定义标签不生效 需要使用v-if调用方法执行 -->
|
||||
<el-dropdown-item v-if="checkPermi(['system:user:import'])" icon="Top" @click="handleImport">导入数据</el-dropdown-item>
|
||||
<el-dropdown-item v-if="checkPermi(['system:user:export'])" icon="Download" @click="handleExport">导出数据</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
@ -155,7 +156,7 @@
|
||||
<el-tree-select
|
||||
v-model="form.deptId"
|
||||
:data="enabledDeptOptions"
|
||||
:props="{ value: 'id', label: 'label', children: 'children' }"
|
||||
:props="{ value: 'id', label: 'label', children: 'children' } as any"
|
||||
value-key="id"
|
||||
placeholder="请选择归属部门"
|
||||
check-strictly
|
||||
@ -294,6 +295,8 @@ import { treeselect } from '@/api/system/dept';
|
||||
import { globalHeaders } from '@/utils/request';
|
||||
import { to } from 'await-to-js';
|
||||
import { optionselect } from '@/api/system/post';
|
||||
import { hasPermi } from '@/directive/permission';
|
||||
import { checkPermi } from '@/utils/permission';
|
||||
|
||||
const router = useRouter();
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
@ -450,7 +453,7 @@ const getDeptTree = async () => {
|
||||
|
||||
/** 过滤禁用的部门 */
|
||||
const filterDisabledDept = (deptList: DeptTreeVO[]) => {
|
||||
return deptList.filter(dept => {
|
||||
return deptList.filter((dept) => {
|
||||
if (dept.disabled) {
|
||||
return false;
|
||||
}
|
||||
@ -660,5 +663,3 @@ async function handleDeptChange(value: number | string) {
|
||||
form.value.postIds = [];
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
|
@ -26,7 +26,7 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script name="Online" lang="ts" setup>
|
||||
<script setup name="Online" lang="ts">
|
||||
import { delOnline } from '@/api/monitor/online';
|
||||
import { propTypes } from '@/utils/propTypes';
|
||||
|
||||
|
@ -55,10 +55,10 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
<script setup lang="ts">
|
||||
import { authUnlock, authBinding } from '@/api/system/social/auth';
|
||||
import { propTypes } from '@/utils/propTypes';
|
||||
import useUserStore from '@/store/modules/user';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
@ -94,7 +94,7 @@ const authUrl = (source: string) => {
|
||||
};
|
||||
</script>
|
||||
|
||||
<style type="text/css">
|
||||
<style lang="scss" scoped>
|
||||
.user-bind .third-app {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
@ -128,8 +128,9 @@ a {
|
||||
}
|
||||
|
||||
.provider-desc {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol',
|
||||
'Liberation Sans', 'PingFang SC', 'Microsoft YaHei', 'Hiragino Sans GB', 'Wenquanyi Micro Hei', 'WenQuanYi Zen Hei', 'ST Heiti', SimHei, SimSun,
|
||||
font-family:
|
||||
-apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Liberation Sans',
|
||||
'PingFang SC', 'Microsoft YaHei', 'Hiragino Sans GB', 'Wenquanyi Micro Hei', 'WenQuanYi Zen Hei', 'ST Heiti', SimHei, SimSun,
|
||||
'WenQuanYi Zen Hei Sharp', sans-serif;
|
||||
font-size: 1.071rem;
|
||||
}
|
||||
|
@ -59,7 +59,7 @@
|
||||
import 'vue-cropper/dist/index.css';
|
||||
import { VueCropper } from 'vue-cropper';
|
||||
import { uploadAvatar } from '@/api/system/user';
|
||||
import useUserStore from '@/store/modules/user';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
import { UploadRawFile } from 'element-plus';
|
||||
|
||||
interface Options {
|
||||
|
@ -89,7 +89,7 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="字典类型" min-width="12%">
|
||||
<template #default="scope">
|
||||
<el-select v-model="scope.row.dictType" clearable filterable placeholder="请选择">
|
||||
<el-select v-model="scope.row.dictType" clearable filterable placeholder="请选择" value-on-clear="">
|
||||
<el-option v-for="dict in dictOptions" :key="dict.dictType" :label="dict.dictName" :value="dict.dictType">
|
||||
<span style="float: left">{{ dict.dictName }}</span>
|
||||
<span style="float: right; color: #8492a6; font-size: 13px">{{ dict.dictType }}</span>
|
||||
|
@ -70,7 +70,7 @@
|
||||
<el-tree-select
|
||||
v-model="infoForm.parentMenuId"
|
||||
:data="menuOptions"
|
||||
:props="{ value: 'menuId', label: 'menuName', children: 'children' }"
|
||||
:props="{ value: 'menuId', label: 'menuName', children: 'children' } as any"
|
||||
value-key="menuId"
|
||||
node-key="menuId"
|
||||
placeholder="选择上级菜单"
|
||||
|
@ -58,7 +58,7 @@
|
||||
<el-tree-select
|
||||
v-model="form.parentId"
|
||||
:data="categoryOptions"
|
||||
:props="{ value: 'categoryId', label: 'categoryName', children: 'children' }"
|
||||
:props="{ value: 'categoryId', label: 'categoryName', children: 'children' } as any"
|
||||
value-key="categoryId"
|
||||
placeholder="请选择上级分类"
|
||||
check-strictly
|
||||
|
@ -111,6 +111,10 @@ const flowCodeOptions = [
|
||||
{
|
||||
value: 'leave5',
|
||||
label: '请假申请-并行会签网关'
|
||||
},
|
||||
{
|
||||
value: 'leave6',
|
||||
label: '请假申请-排他并行会签'
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
class="mt-2"
|
||||
node-key="id"
|
||||
:data="categoryOptions"
|
||||
:props="{ label: 'label', children: 'children' }"
|
||||
:props="{ label: 'label', children: 'children' } as any"
|
||||
:expand-on-click-node="false"
|
||||
:filter-node-method="filterNode"
|
||||
highlight-current
|
||||
@ -131,7 +131,7 @@
|
||||
<el-tree-select
|
||||
v-model="selectCategory"
|
||||
:data="categoryOptions"
|
||||
:props="{ value: 'id', label: 'label', children: 'children' }"
|
||||
:props="{ value: 'id', label: 'label', children: 'children' } as any"
|
||||
filterable
|
||||
value-key="id"
|
||||
:render-after-expand="false"
|
||||
@ -163,7 +163,7 @@
|
||||
<el-tree-select
|
||||
v-model="form.category"
|
||||
:data="categoryOptions"
|
||||
:props="{ value: 'id', label: 'label', children: 'children' }"
|
||||
:props="{ value: 'id', label: 'label', children: 'children' } as any"
|
||||
filterable
|
||||
value-key="id"
|
||||
:render-after-expand="false"
|
||||
@ -177,7 +177,7 @@
|
||||
<el-form-item label="流程名称" prop="flowName">
|
||||
<el-input v-model="form.flowName" placeholder="请输入流程名称" maxlength="100" show-word-limit />
|
||||
</el-form-item>
|
||||
<el-form-item label="表单路径" prop="flowName">
|
||||
<el-form-item label="表单路径" prop="formPath">
|
||||
<el-input v-model="form.formPath" placeholder="请输入表单路径" maxlength="100" show-word-limit />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
@ -190,12 +190,13 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup name="processDefinition">
|
||||
<script setup name="processDefinition" lang="ts">
|
||||
import { listDefinition, deleteDefinition, active, importDef, unPublishList, publish, add, edit, getInfo, copy } from '@/api/workflow/definition';
|
||||
import { categoryTree } from '@/api/workflow/category';
|
||||
import { CategoryTreeVO } from '@/api/workflow/category/types';
|
||||
import { FlowDefinitionQuery, FlowDefinitionVo, FlowDefinitionForm } from '@/api/workflow/definition/types';
|
||||
import { UploadRequestOptions, TabsPaneContext } from 'element-plus';
|
||||
import { ElMessageBoxOptions } from "element-plus/es/components/message-box/src/message-box.type";
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
@ -324,9 +325,9 @@ const handleSelectionChange = (selection: any) => {
|
||||
};
|
||||
//分页
|
||||
const getPageList = async () => {
|
||||
console.log(proxy.$route.query.activeName)
|
||||
if (proxy.$route.query.activeName) {
|
||||
activeName.value = proxy.$route.query.activeName;
|
||||
let query = proxy.$route.query;
|
||||
if (query.activeName) {
|
||||
activeName.value = query.activeName;
|
||||
}
|
||||
if (activeName.value === '0') {
|
||||
getList();
|
||||
@ -370,7 +371,7 @@ const handlePublish = async (row?: FlowDefinitionVo) => {
|
||||
loading.value = true;
|
||||
await publish(row.id).finally(() => (loading.value = false));
|
||||
processDefinitionDialog.visible = false;
|
||||
activeName.value = "0"
|
||||
activeName.value = '0';
|
||||
await handleQuery();
|
||||
proxy?.$modal.msgSuccess('发布成功');
|
||||
};
|
||||
@ -417,7 +418,7 @@ const handlerImportDefinition = (data: UploadRequestOptions): XMLHttpRequest =>
|
||||
.then(() => {
|
||||
uploadDialog.visible = false;
|
||||
proxy?.$modal.msgSuccess('部署成功');
|
||||
activeName.value = "1"
|
||||
activeName.value = '1';
|
||||
handleQuery();
|
||||
})
|
||||
.finally(() => {
|
||||
@ -482,9 +483,9 @@ const handleSubmit = async () => {
|
||||
if (valid) {
|
||||
loading.value = true;
|
||||
if (form.value.id) {
|
||||
await edit(form.value).finally(() => loading.value = false);
|
||||
await edit(form.value).finally(() => (loading.value = false));
|
||||
} else {
|
||||
await add(form.value).finally(() => loading.value = false);
|
||||
await add(form.value).finally(() => (loading.value = false));
|
||||
}
|
||||
proxy?.$modal.msgSuccess('操作成功');
|
||||
modelDialog.visible = false;
|
||||
@ -498,15 +499,17 @@ const handleCopyDef = async (row: FlowDefinitionVo) => {
|
||||
confirmButtonText: '确认',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
} as ElMessageBoxOptions).then(() => {
|
||||
loading.value = true;
|
||||
copy(row.id).then((resp) => {
|
||||
copy(row.id)
|
||||
.then((resp) => {
|
||||
if (resp.code === 200) {
|
||||
proxy?.$modal.msgSuccess('操作成功');
|
||||
activeName.value = "1"
|
||||
activeName.value = '1';
|
||||
handleQuery();
|
||||
}
|
||||
}).finally(() => loading.value = false);
|
||||
})
|
||||
.finally(() => (loading.value = false));
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
class="mt-2"
|
||||
node-key="id"
|
||||
:data="categoryOptions"
|
||||
:props="{ label: 'label', children: 'children' }"
|
||||
:props="{ label: 'label', children: 'children' } as any"
|
||||
:expand-on-click-node="false"
|
||||
:filter-node-method="filterNode"
|
||||
highlight-current
|
||||
@ -174,7 +174,7 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
<script setup lang="ts">
|
||||
import { pageByRunning, pageByFinish, deleteByInstanceIds, instanceVariable, invalid } from '@/api/workflow/instance';
|
||||
import { categoryTree } from '@/api/workflow/category';
|
||||
import { CategoryTreeVO } from '@/api/workflow/category/types';
|
||||
|
@ -97,14 +97,14 @@
|
||||
</el-card>
|
||||
<!-- 选人组件 -->
|
||||
<UserSelect ref="userSelectRef" :multiple="false" @confirm-call-back="submitCallback"></UserSelect>
|
||||
<!-- 选人组件 -->
|
||||
<!-- 流程干预组件 -->
|
||||
<processMeddle ref="processMeddleRef" @submitCallback="getWaitingList"></processMeddle>
|
||||
<!-- 申请人 -->
|
||||
<UserSelect ref="applyUserSelectRef" :multiple="true" :data="selectUserIds" @confirm-call-back="userSelectCallBack"></UserSelect>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
<script setup lang="ts">
|
||||
import { pageByAllTaskWait, pageByAllTaskFinish, updateAssignee } from '@/api/workflow/task';
|
||||
import UserSelect from '@/components/UserSelect';
|
||||
import { TaskQuery } from '@/api/workflow/task/types';
|
||||
|
@ -10,7 +10,7 @@
|
||||
class="mt-2"
|
||||
node-key="id"
|
||||
:data="categoryOptions"
|
||||
:props="{ label: 'label', children: 'children' }"
|
||||
:props="{ label: 'label', children: 'children' } as any"
|
||||
:expand-on-click-node="false"
|
||||
:filter-node-method="filterNode"
|
||||
highlight-current
|
||||
@ -101,7 +101,7 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
<script setup lang="ts">
|
||||
import { pageByCurrent, deleteByInstanceIds, cancelProcessApply } from '@/api/workflow/instance';
|
||||
import { categoryTree } from '@/api/workflow/category';
|
||||
import { CategoryTreeVO } from '@/api/workflow/category/types';
|
||||
|
@ -59,7 +59,7 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
<script setup lang="ts">
|
||||
import { pageByTaskCopy } from '@/api/workflow/task';
|
||||
import { TaskQuery } from '@/api/workflow/task/types';
|
||||
import workflowCommon from '@/api/workflow/workflowCommon';
|
||||
|
@ -80,7 +80,7 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
<script setup lang="ts">
|
||||
import { pageByTaskFinish } from '@/api/workflow/task';
|
||||
import { TaskQuery, FlowTaskVO } from '@/api/workflow/task/types';
|
||||
import workflowCommon from '@/api/workflow/workflowCommon';
|
||||
|
@ -77,7 +77,7 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
<script setup lang="ts">
|
||||
import { pageByTaskWait } from '@/api/workflow/task';
|
||||
import { TaskQuery, FlowTaskVO } from '@/api/workflow/task/types';
|
||||
import workflowCommon from '@/api/workflow/workflowCommon';
|
||||
|
@ -1,31 +1,42 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"compilerOptions": {
|
||||
"target": "esnext",
|
||||
"module": "esnext",
|
||||
// "useDefineForClassFields": true,
|
||||
"moduleResolution": "bundler",
|
||||
"baseUrl": ".",
|
||||
// https://vite.dev/config/build-options.html#build-target
|
||||
"target": "ES2020",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "Bundler",
|
||||
"lib": ["ESNext", "DOM", "DOM.Iterable"],
|
||||
"skipLibCheck": true,
|
||||
// This setting lets you specify a file for storing incremental compilation information as a part of composite projects which enables faster building of larger TypeScript codebases.
|
||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.tsbuildinfo",
|
||||
"strict": true,
|
||||
"allowJs": true,
|
||||
"jsx": "preserve",
|
||||
"strictNullChecks": false,
|
||||
"sourceMap": true,
|
||||
"resolveJsonModule": true,
|
||||
"esModuleInterop": true,
|
||||
"strictFunctionTypes": false,
|
||||
"lib": ["esnext", "dom"],
|
||||
"noImplicitAny": false,
|
||||
"baseUrl": ".",
|
||||
"allowJs": true,
|
||||
"experimentalDecorators": true,
|
||||
"noEmit": true,
|
||||
"paths": {
|
||||
"@/*": ["src/*"]
|
||||
"@/*": ["./src/*"]
|
||||
},
|
||||
"types": ["vite/client"],
|
||||
"skipLibCheck": true,
|
||||
"removeComments": true,
|
||||
// 允许默认导入
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"forceConsistentCasingInFileNames": true
|
||||
"types": ["node", "vite/client"],
|
||||
// 自定义配置
|
||||
"noImplicitAny": false, // 禁用 隐式的any错误
|
||||
"removeComments": true, // 移除 ts注释
|
||||
"experimentalDecorators": true, // 启用实验性的装饰器支持
|
||||
"strictFunctionTypes": false, // 禁用严格函数类型检查
|
||||
"strictNullChecks": false, // 禁用严格的空值检查
|
||||
"allowSyntheticDefaultImports": true, // 允许默认导入
|
||||
"forceConsistentCasingInFileNames": true // 强制在文件名中使用一致的大小写
|
||||
},
|
||||
"include": ["src/**/*.ts", "src/**/*.vue", "src/types/**/*.d.ts", "vite.config.ts"],
|
||||
"exclude": ["node_modules", "dist", "**/*.js", "**/*.md", "src/**/*.md"]
|
||||
"include": [
|
||||
"src/**/*.ts",
|
||||
"src/**/*.vue",
|
||||
"vite.config.ts",
|
||||
"vitest.config.ts",
|
||||
"eslint.config.ts",
|
||||
"src/**/*.d.ts"
|
||||
],
|
||||
"exclude": ["node_modules", "dist", "src/**/__tests__/*"]
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { UserConfig, ConfigEnv, loadEnv, defineConfig } from 'vite';
|
||||
|
||||
import { defineConfig, loadEnv } from 'vite';
|
||||
import createPlugins from './vite/plugins';
|
||||
|
||||
import autoprefixer from 'autoprefixer'; // css自动添加兼容性前缀
|
||||
import path from 'path';
|
||||
export default defineConfig(({ mode, command }: ConfigEnv): UserConfig => {
|
||||
|
||||
export default defineConfig(({ mode, command }) => {
|
||||
const env = loadEnv(mode, process.cwd());
|
||||
return {
|
||||
// 部署生产环境和开发环境下的URL。
|
||||
@ -12,7 +12,6 @@ export default defineConfig(({ mode, command }: ConfigEnv): UserConfig => {
|
||||
base: env.VITE_APP_CONTEXT_PATH,
|
||||
resolve: {
|
||||
alias: {
|
||||
'~': path.resolve(__dirname, './'),
|
||||
'@': path.resolve(__dirname, './src')
|
||||
},
|
||||
extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue']
|
||||
@ -35,21 +34,23 @@ export default defineConfig(({ mode, command }: ConfigEnv): UserConfig => {
|
||||
css: {
|
||||
preprocessorOptions: {
|
||||
scss: {
|
||||
javascriptEnabled: true
|
||||
// additionalData: '@use "@/assets/styles/variables.module.scss as *";'
|
||||
// javascriptEnabled: true
|
||||
api: 'modern-compiler'
|
||||
}
|
||||
},
|
||||
postcss: {
|
||||
plugins: [
|
||||
// 浏览器兼容性
|
||||
autoprefixer(),
|
||||
{
|
||||
postcssPlugin: 'internal:charset-removal',
|
||||
AtRule: {
|
||||
charset: (atRule) => {
|
||||
if (atRule.name === 'charset') {
|
||||
atRule.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
|
@ -1,22 +1,18 @@
|
||||
import AutoImport from 'unplugin-auto-import/vite';
|
||||
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers';
|
||||
import IconsResolver from 'unplugin-icons/resolver';
|
||||
|
||||
export default (path: any) => {
|
||||
return AutoImport({
|
||||
// 自动导入 Vue 相关函数
|
||||
imports: ['vue', 'vue-router', '@vueuse/core', 'pinia'],
|
||||
eslintrc: {
|
||||
enabled: false,
|
||||
enabled: true,
|
||||
filepath: './.eslintrc-auto-import.json',
|
||||
globalsPropValue: true
|
||||
},
|
||||
resolvers: [
|
||||
// 自动导入 Element Plus 相关函数ElMessage, ElMessageBox... (带样式)
|
||||
ElementPlusResolver(),
|
||||
IconsResolver({
|
||||
prefix: 'Icon'
|
||||
})
|
||||
ElementPlusResolver()
|
||||
],
|
||||
vueTemplate: true, // 是否在 vue 模板中自动导入
|
||||
dts: path.resolve(path.resolve(__dirname, '../../src'), 'types', 'auto-imports.d.ts')
|
||||
|
@ -1,4 +1,6 @@
|
||||
import vue from '@vitejs/plugin-vue';
|
||||
import vueDevTools from 'vite-plugin-vue-devtools';
|
||||
|
||||
import createUnoCss from './unocss';
|
||||
import createAutoImport from './auto-import';
|
||||
import createComponents from './components';
|
||||
@ -11,12 +13,13 @@ import path from 'path';
|
||||
export default (viteEnv: any, isBuild = false): [] => {
|
||||
const vitePlugins: any = [];
|
||||
vitePlugins.push(vue());
|
||||
vitePlugins.push(vueDevTools());
|
||||
vitePlugins.push(createUnoCss());
|
||||
vitePlugins.push(createAutoImport(path));
|
||||
vitePlugins.push(createComponents(path));
|
||||
vitePlugins.push(createCompression(viteEnv));
|
||||
vitePlugins.push(createIcons());
|
||||
vitePlugins.push(createSvgIconsPlugin(path, isBuild));
|
||||
vitePlugins.push(createSvgIconsPlugin(path));
|
||||
vitePlugins.push(createSetupExtend());
|
||||
return vitePlugins;
|
||||
};
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons';
|
||||
export default (path: any, isBuild: boolean) => {
|
||||
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons-ng';
|
||||
|
||||
export default (path: any) => {
|
||||
return createSvgIconsPlugin({
|
||||
// 指定需要缓存的图标文件夹
|
||||
iconDirs: [path.resolve(path.resolve(__dirname, '../../src'), 'assets/icons/svg')],
|
||||
// 指定symbolId格式
|
||||
symbolId: 'icon-[dir]-[name]',
|
||||
svgoOptions: isBuild
|
||||
symbolId: 'icon-[dir]-[name]'
|
||||
});
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user