mirror of
https://github.com/vbenjs/vue-vben-admin.git
synced 2025-08-26 00:26:20 +08:00
Compare commits
43 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
038936ff7d | ||
![]() |
960f1d3c0b | ||
![]() |
f67b5d8569 | ||
![]() |
f99cc9b9fe | ||
![]() |
0cf2271667 | ||
![]() |
6d2de002ef | ||
![]() |
617e594d8d | ||
![]() |
4aac1c388c | ||
![]() |
7b6531a309 | ||
![]() |
65651fc25c | ||
![]() |
4fcbdd3925 | ||
![]() |
db2a27060c | ||
![]() |
d9bfe96dad | ||
![]() |
77a0ad450d | ||
![]() |
c37ed8f7e9 | ||
![]() |
1698be7ce4 | ||
![]() |
ea5c66b6eb | ||
![]() |
371c972cc1 | ||
![]() |
2880174be2 | ||
![]() |
b0c0b916fd | ||
![]() |
f314826230 | ||
![]() |
56c5dce99f | ||
![]() |
95abe06107 | ||
![]() |
ecfe66a019 | ||
![]() |
25699c0b60 | ||
![]() |
5b7b6b1780 | ||
![]() |
57ff038d82 | ||
![]() |
baf406e7e2 | ||
![]() |
1745f480fd | ||
![]() |
cec5c11289 | ||
![]() |
dd1b16acdc | ||
![]() |
64a4992a84 | ||
![]() |
cae5538aba | ||
![]() |
e7868e7193 | ||
![]() |
71c4edad63 | ||
![]() |
65fba1c329 | ||
![]() |
8d3981f599 | ||
![]() |
cca7f59fac | ||
![]() |
1a5692060b | ||
![]() |
4974de2553 | ||
![]() |
f83002441d | ||
![]() |
e84c4051f3 | ||
![]() |
af39afa24b |
@@ -5,4 +5,4 @@
|
||||
|
||||
PATH="/usr/local/bin:$PATH"
|
||||
|
||||
npx --no-install commitlint --edit "$1"
|
||||
# npx --no-install commitlint --edit "$1"
|
||||
|
@@ -7,4 +7,4 @@
|
||||
PATH="/usr/local/bin:$PATH"
|
||||
|
||||
# Format and submit code according to lintstagedrc.js configuration
|
||||
pnpm exec lint-staged
|
||||
# pnpm exec lint-staged
|
||||
|
@@ -63,8 +63,8 @@ function defineApplicationConfig(defineOptions: DefineOptions = {}) {
|
||||
cssTarget: 'chrome80',
|
||||
rollupOptions: {
|
||||
output: {
|
||||
// 入口文件名(不能变,否则所有打包的 js hash 值全变了)
|
||||
entryFileNames: 'index.js',
|
||||
// 入口文件名
|
||||
entryFileNames: 'assets/entry/[name]-[hash].js',
|
||||
manualChunks: {
|
||||
vue: ['vue', 'pinia', 'vue-router'],
|
||||
antd: ['ant-design-vue', '@ant-design/icons-vue'],
|
||||
|
@@ -107,9 +107,10 @@
|
||||
"vue-router": "^4.3.2",
|
||||
"vue-types": "^5.1.1",
|
||||
"vuedraggable": "^4.1.0",
|
||||
"vxe-table": "^4.6.3",
|
||||
"vxe-table-plugin-export-xlsx": "^4.0.1",
|
||||
"xe-utils": "^3.5.25",
|
||||
"vxe-pc-ui": "^4.0.44",
|
||||
"vxe-table": "^4.7.40",
|
||||
"vxe-table-plugin-export-xlsx": "^4.0.4",
|
||||
"xe-utils": "^3.5.28",
|
||||
"xlsx": "^0.18.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
62
pnpm-lock.yaml
generated
62
pnpm-lock.yaml
generated
@@ -122,15 +122,18 @@ importers:
|
||||
vuedraggable:
|
||||
specifier: ^4.1.0
|
||||
version: 4.1.0(vue@3.4.25(typescript@5.4.5))
|
||||
vxe-pc-ui:
|
||||
specifier: ^4.0.44
|
||||
version: 4.0.44
|
||||
vxe-table:
|
||||
specifier: ^4.6.3
|
||||
version: 4.6.3(vue@3.4.25(typescript@5.4.5))
|
||||
specifier: ^4.7.40
|
||||
version: 4.7.40
|
||||
vxe-table-plugin-export-xlsx:
|
||||
specifier: ^4.0.1
|
||||
version: 4.0.1(vxe-table@4.6.3(vue@3.4.25(typescript@5.4.5)))
|
||||
specifier: ^4.0.4
|
||||
version: 4.0.4(vxe-table@4.7.40)
|
||||
xe-utils:
|
||||
specifier: ^3.5.25
|
||||
version: 3.5.25
|
||||
specifier: ^3.5.28
|
||||
version: 3.5.28
|
||||
xlsx:
|
||||
specifier: ^0.18.5
|
||||
version: 0.18.5
|
||||
@@ -2005,6 +2008,9 @@ packages:
|
||||
'@vueuse/shared@10.9.0':
|
||||
resolution: {integrity: sha512-Uud2IWncmAfJvRaFYzv5OHDli+FbOzxiVEQdLCKQKLyhz94PIyFC3CHcH7EDMwIn8NPtD06+PNbC/PiO0LGLtw==}
|
||||
|
||||
'@vxe-ui/core@1.0.12':
|
||||
resolution: {integrity: sha512-s79mQw6uYSbTVGBWbxrisHwJV1b770vZMT9XpY3khcFQhXNo25+PS3FLrNCSsBBJR0ZkBLOXDER/ft9DIqgFTw==}
|
||||
|
||||
'@zxcvbn-ts/core@3.0.4':
|
||||
resolution: {integrity: sha512-aQeiT0F09FuJaAqNrxynlAwZ2mW/1MdXakKWNmGM1Qp/VaY6CnB/GfnMS2T8gB2231Esp1/maCWd8vTG4OuShw==}
|
||||
|
||||
@@ -3096,8 +3102,8 @@ packages:
|
||||
dom-serializer@2.0.0:
|
||||
resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==}
|
||||
|
||||
dom-zindex@1.0.2:
|
||||
resolution: {integrity: sha512-QceDZxPlvzhpg6e8szxNiKPUt5Y9SfFTe3nZy8og3JoPQPlAlzBzHa/lhDkhgeG3cjbKyQcuoic+wymF0o0d1Q==}
|
||||
dom-zindex@1.0.4:
|
||||
resolution: {integrity: sha512-PNk7u71TJ1C9Lwjjp5nNuQcVWuECFMmr9kZAwi2UbgWUM7jXdTCe4O4x5bhLUa07jpcZUVA5Du3ho7/FXzS9Ng==}
|
||||
|
||||
domelementtype@1.3.1:
|
||||
resolution: {integrity: sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==}
|
||||
@@ -7060,15 +7066,16 @@ packages:
|
||||
peerDependencies:
|
||||
vue: ^3.0.1
|
||||
|
||||
vxe-table-plugin-export-xlsx@4.0.1:
|
||||
resolution: {integrity: sha512-puUOUfptu5ciEiFqTlVni3twLICSbkl87uXOsjZzrEyXJHJS9dYu7ZTD7/DRMqyuWyU3Idg7AekfcdcslP4Y/A==}
|
||||
vxe-pc-ui@4.0.44:
|
||||
resolution: {integrity: sha512-wiauFMmSvEkVKa/AsKGb5CMi91Ojts+Ydcn+iespgl3xMBD01BR/CGzeCI478P3XAFBsiN4gWlgxHmGP5TR8UA==}
|
||||
|
||||
vxe-table-plugin-export-xlsx@4.0.4:
|
||||
resolution: {integrity: sha512-Og2ZcIWTV7msT1ddPT/spxJaP1T8wxs3Uuu1LO/3HL5Ugt9tShEY3FJ7YGic3j1Nk6ZZT+VsU+afgT5EzpcUJw==}
|
||||
peerDependencies:
|
||||
vxe-table: ^4.5.0
|
||||
|
||||
vxe-table@4.6.3:
|
||||
resolution: {integrity: sha512-71FOi0lFQbvs1dUIZPTDCLaSJkRjLHlBuNzWIR9RofBe4EvhX4OowrhaCCsCXXKCCGSlJRp6+/O2c71lEZY9PQ==}
|
||||
peerDependencies:
|
||||
vue: ^3.2.28
|
||||
vxe-table@4.7.40:
|
||||
resolution: {integrity: sha512-y9VC3oLJgusxFj3xZ28G4gU+YClBuDIV8oM75Dx3doYJ7vanXZnSf70XJ+W5xEKflamUmjGre66XZ2b4XuqtMw==}
|
||||
|
||||
w3c-hr-time@1.0.2:
|
||||
resolution: {integrity: sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==}
|
||||
@@ -7206,8 +7213,8 @@ packages:
|
||||
utf-8-validate:
|
||||
optional: true
|
||||
|
||||
xe-utils@3.5.25:
|
||||
resolution: {integrity: sha512-d/ty5eo4hXtho/3195XAvqereIoSYJ+XfC52f3ZEPxTaCeyLFivDZTyX6gTdsR65ISH1Irvn85H0bSL60dUhSQ==}
|
||||
xe-utils@3.5.28:
|
||||
resolution: {integrity: sha512-oeLLJ0b54QdOSSgYQ9TiKW/xAGrc9r0weCA/5UfyGdm3n3js4cNOuuf9Tml7UwgBQpl4uWMbMwUZKLh2yqPF3A==}
|
||||
|
||||
xlsx@0.18.5:
|
||||
resolution: {integrity: sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==}
|
||||
@@ -9228,6 +9235,11 @@ snapshots:
|
||||
- '@vue/composition-api'
|
||||
- vue
|
||||
|
||||
'@vxe-ui/core@1.0.12':
|
||||
dependencies:
|
||||
dom-zindex: 1.0.4
|
||||
xe-utils: 3.5.28
|
||||
|
||||
'@zxcvbn-ts/core@3.0.4':
|
||||
dependencies:
|
||||
fastest-levenshtein: 1.0.16
|
||||
@@ -10389,7 +10401,7 @@ snapshots:
|
||||
domhandler: 5.0.3
|
||||
entities: 4.5.0
|
||||
|
||||
dom-zindex@1.0.2: {}
|
||||
dom-zindex@1.0.4: {}
|
||||
|
||||
domelementtype@1.3.1: {}
|
||||
|
||||
@@ -15005,15 +15017,17 @@ snapshots:
|
||||
sortablejs: 1.14.0
|
||||
vue: 3.4.25(typescript@5.4.5)
|
||||
|
||||
vxe-table-plugin-export-xlsx@4.0.1(vxe-table@4.6.3(vue@3.4.25(typescript@5.4.5))):
|
||||
vxe-pc-ui@4.0.44:
|
||||
dependencies:
|
||||
vxe-table: 4.6.3(vue@3.4.25(typescript@5.4.5))
|
||||
'@vxe-ui/core': 1.0.12
|
||||
|
||||
vxe-table@4.6.3(vue@3.4.25(typescript@5.4.5)):
|
||||
vxe-table-plugin-export-xlsx@4.0.4(vxe-table@4.7.40):
|
||||
dependencies:
|
||||
dom-zindex: 1.0.2
|
||||
vue: 3.4.25(typescript@5.4.5)
|
||||
xe-utils: 3.5.25
|
||||
vxe-table: 4.7.40
|
||||
|
||||
vxe-table@4.7.40:
|
||||
dependencies:
|
||||
vxe-pc-ui: 4.0.44
|
||||
|
||||
w3c-hr-time@1.0.2:
|
||||
dependencies:
|
||||
@@ -15138,7 +15152,7 @@ snapshots:
|
||||
|
||||
ws@8.16.0: {}
|
||||
|
||||
xe-utils@3.5.25: {}
|
||||
xe-utils@3.5.28: {}
|
||||
|
||||
xlsx@0.18.5:
|
||||
dependencies:
|
||||
|
@@ -151,7 +151,7 @@
|
||||
fileReader.onerror = () => {
|
||||
emit('cropendError');
|
||||
};
|
||||
}, 'image/png');
|
||||
}, 'image/jpeg');
|
||||
}
|
||||
|
||||
// Get a circular picture canvas
|
||||
|
@@ -54,7 +54,7 @@
|
||||
|
||||
import { useFormValues } from './hooks/useFormValues';
|
||||
import useAdvanced from './hooks/useAdvanced';
|
||||
import { useFormEvents } from './hooks/useFormEvents';
|
||||
import { itemIsUploadComponent, useFormEvents } from './hooks/useFormEvents';
|
||||
import { createFormContext } from './hooks/useFormContext';
|
||||
import { useAutoFocus } from './hooks/useAutoFocus';
|
||||
import { useModalContext } from '@/components/Modal';
|
||||
@@ -64,7 +64,7 @@
|
||||
import { useDesign } from '@/hooks/web/useDesign';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { TableActionType } from '@/components/Table';
|
||||
import { isFunction } from '@/utils/is';
|
||||
import { isArray, isFunction } from '@/utils/is';
|
||||
|
||||
defineOptions({ name: 'BasicForm' });
|
||||
|
||||
@@ -124,7 +124,9 @@
|
||||
const getBindValue = computed(() => ({ ...attrs, ...props, ...unref(getProps) }) as AntFormProps);
|
||||
|
||||
const getSchema = computed((): FormSchema[] => {
|
||||
const schemas: FormSchema[] = cloneDeep(unref(schemaRef) || (unref(getProps).schemas as any));
|
||||
const schemas: (FormSchema & { ifshow2?: boolean })[] = cloneDeep(
|
||||
unref(schemaRef) || (unref(getProps).schemas as any),
|
||||
);
|
||||
for (const schema of schemas) {
|
||||
const {
|
||||
defaultValue,
|
||||
@@ -134,7 +136,16 @@
|
||||
field,
|
||||
isHandleDefaultValue = true,
|
||||
valueFormat,
|
||||
ifShow,
|
||||
} = schema;
|
||||
|
||||
//fix:修复showAdvancedButton为true时,FormSchema中ifshow是与model有关的函数时候,查询按钮位置不重新计算的问题。
|
||||
if (unref(getProps).showAdvancedButton) {
|
||||
schema.ifshow2 = isFunction(ifShow)
|
||||
? ifShow({ schema, values: formModel, model: formModel, field })
|
||||
: ifShow;
|
||||
}
|
||||
|
||||
// handle date type
|
||||
if (
|
||||
isHandleDateDefaultValue &&
|
||||
@@ -165,14 +176,17 @@
|
||||
schema.defaultValue = def;
|
||||
}
|
||||
}
|
||||
// handle upload type
|
||||
if (defaultValue && itemIsUploadComponent(schema?.component)) {
|
||||
if (isArray(defaultValue)) {
|
||||
schema.defaultValue = defaultValue;
|
||||
} else if (typeof defaultValue == 'string') {
|
||||
schema.defaultValue = [defaultValue];
|
||||
}
|
||||
}
|
||||
|
||||
// handle schema.valueFormat
|
||||
if (
|
||||
isHandleDefaultValue &&
|
||||
defaultValue &&
|
||||
component &&
|
||||
isFunction(valueFormat)
|
||||
) {
|
||||
if (isHandleDefaultValue && defaultValue && component && isFunction(valueFormat)) {
|
||||
schema.defaultValue = valueFormat({
|
||||
value: defaultValue,
|
||||
schema,
|
||||
|
@@ -3,6 +3,7 @@
|
||||
@dropdown-visible-change="handleFetch"
|
||||
v-bind="$attrs"
|
||||
@change="handleChange"
|
||||
@search="debounceSearchFn"
|
||||
:options="getOptions"
|
||||
v-model:value="state"
|
||||
>
|
||||
@@ -20,26 +21,41 @@
|
||||
</template>
|
||||
</Select>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { PropType, ref, computed, unref, watch } from 'vue';
|
||||
import { computed, PropType, ref, unref, watch } from 'vue';
|
||||
import { Select } from 'ant-design-vue';
|
||||
import type { SelectValue } from 'ant-design-vue/es/select';
|
||||
import { isFunction } from '@/utils/is';
|
||||
import { isEmpty, isFunction } from '@/utils/is';
|
||||
import { useRuleFormItem } from '@/hooks/component/useFormItem';
|
||||
import { get, omit, isEqual } from 'lodash-es';
|
||||
import { assignIn, get, isEqual, omit } from 'lodash-es';
|
||||
import { LoadingOutlined } from '@ant-design/icons-vue';
|
||||
import { useI18n } from '@/hooks/web/useI18n';
|
||||
import { propTypes } from '@/utils/propTypes';
|
||||
import { useDebounceFn } from '@vueuse/core';
|
||||
|
||||
type OptionsItem = { label?: string; value?: string; disabled?: boolean; [name: string]: any };
|
||||
|
||||
type ApiSearchOption = {
|
||||
// 展示搜索
|
||||
show?: boolean;
|
||||
// 待搜索字段名
|
||||
searchName?: string;
|
||||
// 是否允许空搜索
|
||||
emptySearch?: boolean;
|
||||
// 搜索前置方法
|
||||
beforeFetch?: (value?: string) => Promise<string>;
|
||||
// 拦截方法
|
||||
interceptFetch?: (value?: string) => Promise<boolean>;
|
||||
};
|
||||
|
||||
defineOptions({ name: 'ApiSelect', inheritAttrs: false });
|
||||
|
||||
const props = defineProps({
|
||||
value: { type: [Array, Object, String, Number] as PropType<SelectValue> },
|
||||
numberToString: propTypes.bool,
|
||||
api: {
|
||||
type: Function as PropType<(arg?: any) => Promise<OptionsItem[] | Recordable<any>>>,
|
||||
type: Function as PropType<(arg?: any) => Promise<OptionsItem[] | Recordable>>,
|
||||
default: null,
|
||||
},
|
||||
// api params
|
||||
@@ -54,6 +70,10 @@
|
||||
type: Array<OptionsItem>,
|
||||
default: [],
|
||||
},
|
||||
apiSearch: {
|
||||
type: Object as PropType<ApiSearchOption>,
|
||||
default: () => null,
|
||||
},
|
||||
beforeFetch: {
|
||||
type: Function as PropType<Fn>,
|
||||
default: null,
|
||||
@@ -72,6 +92,7 @@
|
||||
// 首次是否加载过了
|
||||
const isFirstLoaded = ref(false);
|
||||
const emitData = ref<OptionsItem[]>([]);
|
||||
const searchParams = ref<any>({});
|
||||
const { t } = useI18n();
|
||||
|
||||
// Embedded in the form, just use the hook binding to perform form verification
|
||||
@@ -110,16 +131,29 @@
|
||||
{ deep: true, immediate: props.immediate },
|
||||
);
|
||||
|
||||
watch(
|
||||
() => searchParams.value,
|
||||
(value, oldValue) => {
|
||||
if (isEmpty(value) || isEqual(value, oldValue)) return;
|
||||
(async () => {
|
||||
await fetch();
|
||||
searchParams.value = {};
|
||||
})();
|
||||
},
|
||||
{ deep: true, immediate: props.immediate },
|
||||
);
|
||||
|
||||
async function fetch() {
|
||||
let { api, beforeFetch, afterFetch, params, resultField } = props;
|
||||
if (!api || !isFunction(api) || loading.value) return;
|
||||
optionsRef.value = [];
|
||||
try {
|
||||
loading.value = true;
|
||||
let apiParams = assignIn({}, params, searchParams.value);
|
||||
if (beforeFetch && isFunction(beforeFetch)) {
|
||||
params = (await beforeFetch(params)) || params;
|
||||
apiParams = (await beforeFetch(apiParams)) || apiParams;
|
||||
}
|
||||
let res = await api(params);
|
||||
let res = await api(apiParams);
|
||||
if (afterFetch && isFunction(afterFetch)) {
|
||||
res = (await afterFetch(res)) || res;
|
||||
}
|
||||
@@ -147,11 +181,43 @@
|
||||
if (props.alwaysLoad) {
|
||||
await fetch();
|
||||
} else if (!props.immediate && !unref(isFirstLoaded)) {
|
||||
await fetch();
|
||||
// 动态搜索查询时,允许控制初始不加载数据
|
||||
if (!(!!props.apiSearch && !!props.apiSearch.show && !props.apiSearch.emptySearch)) {
|
||||
await fetch();
|
||||
} else {
|
||||
optionsRef.value = [];
|
||||
emitChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let debounceSearchFn = useDebounceFn(handleSearch, 500);
|
||||
|
||||
async function handleSearch(value: any) {
|
||||
if (!props.apiSearch) {
|
||||
return;
|
||||
}
|
||||
const { show, searchName, beforeFetch, interceptFetch } = props.apiSearch;
|
||||
if (!show || !searchName) {
|
||||
return;
|
||||
}
|
||||
|
||||
value = value || undefined;
|
||||
if (beforeFetch && isFunction(beforeFetch)) {
|
||||
value = (await beforeFetch(value)) || value;
|
||||
}
|
||||
|
||||
if (interceptFetch && isFunction(interceptFetch)) {
|
||||
if (!(await interceptFetch(value))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
searchParams.value = {
|
||||
[searchName]: value,
|
||||
};
|
||||
}
|
||||
|
||||
function emitChange() {
|
||||
emit('options-change', unref(getOptions));
|
||||
}
|
||||
|
@@ -287,11 +287,11 @@
|
||||
const on = {
|
||||
[eventKey]: (...args: Nullable<Recordable<any>>[]) => {
|
||||
const [e] = args;
|
||||
|
||||
|
||||
const target = e ? e.target : null;
|
||||
let value = target ? (isCheck ? target.checked : target.value) : e;
|
||||
if(isFunction(valueFormat)){
|
||||
value = valueFormat({...unref(getValues),value});
|
||||
if (isFunction(valueFormat)) {
|
||||
value = valueFormat({ ...unref(getValues), value });
|
||||
}
|
||||
props.setFormModel(field, value, props.schema);
|
||||
|
||||
|
@@ -31,8 +31,13 @@ export function createPlaceholderMessage(component: ComponentType) {
|
||||
|
||||
const DATE_TYPE = ['DatePicker', 'MonthPicker', 'WeekPicker', 'TimePicker'];
|
||||
|
||||
/**
|
||||
* 上传组件
|
||||
*/
|
||||
export const uploadItemType: ComponentType[] = ['Upload', 'ImageUpload'];
|
||||
|
||||
function genType() {
|
||||
return [...DATE_TYPE, 'RangePicker',"TimeRangePicker"];
|
||||
return [...DATE_TYPE, 'RangePicker', 'TimeRangePicker'];
|
||||
}
|
||||
|
||||
export function setComponentRuleType(
|
||||
@@ -45,7 +50,7 @@ export function setComponentRuleType(
|
||||
}
|
||||
if (['DatePicker', 'MonthPicker', 'WeekPicker', 'TimePicker'].includes(component)) {
|
||||
rule.type = valueFormat ? 'string' : 'object';
|
||||
} else if (['RangePicker', 'Upload', 'CheckboxGroup'].includes(component)) {
|
||||
} else if (['RangePicker', 'CheckboxGroup'].includes(component)) {
|
||||
rule.type = 'array';
|
||||
} else if (['InputNumber'].includes(component)) {
|
||||
rule.type = 'number';
|
||||
|
@@ -1,6 +1,15 @@
|
||||
import type { ColEx } from '../types';
|
||||
import type { AdvanceState } from '../types/hooks';
|
||||
import { ComputedRef, getCurrentInstance, Ref, shallowReactive, computed, unref, watch } from 'vue';
|
||||
import {
|
||||
ComputedRef,
|
||||
getCurrentInstance,
|
||||
Ref,
|
||||
shallowReactive,
|
||||
computed,
|
||||
unref,
|
||||
watch,
|
||||
nextTick,
|
||||
} from 'vue';
|
||||
import type { FormProps, FormSchemaInner as FormSchema } from '../types/form';
|
||||
import { isBoolean, isFunction, isNumber, isObject } from '@/utils/is';
|
||||
import { useBreakpoint } from '@/hooks/event/useBreakpoint';
|
||||
@@ -49,14 +58,17 @@ export default function ({
|
||||
return 0;
|
||||
});
|
||||
|
||||
const debounceUpdateAdvanced = useDebounceFn(updateAdvanced, 30);
|
||||
// const debounceUpdateAdvanced = useDebounceFn(updateAdvanced, 30);
|
||||
|
||||
watch(
|
||||
[() => unref(getSchema), () => advanceState.isAdvanced, () => unref(realWidthRef)],
|
||||
() => {
|
||||
const { showAdvancedButton } = unref(getProps);
|
||||
if (showAdvancedButton) {
|
||||
debounceUpdateAdvanced();
|
||||
// debounceUpdateAdvanced();
|
||||
nextTick(() => {
|
||||
updateAdvanced();
|
||||
});
|
||||
}
|
||||
},
|
||||
{ immediate: true },
|
||||
|
@@ -4,10 +4,16 @@ import type { NamePath } from 'ant-design-vue/lib/form/interface';
|
||||
import { unref, toRaw, nextTick } from 'vue';
|
||||
import { isArray, isFunction, isObject, isString, isNil } from '@/utils/is';
|
||||
import { deepMerge } from '@/utils';
|
||||
import { dateItemType, defaultValueComponents, isIncludeSimpleComponents } from '../helper';
|
||||
import {
|
||||
dateItemType,
|
||||
defaultValueComponents,
|
||||
isIncludeSimpleComponents,
|
||||
uploadItemType,
|
||||
} from '../helper';
|
||||
import { dateUtil } from '@/utils/dateUtil';
|
||||
import { cloneDeep, has, uniqBy, get, set } from 'lodash-es';
|
||||
import { error } from '@/utils/log';
|
||||
import { ComponentProps } from '../types';
|
||||
|
||||
interface UseFormActionContext {
|
||||
emit: EmitType;
|
||||
@@ -19,7 +25,12 @@ interface UseFormActionContext {
|
||||
schemaRef: Ref<FormSchema[]>;
|
||||
handleFormValues: Fn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Is it upload
|
||||
*/
|
||||
export function itemIsUploadComponent(key: keyof ComponentProps) {
|
||||
return uploadItemType.includes(key);
|
||||
}
|
||||
function tryConstructArray(field: string, values: Recordable = {}): any[] | undefined {
|
||||
const pattern = /^\[(.+)\]$/;
|
||||
if (pattern.test(field)) {
|
||||
@@ -123,7 +134,20 @@ export function useFormEvents({
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Adapt upload component
|
||||
if (itemIsUploadComponent(schema?.component)) {
|
||||
constructValue = get(value, key);
|
||||
const fieldValue = constructValue || value;
|
||||
if (fieldValue) {
|
||||
if (isArray(fieldValue)) {
|
||||
unref(formModel)[key] = fieldValue;
|
||||
} else if (typeof fieldValue == 'string') {
|
||||
unref(formModel)[key] = [fieldValue];
|
||||
}
|
||||
}
|
||||
validKeys.push(key);
|
||||
return;
|
||||
}
|
||||
// Adapt common component
|
||||
if (hasKey) {
|
||||
constructValue = get(value, key);
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import type { Ref } from 'vue';
|
||||
import { computed, unref } from 'vue';
|
||||
import type { FormProps, FormSchemaInner as FormSchema } from '../types/form';
|
||||
import { isNumber } from '@/utils/is';
|
||||
import { isDef, isNumber } from '@/utils/is';
|
||||
|
||||
export function useItemLabelWidth(schemaItemRef: Ref<FormSchema>, propsRef: Ref<FormProps>) {
|
||||
return computed(() => {
|
||||
@@ -23,11 +23,11 @@ export function useItemLabelWidth(schemaItemRef: Ref<FormSchema>, propsRef: Ref<
|
||||
};
|
||||
return { labelCol, wrapperCol };
|
||||
}
|
||||
let width = labelWidth || globalLabelWidth;
|
||||
let width = labelWidth ?? globalLabelWidth;
|
||||
const col = { ...globalLabelCol, ...labelCol };
|
||||
const wrapCol = { ...globWrapperCol, ...wrapperCol };
|
||||
|
||||
if (width) {
|
||||
if (isDef(width)) {
|
||||
width = isNumber(width) ? `${width}px` : width;
|
||||
}
|
||||
|
||||
|
@@ -54,7 +54,7 @@
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgb(240 242 245 / 40%);
|
||||
background-color: #f0f2f566;
|
||||
|
||||
&.absolute {
|
||||
position: absolute;
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { VNode, defineComponent, createVNode, render, reactive, h } from 'vue';
|
||||
import { createVNode, defineComponent, h, reactive, render, VNode } from 'vue';
|
||||
import type { LoadingProps } from './typing';
|
||||
|
||||
import Loading from './Loading.vue';
|
||||
@@ -41,7 +41,7 @@ export function createLoading(props?: Partial<LoadingProps>, target?: HTMLElemen
|
||||
target.appendChild(vm.el as HTMLElement);
|
||||
}
|
||||
|
||||
function destory() {
|
||||
function destroy() {
|
||||
container && render(null, container);
|
||||
container = vm = null;
|
||||
}
|
||||
@@ -53,7 +53,7 @@ export function createLoading(props?: Partial<LoadingProps>, target?: HTMLElemen
|
||||
vm,
|
||||
close,
|
||||
open,
|
||||
destory,
|
||||
destroy,
|
||||
setTip: (tip: string) => {
|
||||
data.tip = tip;
|
||||
},
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { unref } from 'vue';
|
||||
import type { Ref } from 'vue';
|
||||
import { unref } from 'vue';
|
||||
import { tryOnUnmounted } from '@vueuse/core';
|
||||
import { createLoading } from './createLoading';
|
||||
import type { LoadingProps } from './typing';
|
||||
@@ -47,7 +47,7 @@ export function useLoading(
|
||||
};
|
||||
|
||||
tryOnUnmounted(() => {
|
||||
instance.destory();
|
||||
instance.destroy();
|
||||
});
|
||||
|
||||
return [open, close, setTip];
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import type { Options, Props } from './typing';
|
||||
import ImgPreview from './Functional.vue';
|
||||
import { isClient } from '@/utils/is';
|
||||
import { createVNode, render } from 'vue';
|
||||
import ImgPreview from './Functional.vue';
|
||||
import type { Options, Props } from './typing';
|
||||
|
||||
let instance: ReturnType<typeof createVNode> | null = null;
|
||||
export function createImgPreview(options: Options) {
|
||||
@@ -10,8 +10,13 @@ export function createImgPreview(options: Options) {
|
||||
const container = document.createElement('div');
|
||||
Object.assign(propsData, { show: true, index: 0, scaleStep: 100 }, options);
|
||||
|
||||
instance = createVNode(ImgPreview, propsData);
|
||||
render(instance, container);
|
||||
document.body.appendChild(container);
|
||||
if (instance?.component) {
|
||||
// 存在实例时,更新props
|
||||
Object.assign(instance.component.props, propsData);
|
||||
} else {
|
||||
instance = createVNode(ImgPreview, propsData);
|
||||
render(instance, container);
|
||||
document.body.appendChild(container);
|
||||
}
|
||||
return instance.component?.exposed;
|
||||
}
|
||||
|
@@ -153,11 +153,11 @@
|
||||
height: 0;
|
||||
transition: 0.3s background-color;
|
||||
border-radius: inherit;
|
||||
background-color: rgb(144 147 153 / 30%);
|
||||
background-color: #9093994d;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: rgb(144 147 153 / 50%);
|
||||
background-color: #90939980;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -17,11 +17,11 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { PropType, ref, computed, unref, getCurrentInstance, watch, useSlots } from 'vue';
|
||||
import { useDesign } from '@/hooks/web/useDesign';
|
||||
import { propTypes } from '@/utils/propTypes';
|
||||
import { useMenuItem } from './useMenu';
|
||||
import { Tooltip } from 'ant-design-vue';
|
||||
import { computed, getCurrentInstance, PropType, ref, unref, useSlots, watch } from 'vue';
|
||||
import { useMenuItem } from './useMenu';
|
||||
import { useSimpleRootMenuContext } from './useSimpleMenuContext';
|
||||
|
||||
defineOptions({ name: 'MenuItem' });
|
||||
@@ -76,7 +76,7 @@
|
||||
const { uidList } = getParentList();
|
||||
|
||||
rootMenuEmitter.emit('on-update-opened', {
|
||||
opend: false,
|
||||
opened: false,
|
||||
parent: instance?.parent,
|
||||
uidList: uidList,
|
||||
});
|
||||
|
@@ -57,27 +57,27 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { type TimeoutHandle, type Recordable } from '@vben/types';
|
||||
import type { CSSProperties, PropType } from 'vue';
|
||||
import type { SubMenuProvider } from './types';
|
||||
import {
|
||||
computed,
|
||||
unref,
|
||||
getCurrentInstance,
|
||||
reactive,
|
||||
provide,
|
||||
onBeforeMount,
|
||||
inject,
|
||||
} from 'vue';
|
||||
import { useDesign } from '@/hooks/web/useDesign';
|
||||
import { propTypes } from '@/utils/propTypes';
|
||||
import { useMenuItem } from './useMenu';
|
||||
import { useSimpleRootMenuContext } from './useSimpleMenuContext';
|
||||
import { CollapseTransition } from '@/components/Transition';
|
||||
import Icon from '@/components/Icon/Icon.vue';
|
||||
import { Popover } from 'ant-design-vue';
|
||||
import { CollapseTransition } from '@/components/Transition';
|
||||
import { useDesign } from '@/hooks/web/useDesign';
|
||||
import { isBoolean, isObject } from '@/utils/is';
|
||||
import { mitt } from '@/utils/mitt';
|
||||
import { propTypes } from '@/utils/propTypes';
|
||||
import { type Recordable, type TimeoutHandle } from '@vben/types';
|
||||
import { Popover } from 'ant-design-vue';
|
||||
import type { CSSProperties, PropType } from 'vue';
|
||||
import {
|
||||
computed,
|
||||
getCurrentInstance,
|
||||
inject,
|
||||
onBeforeMount,
|
||||
provide,
|
||||
reactive,
|
||||
unref,
|
||||
} from 'vue';
|
||||
import type { SubMenuProvider } from './types';
|
||||
import { useMenuItem } from './useMenu';
|
||||
import { useSimpleRootMenuContext } from './useSimpleMenuContext';
|
||||
|
||||
defineOptions({ name: 'SubMenu' });
|
||||
|
||||
@@ -184,7 +184,7 @@
|
||||
if (unref(getAccordion)) {
|
||||
const { uidList } = getParentList();
|
||||
rootMenuEmitter.emit('on-update-opened', {
|
||||
opend: false,
|
||||
opened: false,
|
||||
parent: instance?.parent,
|
||||
uidList: uidList,
|
||||
});
|
||||
@@ -267,9 +267,9 @@
|
||||
return;
|
||||
}
|
||||
if (isObject(data) && rootProps.accordion) {
|
||||
const { opend, parent, uidList } = data as Recordable<any>;
|
||||
const { opened, parent, uidList } = data as Recordable<any>;
|
||||
if (parent === instance?.parent) {
|
||||
state.opened = opend;
|
||||
state.opened = opened;
|
||||
} else if (!uidList.includes(instance?.uid)) {
|
||||
state.opened = false;
|
||||
}
|
||||
|
@@ -1,12 +1,12 @@
|
||||
import type { InjectionKey, Ref, ComponentInternalInstance } from 'vue';
|
||||
import type { Emitter } from '@/utils/mitt';
|
||||
import { createContext, useContext } from '@/hooks/core/useContext';
|
||||
import type { Emitter } from '@/utils/mitt';
|
||||
import type { ComponentInternalInstance, InjectionKey, Ref } from 'vue';
|
||||
|
||||
export type MenuEmitterEvents = {
|
||||
'on-update-opened':
|
||||
| (string | number)[]
|
||||
| {
|
||||
opend: boolean;
|
||||
opened: boolean;
|
||||
parent?: ComponentInternalInstance | null;
|
||||
uidList: number[];
|
||||
};
|
||||
|
@@ -17,6 +17,7 @@
|
||||
import { treeToList } from '@/utils/helper/treeHelper';
|
||||
import { Spin } from 'ant-design-vue';
|
||||
import { parseRowKey } from '../../helper';
|
||||
import { warn } from '@/utils/log';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'EditableCell',
|
||||
@@ -282,6 +283,7 @@
|
||||
});
|
||||
} catch (e) {
|
||||
result = false;
|
||||
warn(e);
|
||||
} finally {
|
||||
spinning.value = false;
|
||||
}
|
||||
|
@@ -540,13 +540,13 @@
|
||||
label:
|
||||
typeof col.title === 'string'
|
||||
? col.title
|
||||
: col.customTitle === 'string'
|
||||
: typeof col.customTitle === 'string'
|
||||
? col.customTitle
|
||||
: '',
|
||||
value:
|
||||
typeof col.dataIndex === 'string'
|
||||
? col.dataIndex
|
||||
: col.title === 'string'
|
||||
: typeof col.title === 'string'
|
||||
? col.title
|
||||
: '',
|
||||
column: {
|
||||
|
@@ -39,7 +39,7 @@
|
||||
redo: true,
|
||||
size: true,
|
||||
setting: true,
|
||||
settingCache: false,
|
||||
settingCache: !import.meta.env.DEV,
|
||||
fullScreen: false,
|
||||
...props.setting,
|
||||
};
|
||||
@@ -55,6 +55,8 @@
|
||||
</script>
|
||||
<style lang="less">
|
||||
.table-settings {
|
||||
display: flex;
|
||||
|
||||
& > * {
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
@@ -146,6 +146,7 @@ export function useDataSource(
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
immediate: true,
|
||||
},
|
||||
);
|
||||
|
||||
|
@@ -33,7 +33,7 @@ export function useRowSelection(
|
||||
// 点击 checkbox/radiobox 触发
|
||||
|
||||
// 取出【当前页】所有 keyValues
|
||||
const currentPageKeys = tableData.value.map((o) => parseRowKeyValue(unref(getRowKey), o));
|
||||
const currentPageKeys = getCcurrentPageKeys();
|
||||
|
||||
// 从【所有分页】已选的 keyValues,且属于【当前页】的部分
|
||||
for (const selectedKey of selectedRowKeysRef.value.filter((k) =>
|
||||
@@ -110,6 +110,18 @@ export function useRowSelection(
|
||||
const { rowKey } = unref(propsRef);
|
||||
return unref(getAutoCreateKey) ? ROW_KEY : rowKey;
|
||||
});
|
||||
function getCcurrentPageKeys() {
|
||||
const { childrenColumnName = 'children' } = unref(propsRef);
|
||||
const keys: Key[] = [];
|
||||
const extractKeys = (record: Recordable) => {
|
||||
keys.push(parseRowKeyValue(unref(getRowKey), record));
|
||||
if (record[childrenColumnName]?.length) {
|
||||
record[childrenColumnName].forEach(extractKeys);
|
||||
}
|
||||
};
|
||||
tableData.value.forEach(extractKeys);
|
||||
return keys;
|
||||
}
|
||||
|
||||
function setSelectedRowKeys(keyValues?: Key[]) {
|
||||
selectedRowKeysRef.value = keyValues || [];
|
||||
|
@@ -59,6 +59,7 @@
|
||||
import UploadPreviewModal from './components/UploadPreviewModal.vue';
|
||||
import { BaseFileItem } from './types/typing';
|
||||
import { buildUUID } from '@/utils/uuid';
|
||||
|
||||
defineOptions({ name: 'BasicUpload' });
|
||||
|
||||
const props = defineProps(uploadContainerProps);
|
||||
@@ -85,7 +86,10 @@
|
||||
const value = { ...attrs, ...props };
|
||||
return omit(value, 'onChange');
|
||||
});
|
||||
function getValue(valueKey="url") {
|
||||
|
||||
const isFirstRender = ref<boolean>(true);
|
||||
|
||||
function getValue(valueKey = 'url') {
|
||||
const list = (fileList.value || []).map((item: any) => {
|
||||
return item[valueKey];
|
||||
});
|
||||
@@ -110,7 +114,7 @@
|
||||
} else if (typeof v == 'string') {
|
||||
values.push(v);
|
||||
}
|
||||
fileList.value = values.map((item,i) => {
|
||||
fileList.value = values.map((item) => {
|
||||
if (item && isString(item)) {
|
||||
return {
|
||||
uid: buildUUID(),
|
||||
@@ -124,13 +128,19 @@
|
||||
}) as any;
|
||||
}
|
||||
emit('update:value', values);
|
||||
emit('change', values);
|
||||
if (!isFirstRender.value) {
|
||||
emit('change', values);
|
||||
isFirstRender.value = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
// 上传modal保存操作
|
||||
function handleChange(urls: string[],valueKey:string) {
|
||||
function handleChange(urls: string[], valueKey: string) {
|
||||
fileList.value = [...unref(fileList), ...(genFileListByUrls(urls) || [])];
|
||||
const values = getValue(valueKey);
|
||||
emit('update:value', values);
|
||||
@@ -138,7 +148,7 @@
|
||||
}
|
||||
|
||||
// 预览modal保存操作
|
||||
function handlePreviewChange(fileItems: string[],valueKey:string) {
|
||||
function handlePreviewChange(fileItems: string[], valueKey: string) {
|
||||
fileList.value = [...(fileItems || [])];
|
||||
const values = getValue(valueKey);
|
||||
emit('update:value', values);
|
||||
|
@@ -63,6 +63,7 @@
|
||||
const fileList = ref<UploadProps['fileList']>([]);
|
||||
const isLtMsg = ref<boolean>(true);
|
||||
const isActMsg = ref<boolean>(true);
|
||||
const isFirstRender = ref<boolean>(true);
|
||||
|
||||
watch(
|
||||
() => props.value,
|
||||
@@ -94,7 +95,10 @@
|
||||
}) as UploadProps['fileList'];
|
||||
}
|
||||
emit('update:value', value);
|
||||
emit('change', value);
|
||||
if (!isFirstRender.value) {
|
||||
emit('change', value);
|
||||
isFirstRender.value = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
|
@@ -57,7 +57,7 @@
|
||||
import { useMessage } from '@/hooks/web/useMessage';
|
||||
// types
|
||||
import { FileItem, UploadResultStatus } from '../types/typing';
|
||||
import { basicProps } from '../props';
|
||||
import { handleFnKey, basicProps } from '../props';
|
||||
import { createTableColumns, createActionColumn } from './data';
|
||||
// utils
|
||||
import { checkImgType, getBase64WithFile } from '../helper';
|
||||
@@ -161,13 +161,13 @@
|
||||
}
|
||||
|
||||
// 删除
|
||||
function handleRemove(record: FileItem) {
|
||||
const index = fileListRef.value.findIndex((item) => item.uuid === record.uuid);
|
||||
index !== -1 && fileListRef.value.splice(index, 1);
|
||||
isUploadingRef.value = fileListRef.value.some(
|
||||
(item) => item.status === UploadResultStatus.UPLOADING,
|
||||
);
|
||||
emit('delete', record);
|
||||
function handleRemove(obj: Record<handleFnKey, any>) {
|
||||
let { record = {}, uidKey = 'uid' } = obj;
|
||||
const index = fileListRef.value.findIndex((item) => item[uidKey] === record[uidKey]);
|
||||
if (index !== -1) {
|
||||
const removed = fileListRef.value.splice(index, 1);
|
||||
emit('delete', removed[0][uidKey]);
|
||||
}
|
||||
}
|
||||
|
||||
async function uploadApiByItem(item: FileItem) {
|
||||
|
@@ -23,6 +23,7 @@
|
||||
import { BasicColumn } from '@/components/Table';
|
||||
import { useMessage } from '@/hooks/web/useMessage';
|
||||
import { buildUUID } from '@/utils/uuid';
|
||||
|
||||
const { createMessage } = useMessage();
|
||||
|
||||
const props = defineProps(previewProps);
|
||||
@@ -97,7 +98,6 @@
|
||||
return createMessage.warning(t('component.upload.maxNumber', [maxNumber]));
|
||||
}
|
||||
record[uidKey] = record[uidKey] ?? buildUUID();
|
||||
record[valueKey] = record[valueKey];
|
||||
fileListRef.value = [...fileListRef.value, record];
|
||||
emit('list-change', fileListRef.value, valueKey);
|
||||
}
|
||||
|
@@ -14,7 +14,7 @@ type SortableOptions = Merge<
|
||||
// ...可扩展
|
||||
}
|
||||
>;
|
||||
export type handleFnKey = "record" | "valueKey" | "uidKey"
|
||||
export type handleFnKey = 'record' | 'valueKey' | 'uidKey';
|
||||
export type previewColumnsFnType = {
|
||||
handleRemove: (record: Record<handleFnKey, any>) => any;
|
||||
handleAdd: (record: Record<handleFnKey, any>) => any;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { withInstall } from '@/utils';
|
||||
import vxeBasicTable from './src/VxeBasicTable';
|
||||
import { VXETable } from 'vxe-table';
|
||||
import { VxeUI } from 'vxe-table';
|
||||
import VXETablePluginAntd from './src/components';
|
||||
import VXETablePluginExportXLSX from 'vxe-table-plugin-export-xlsx';
|
||||
import ExcelJS from 'exceljs';
|
||||
@@ -10,4 +10,4 @@ export const VxeBasicTable = withInstall(vxeBasicTable);
|
||||
export * from 'vxe-table';
|
||||
export * from './src/types';
|
||||
|
||||
VXETable.use(VXETablePluginAntd).use(VXETablePluginExportXLSX, { ExcelJS });
|
||||
VxeUI.use(VXETablePluginAntd).use(VXETablePluginExportXLSX, { ExcelJS });
|
||||
|
@@ -1,22 +1,25 @@
|
||||
import { defineComponent, computed, ref } from 'vue';
|
||||
import { defineComponent, computed, ref, watch } from 'vue';
|
||||
import { BasicTableProps } from './types';
|
||||
import { basicProps } from './props';
|
||||
import { ignorePropKeys } from './const';
|
||||
import { basicEmits } from './emits';
|
||||
import XEUtils from 'xe-utils';
|
||||
import type {
|
||||
import {
|
||||
VxeGridInstance,
|
||||
VxeGridEventProps,
|
||||
GridMethods,
|
||||
TableMethods,
|
||||
TableEditMethods,
|
||||
TableValidatorMethods,
|
||||
VxeUI,
|
||||
VxeGlobalThemeName,
|
||||
VxeGrid,
|
||||
} from 'vxe-table';
|
||||
import { Grid as VxeGrid } from 'vxe-table';
|
||||
|
||||
import { extendSlots } from '@/utils/helper/tsxHelper';
|
||||
import { gridComponentMethodKeys } from './methods';
|
||||
import { omit } from 'lodash-es';
|
||||
import { useRootSetting } from '@/hooks/setting/useRootSetting';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'VxeBasicTable',
|
||||
@@ -25,7 +28,14 @@ export default defineComponent({
|
||||
setup(props, { emit, attrs }) {
|
||||
const tableElRef = ref<VxeGridInstance>();
|
||||
const emitEvents: VxeGridEventProps = {};
|
||||
|
||||
const { getDarkMode } = useRootSetting();
|
||||
watch(
|
||||
() => getDarkMode.value,
|
||||
() => {
|
||||
VxeUI.setTheme(getDarkMode.value as VxeGlobalThemeName);
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
const extendTableMethods = (methodKeys) => {
|
||||
const funcs: any = {};
|
||||
methodKeys.forEach((name) => {
|
||||
|
@@ -1,20 +1,21 @@
|
||||
import XEUtils from 'xe-utils';
|
||||
import { createDefaultRender, createEditRender, createFormItemRender } from './common';
|
||||
import { VxeGlobalRendererOptions } from 'vxe-table';
|
||||
|
||||
export default {
|
||||
renderDefault: createDefaultRender({}, (_, params) => {
|
||||
renderTableDefault: createDefaultRender({}, (_, params) => {
|
||||
return {
|
||||
params: XEUtils.get(params, 'row'),
|
||||
};
|
||||
}),
|
||||
renderEdit: createEditRender({}, (_, params) => {
|
||||
renderTableEdit: createEditRender({}, (_, params) => {
|
||||
return {
|
||||
params: XEUtils.get(params, 'row'),
|
||||
};
|
||||
}),
|
||||
renderItemContent: createFormItemRender({}, (_, params) => {
|
||||
renderFormItemContent: createFormItemRender({}, (_, params) => {
|
||||
return {
|
||||
params: XEUtils.get(params, 'row'),
|
||||
};
|
||||
}),
|
||||
};
|
||||
} as VxeGlobalRendererOptions;
|
||||
|
@@ -1,20 +1,21 @@
|
||||
import XEUtils from 'xe-utils';
|
||||
import { createDefaultRender, createEditRender, createFormItemRender } from './common';
|
||||
import { VxeGlobalRendererOptions } from 'vxe-table';
|
||||
|
||||
export default {
|
||||
renderDefault: createDefaultRender({}, (_, params) => {
|
||||
renderTableDefault: createDefaultRender({}, (_, params) => {
|
||||
return {
|
||||
params: XEUtils.get(params, 'row'),
|
||||
};
|
||||
}),
|
||||
renderEdit: createEditRender({}, (_, params) => {
|
||||
renderTableEdit: createEditRender({}, (_, params) => {
|
||||
return {
|
||||
params: XEUtils.get(params, 'row'),
|
||||
};
|
||||
}),
|
||||
renderItemContent: createFormItemRender({}, (_, params) => {
|
||||
renderFormItemContent: createFormItemRender({}, (_, params) => {
|
||||
return {
|
||||
params: XEUtils.get(params, 'row'),
|
||||
};
|
||||
}),
|
||||
};
|
||||
} as VxeGlobalRendererOptions;
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import { VxeGlobalRendererOptions } from 'vxe-table';
|
||||
import {
|
||||
createEditRender,
|
||||
createDefaultRender,
|
||||
@@ -7,10 +8,10 @@ import {
|
||||
} from './common';
|
||||
|
||||
export default {
|
||||
autofocus: 'input.ant-input',
|
||||
renderDefault: createDefaultRender(),
|
||||
renderEdit: createEditRender(),
|
||||
renderFilter: createFilterRender(),
|
||||
defaultFilterMethod: createDefaultFilterRender(),
|
||||
renderItemContent: createFormItemRender(),
|
||||
};
|
||||
tableAutoFocus: 'input.ant-input',
|
||||
renderTableDefault: createDefaultRender(),
|
||||
renderTableEdit: createEditRender(),
|
||||
renderTableFilter: createFilterRender(),
|
||||
tableFilterDefaultMethod: createDefaultFilterRender(),
|
||||
renderFormItemContent: createFormItemRender(),
|
||||
} as VxeGlobalRendererOptions;
|
||||
|
@@ -1,8 +1,9 @@
|
||||
import { h } from 'vue';
|
||||
import {
|
||||
FormItemContentRenderParams,
|
||||
FormItemRenderOptions,
|
||||
VxeFormItemPropTypes,
|
||||
VxeGlobalRendererHandles,
|
||||
VxeGlobalRendererOptions,
|
||||
} from 'vxe-table';
|
||||
import XEUtils from 'xe-utils';
|
||||
import { cellText, createEvents, createProps, getComponent } from './common';
|
||||
@@ -11,8 +12,8 @@ const COMPONENT_NAME = 'AButton';
|
||||
|
||||
export function createEditRender() {
|
||||
return function (
|
||||
renderOpts: VxeGlobalRendererHandles.RenderEditOptions,
|
||||
params: VxeGlobalRendererHandles.RenderEditParams,
|
||||
renderOpts: VxeGlobalRendererHandles.RenderTableEditOptions,
|
||||
params: VxeGlobalRendererHandles.RenderTableEditParams,
|
||||
) {
|
||||
const { attrs } = renderOpts;
|
||||
const Component = getComponent(COMPONENT_NAME);
|
||||
@@ -29,8 +30,8 @@ export function createEditRender() {
|
||||
|
||||
export function createDefaultRender() {
|
||||
return function (
|
||||
renderOpts: VxeGlobalRendererHandles.RenderEditOptions,
|
||||
params: VxeGlobalRendererHandles.RenderEditParams,
|
||||
renderOpts: VxeGlobalRendererHandles.RenderTableEditOptions,
|
||||
params: VxeGlobalRendererHandles.RenderTableEditParams,
|
||||
) {
|
||||
const { attrs } = renderOpts;
|
||||
const Component = getComponent(COMPONENT_NAME);
|
||||
@@ -50,7 +51,10 @@ export function createDefaultRender() {
|
||||
}
|
||||
|
||||
export function createFormItemRender() {
|
||||
return function (renderOpts: FormItemRenderOptions, params: FormItemContentRenderParams) {
|
||||
return function (
|
||||
renderOpts: VxeFormItemPropTypes.ItemRender,
|
||||
params: FormItemContentRenderParams,
|
||||
) {
|
||||
const { attrs, content } = renderOpts;
|
||||
const { property, $form, data } = params;
|
||||
const props = createProps(renderOpts, null);
|
||||
@@ -113,8 +117,8 @@ function createToolbarButtonRender() {
|
||||
}
|
||||
|
||||
export default {
|
||||
renderEdit: createEditRender(),
|
||||
renderDefault: createDefaultRender(),
|
||||
renderItemContent: createFormItemRender(),
|
||||
renderTableEdit: createEditRender(),
|
||||
renderTableDefault: createDefaultRender(),
|
||||
renderFormItemContent: createFormItemRender(),
|
||||
renderToolbarButton: createToolbarButtonRender(),
|
||||
};
|
||||
} as VxeGlobalRendererOptions;
|
||||
|
@@ -1,20 +1,21 @@
|
||||
import {
|
||||
FormItemContentRenderParams,
|
||||
FormItemRenderOptions,
|
||||
VxeFormItemPropTypes,
|
||||
VxeGlobalRendererHandles,
|
||||
VxeGlobalRendererOptions,
|
||||
} from 'vxe-table';
|
||||
import { createDefaultRender, createEditRender, createFormItemRender } from './AButton';
|
||||
|
||||
function createEditButtonRender() {
|
||||
return function (
|
||||
renderOpts: VxeGlobalRendererHandles.RenderEditOptions,
|
||||
params: VxeGlobalRendererHandles.RenderEditParams,
|
||||
renderOpts: VxeGlobalRendererHandles.RenderTableEditOptions,
|
||||
params: VxeGlobalRendererHandles.RenderTableEditParams,
|
||||
) {
|
||||
const buttonEditRender = createEditRender();
|
||||
const { children } = renderOpts;
|
||||
if (children) {
|
||||
return children.map(
|
||||
(childRenderOpts: VxeGlobalRendererHandles.RenderEditOptions) =>
|
||||
(childRenderOpts: VxeGlobalRendererHandles.RenderTableEditOptions) =>
|
||||
buttonEditRender(childRenderOpts, params)[0],
|
||||
);
|
||||
}
|
||||
@@ -25,7 +26,7 @@ function createEditButtonRender() {
|
||||
function createDefaultButtonRender() {
|
||||
return function (
|
||||
renderOpts: VxeGlobalRendererHandles.RenderDefaultOptions,
|
||||
params: VxeGlobalRendererHandles.RenderDefaultParams,
|
||||
params: VxeGlobalRendererHandles.RenderTableDefaultParams,
|
||||
) {
|
||||
const buttonDefaultRender = createDefaultRender();
|
||||
const { children } = renderOpts;
|
||||
@@ -40,12 +41,16 @@ function createDefaultButtonRender() {
|
||||
}
|
||||
|
||||
function createButtonItemRender() {
|
||||
return function (renderOpts: FormItemRenderOptions, params: FormItemContentRenderParams) {
|
||||
return function (
|
||||
renderOpts: VxeFormItemPropTypes.ItemRender,
|
||||
params: FormItemContentRenderParams,
|
||||
) {
|
||||
const buttonItemRender = createFormItemRender();
|
||||
const { children } = renderOpts;
|
||||
if (children) {
|
||||
return children.map(
|
||||
(childRenderOpts: FormItemRenderOptions) => buttonItemRender(childRenderOpts, params)[0],
|
||||
(childRenderOpts: VxeFormItemPropTypes.ItemRender) =>
|
||||
buttonItemRender(childRenderOpts, params)[0],
|
||||
);
|
||||
}
|
||||
return [];
|
||||
@@ -53,7 +58,7 @@ function createButtonItemRender() {
|
||||
}
|
||||
|
||||
export default {
|
||||
renderEdit: createEditButtonRender(),
|
||||
renderDefault: createDefaultButtonRender(),
|
||||
renderItemContent: createButtonItemRender(),
|
||||
};
|
||||
renderTableEdit: createEditButtonRender(),
|
||||
renderTableDefault: createDefaultButtonRender(),
|
||||
renderFormItemContent: createButtonItemRender(),
|
||||
} as VxeGlobalRendererOptions;
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { VxeGlobalRendererHandles } from 'vxe-table';
|
||||
import { VxeGlobalRendererHandles, VxeGlobalRendererOptions } from 'vxe-table';
|
||||
import XEUtils from 'xe-utils';
|
||||
import {
|
||||
createEditRender,
|
||||
@@ -21,7 +21,7 @@ function matchCascaderData(index: number, list: any[], values: any[], labels: an
|
||||
|
||||
function getCascaderCellValue(
|
||||
renderOpts: VxeGlobalRendererHandles.RenderOptions,
|
||||
params: VxeGlobalRendererHandles.RenderCellParams,
|
||||
params: VxeGlobalRendererHandles.RenderTableCellParams,
|
||||
) {
|
||||
const { props = {} } = renderOpts;
|
||||
const { row, column } = params;
|
||||
@@ -35,8 +35,8 @@ function getCascaderCellValue(
|
||||
}
|
||||
|
||||
export default {
|
||||
renderEdit: createEditRender(),
|
||||
renderCell: createCellRender(getCascaderCellValue),
|
||||
renderItemContent: createFormItemRender(),
|
||||
exportMethod: createExportMethod(getCascaderCellValue),
|
||||
};
|
||||
renderTableEdit: createEditRender(),
|
||||
renderTableCell: createCellRender(getCascaderCellValue),
|
||||
renderFormItemContent: createFormItemRender(),
|
||||
tableExportMethod: createExportMethod(getCascaderCellValue),
|
||||
} as VxeGlobalRendererOptions;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
import { VxeGlobalRendererOptions } from 'vxe-table';
|
||||
import { createFormItemRender } from './common';
|
||||
|
||||
export default {
|
||||
renderItemContent: createFormItemRender(),
|
||||
};
|
||||
renderFormItemContent: createFormItemRender(),
|
||||
} as VxeGlobalRendererOptions;
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { VxeGlobalRendererHandles } from 'vxe-table';
|
||||
import { VxeGlobalRendererHandles, VxeGlobalRendererOptions } from 'vxe-table';
|
||||
import XEUtils from 'xe-utils';
|
||||
import {
|
||||
createCellRender,
|
||||
@@ -9,7 +9,9 @@ import {
|
||||
|
||||
export function getDatePickerCellValue(
|
||||
renderOpts: VxeGlobalRendererHandles.RenderOptions,
|
||||
params: VxeGlobalRendererHandles.RenderCellParams | VxeGlobalRendererHandles.ExportMethodParams,
|
||||
params:
|
||||
| VxeGlobalRendererHandles.RenderTableCellParams
|
||||
| VxeGlobalRendererHandles.ExportMethodParams,
|
||||
defaultFormat: string,
|
||||
) {
|
||||
const { props = {} } = renderOpts;
|
||||
@@ -22,12 +24,12 @@ export function getDatePickerCellValue(
|
||||
}
|
||||
|
||||
export default {
|
||||
renderEdit: createEditRender(),
|
||||
renderCell: createCellRender(getDatePickerCellValue, () => {
|
||||
renderTableEdit: createEditRender(),
|
||||
renderTableCell: createCellRender(getDatePickerCellValue, () => {
|
||||
return ['YYYY-MM-DD'];
|
||||
}),
|
||||
renderItemContent: createFormItemRender(),
|
||||
exportMethod: createExportMethod(getDatePickerCellValue, () => {
|
||||
renderFormItemContent: createFormItemRender(),
|
||||
tableExportMethod: createExportMethod(getDatePickerCellValue, () => {
|
||||
return ['YYYY-MM-DD'];
|
||||
}),
|
||||
};
|
||||
} as VxeGlobalRendererOptions;
|
||||
|
@@ -1,9 +1,9 @@
|
||||
import { h } from 'vue';
|
||||
import { VxeGlobalRendererHandles } from 'vxe-table';
|
||||
import { VxeGlobalRendererHandles, VxeGlobalRendererOptions } from 'vxe-table';
|
||||
import { getComponent } from './common';
|
||||
|
||||
function createEmptyRender() {
|
||||
return function (renderOpts: VxeGlobalRendererHandles.RenderEmptyOptions) {
|
||||
return function (renderOpts: VxeGlobalRendererHandles.RenderTableEmptyOptions) {
|
||||
const { name, attrs, props } = renderOpts;
|
||||
|
||||
const Component = getComponent(name);
|
||||
@@ -23,5 +23,5 @@ function createEmptyRender() {
|
||||
}
|
||||
|
||||
export default {
|
||||
renderEmpty: createEmptyRender(),
|
||||
};
|
||||
renderTableEmptyView: createEmptyRender(),
|
||||
} as VxeGlobalRendererOptions;
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import { VxeGlobalRendererOptions } from 'vxe-table';
|
||||
import {
|
||||
createEditRender,
|
||||
createDefaultRender,
|
||||
@@ -7,10 +8,10 @@ import {
|
||||
} from './common';
|
||||
|
||||
export default {
|
||||
autofocus: 'input.ant-input',
|
||||
renderDefault: createDefaultRender(),
|
||||
renderEdit: createEditRender(),
|
||||
renderFilter: createFilterRender(),
|
||||
defaultFilterMethod: createDefaultFilterRender(),
|
||||
renderItemContent: createFormItemRender(),
|
||||
};
|
||||
tableAutoFocus: 'input.ant-input',
|
||||
renderTableDefault: createDefaultRender(),
|
||||
renderTableEdit: createEditRender(),
|
||||
renderTableFilter: createFilterRender(),
|
||||
tableFilterDefaultMethod: createDefaultFilterRender(),
|
||||
renderFormItemContent: createFormItemRender(),
|
||||
} as VxeGlobalRendererOptions;
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import { VxeGlobalRendererOptions } from 'vxe-table';
|
||||
import {
|
||||
createEditRender,
|
||||
createFilterRender,
|
||||
@@ -7,10 +8,10 @@ import {
|
||||
} from './common';
|
||||
|
||||
export default {
|
||||
autofocus: 'input.ant-input-number-input',
|
||||
renderDefault: createDefaultRender(),
|
||||
renderEdit: createEditRender(),
|
||||
renderFilter: createFilterRender(),
|
||||
defaultFilterMethod: createDefaultFilterRender(),
|
||||
renderItemContent: createFormItemRender(),
|
||||
};
|
||||
tableAutoFocus: 'input.ant-input-number-input',
|
||||
renderTableDefault: createDefaultRender(),
|
||||
renderTableEdit: createEditRender(),
|
||||
renderTableFilter: createFilterRender(),
|
||||
tableFilterDefaultMethod: createDefaultFilterRender(),
|
||||
renderFormItemContent: createFormItemRender(),
|
||||
} as VxeGlobalRendererOptions;
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import { VxeGlobalRendererOptions } from 'vxe-table';
|
||||
import {
|
||||
createEditRender,
|
||||
createDefaultRender,
|
||||
@@ -8,10 +9,10 @@ import {
|
||||
} from './common';
|
||||
|
||||
export default {
|
||||
renderDefault: createDefaultRender(),
|
||||
renderEdit: createEditRender(),
|
||||
renderFilter: createFilterRender(),
|
||||
defaultFilterMethod: createDefaultFilterRender(),
|
||||
renderItemContent: createFormItemRender(),
|
||||
renderTableDefault: createDefaultRender(),
|
||||
renderTableEdit: createEditRender(),
|
||||
renderTableFilter: createFilterRender(),
|
||||
tableFilterDefaultMethod: createDefaultFilterRender(),
|
||||
renderFormItemContent: createFormItemRender(),
|
||||
renderToolbarTool: createToolbarToolRender(),
|
||||
};
|
||||
} as VxeGlobalRendererOptions;
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import { VxeGlobalRendererOptions } from 'vxe-table';
|
||||
import { getDatePickerCellValue } from './ADatePicker';
|
||||
import {
|
||||
createCellRender,
|
||||
@@ -7,12 +8,12 @@ import {
|
||||
} from './common';
|
||||
|
||||
export default {
|
||||
renderEdit: createEditRender(),
|
||||
renderCell: createCellRender(getDatePickerCellValue, () => {
|
||||
renderTableEdit: createEditRender(),
|
||||
renderTableCell: createCellRender(getDatePickerCellValue, () => {
|
||||
return ['YYYY-MM'];
|
||||
}),
|
||||
renderItemContent: createFormItemRender(),
|
||||
exportMethod: createExportMethod(getDatePickerCellValue, () => {
|
||||
renderFormItemContent: createFormItemRender(),
|
||||
tableExportMethod: createExportMethod(getDatePickerCellValue, () => {
|
||||
return ['YYYY-MM'];
|
||||
}),
|
||||
};
|
||||
} as VxeGlobalRendererOptions;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
import { VxeGlobalRendererOptions } from 'vxe-table';
|
||||
import { createFormItemRender } from './common';
|
||||
|
||||
export default {
|
||||
renderItemContent: createFormItemRender(),
|
||||
};
|
||||
renderFormItemContent: createFormItemRender(),
|
||||
} as VxeGlobalRendererOptions;
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { VxeColumnPropTypes, VxeGlobalRendererHandles } from 'vxe-table';
|
||||
import { VxeColumnPropTypes, VxeGlobalRendererHandles, VxeGlobalRendererOptions } from 'vxe-table';
|
||||
import XEUtils from 'xe-utils';
|
||||
import {
|
||||
createCellRender,
|
||||
@@ -9,7 +9,9 @@ import {
|
||||
|
||||
function getRangePickerCellValue(
|
||||
renderOpts: VxeColumnPropTypes.EditRender,
|
||||
params: VxeGlobalRendererHandles.RenderCellParams | VxeGlobalRendererHandles.ExportMethodParams,
|
||||
params:
|
||||
| VxeGlobalRendererHandles.RenderTableCellParams
|
||||
| VxeGlobalRendererHandles.ExportMethodParams,
|
||||
) {
|
||||
const { props = {} } = renderOpts;
|
||||
const { row, column } = params;
|
||||
@@ -23,8 +25,8 @@ function getRangePickerCellValue(
|
||||
}
|
||||
|
||||
export default {
|
||||
renderEdit: createEditRender(),
|
||||
renderCell: createCellRender(getRangePickerCellValue),
|
||||
renderItemContent: createFormItemRender(),
|
||||
exportMethod: createExportMethod(getRangePickerCellValue),
|
||||
};
|
||||
renderTableEdit: createEditRender(),
|
||||
renderTableCell: createCellRender(getRangePickerCellValue),
|
||||
renderFormItemContent: createFormItemRender(),
|
||||
tableExportMethod: createExportMethod(getRangePickerCellValue),
|
||||
} as VxeGlobalRendererOptions;
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import { VxeGlobalRendererOptions } from 'vxe-table';
|
||||
import {
|
||||
createEditRender,
|
||||
createDefaultRender,
|
||||
@@ -7,9 +8,9 @@ import {
|
||||
} from './common';
|
||||
|
||||
export default {
|
||||
renderDefault: createDefaultRender(),
|
||||
renderEdit: createEditRender(),
|
||||
renderFilter: createFilterRender(),
|
||||
defaultFilterMethod: createDefaultFilterRender(),
|
||||
renderItemContent: createFormItemRender(),
|
||||
};
|
||||
renderTableDefault: createDefaultRender(),
|
||||
renderTableEdit: createEditRender(),
|
||||
renderTableFilter: createFilterRender(),
|
||||
tableFilterDefaultMethod: createDefaultFilterRender(),
|
||||
renderFormItemContent: createFormItemRender(),
|
||||
} as VxeGlobalRendererOptions;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { ComponentOptions, h, resolveComponent } from 'vue';
|
||||
import { VxeColumnPropTypes, VxeGlobalRendererHandles } from 'vxe-table';
|
||||
import { VxeColumnPropTypes, VxeGlobalRendererHandles, VxeGlobalRendererOptions } from 'vxe-table';
|
||||
import XEUtils from 'xe-utils';
|
||||
import {
|
||||
cellText,
|
||||
@@ -32,7 +32,7 @@ function renderOptions(options: any[], optionProps: VxeGlobalRendererHandles.Ren
|
||||
function createEditRender() {
|
||||
return function (
|
||||
renderOpts: VxeColumnPropTypes.EditRender,
|
||||
params: VxeGlobalRendererHandles.RenderEditParams,
|
||||
params: VxeGlobalRendererHandles.RenderTableEditParams,
|
||||
) {
|
||||
const { options = [], optionGroups, optionProps = {}, optionGroupProps = {} } = renderOpts;
|
||||
const { row, column, $table } = params;
|
||||
@@ -100,8 +100,8 @@ function createEditRender() {
|
||||
}
|
||||
|
||||
function getSelectCellValue(
|
||||
renderOpts: VxeGlobalRendererHandles.RenderCellOptions,
|
||||
params: VxeGlobalRendererHandles.RenderCellParams,
|
||||
renderOpts: VxeGlobalRendererHandles.RenderTableCellOptions,
|
||||
params: VxeGlobalRendererHandles.RenderTableCellParams,
|
||||
) {
|
||||
const {
|
||||
options = [],
|
||||
@@ -144,7 +144,7 @@ function getSelectCellValue(
|
||||
function createFilterRender() {
|
||||
return function (
|
||||
renderOpts: VxeColumnPropTypes.FilterRender,
|
||||
params: VxeGlobalRendererHandles.RenderFilterParams,
|
||||
params: VxeGlobalRendererHandles.RenderTableFilterParams,
|
||||
) {
|
||||
const { options = [], optionGroups, optionProps = {}, optionGroupProps = {} } = renderOpts;
|
||||
const groupOptions = optionGroupProps.options || 'options';
|
||||
@@ -249,10 +249,10 @@ function createFilterRender() {
|
||||
}
|
||||
|
||||
export default {
|
||||
renderEdit: createEditRender(),
|
||||
renderCell: createCellRender(getSelectCellValue),
|
||||
renderFilter: createFilterRender(),
|
||||
defaultFilterMethod(params) {
|
||||
renderTableEdit: createEditRender(),
|
||||
renderTableCell: createCellRender(getSelectCellValue),
|
||||
renderTableFilter: createFilterRender(),
|
||||
tableFilterDefaultMethod(params) {
|
||||
const { option, row, column } = params;
|
||||
const { data } = option;
|
||||
const { field, filterRender: renderOpts } = column;
|
||||
@@ -266,6 +266,6 @@ export default {
|
||||
}
|
||||
return cellValue == data;
|
||||
},
|
||||
renderItemContent: createFormItemRender(),
|
||||
exportMethod: createExportMethod(getSelectCellValue),
|
||||
};
|
||||
renderFormItemContent: createFormItemRender(),
|
||||
tableExportMethod: createExportMethod(getSelectCellValue),
|
||||
} as VxeGlobalRendererOptions;
|
||||
|
@@ -9,11 +9,12 @@ import {
|
||||
createFormItemRender,
|
||||
getComponent,
|
||||
} from './common';
|
||||
import { VxeGlobalRendererOptions } from 'vxe-table';
|
||||
|
||||
export default {
|
||||
renderDefault: createDefaultRender(),
|
||||
renderEdit: createEditRender(),
|
||||
renderFilter(renderOpts, params) {
|
||||
renderTableDefault: createDefaultRender(),
|
||||
renderTableEdit: createEditRender(),
|
||||
renderTableFilter(renderOpts, params) {
|
||||
const { column } = params;
|
||||
const { name, attrs } = renderOpts;
|
||||
const Component = getComponent(name);
|
||||
@@ -48,6 +49,6 @@ export default {
|
||||
),
|
||||
];
|
||||
},
|
||||
defaultFilterMethod: createDefaultFilterRender(),
|
||||
renderItemContent: createFormItemRender(),
|
||||
};
|
||||
tableFilterDefaultMethod: createDefaultFilterRender(),
|
||||
renderFormItemContent: createFormItemRender(),
|
||||
} as VxeGlobalRendererOptions;
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import { VxeGlobalRendererOptions } from 'vxe-table';
|
||||
import { getDatePickerCellValue } from './ADatePicker';
|
||||
import {
|
||||
createEditRender,
|
||||
@@ -7,12 +8,12 @@ import {
|
||||
} from './common';
|
||||
|
||||
export default {
|
||||
renderEdit: createEditRender(),
|
||||
renderCell: createCellRender(getDatePickerCellValue, () => {
|
||||
renderTableEdit: createEditRender(),
|
||||
renderTableCell: createCellRender(getDatePickerCellValue, () => {
|
||||
return ['HH:mm:ss'];
|
||||
}),
|
||||
renderItemContent: createFormItemRender(),
|
||||
exportMethod: createExportMethod(getDatePickerCellValue, () => {
|
||||
renderFormItemContent: createFormItemRender(),
|
||||
tableExportMethod: createExportMethod(getDatePickerCellValue, () => {
|
||||
return ['HH:mm:ss'];
|
||||
}),
|
||||
};
|
||||
} as VxeGlobalRendererOptions;
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { VxeGlobalRendererHandles } from 'vxe-table';
|
||||
import { VxeGlobalRendererHandles, VxeGlobalRendererOptions } from 'vxe-table';
|
||||
import XEUtils from 'xe-utils';
|
||||
import {
|
||||
createEditRender,
|
||||
@@ -10,7 +10,9 @@ import {
|
||||
|
||||
function getTreeSelectCellValue(
|
||||
renderOpts: VxeGlobalRendererHandles.RenderOptions,
|
||||
params: VxeGlobalRendererHandles.RenderCellParams | VxeGlobalRendererHandles.ExportMethodParams,
|
||||
params:
|
||||
| VxeGlobalRendererHandles.RenderTableCellParams
|
||||
| VxeGlobalRendererHandles.ExportMethodParams,
|
||||
) {
|
||||
const { props = {} } = renderOpts;
|
||||
const { treeData, treeCheckable } = props;
|
||||
@@ -28,8 +30,8 @@ function getTreeSelectCellValue(
|
||||
}
|
||||
|
||||
export default {
|
||||
renderEdit: createEditRender(),
|
||||
renderCell: createCellRender(getTreeSelectCellValue),
|
||||
renderItemContent: createFormItemRender(),
|
||||
exportMethod: createExportMethod(getTreeSelectCellValue),
|
||||
};
|
||||
renderTableEdit: createEditRender(),
|
||||
renderTableCell: createCellRender(getTreeSelectCellValue),
|
||||
renderFormItemContent: createFormItemRender(),
|
||||
tableExportMethod: createExportMethod(getTreeSelectCellValue),
|
||||
} as VxeGlobalRendererOptions;
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import { VxeGlobalRendererOptions } from 'vxe-table';
|
||||
import { getDatePickerCellValue } from './ADatePicker';
|
||||
import {
|
||||
createEditRender,
|
||||
@@ -7,12 +8,12 @@ import {
|
||||
} from './common';
|
||||
|
||||
export default {
|
||||
renderEdit: createEditRender(),
|
||||
renderCell: createCellRender(getDatePickerCellValue, () => {
|
||||
renderTableEdit: createEditRender(),
|
||||
renderTableCell: createCellRender(getDatePickerCellValue, () => {
|
||||
return ['YYYY-WW周'];
|
||||
}),
|
||||
renderItemContent: createFormItemRender(),
|
||||
exportMethod: createExportMethod(getDatePickerCellValue, () => {
|
||||
renderFormItemContent: createFormItemRender(),
|
||||
tableExportMethod: createExportMethod(getDatePickerCellValue, () => {
|
||||
return ['YYYY-WW周'];
|
||||
}),
|
||||
};
|
||||
} as VxeGlobalRendererOptions;
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import { VxeGlobalRendererOptions } from 'vxe-table';
|
||||
import { getDatePickerCellValue } from './ADatePicker';
|
||||
import {
|
||||
createEditRender,
|
||||
@@ -7,12 +8,12 @@ import {
|
||||
} from './common';
|
||||
|
||||
export default {
|
||||
renderEdit: createEditRender(),
|
||||
renderCell: createCellRender(getDatePickerCellValue, () => {
|
||||
renderTableEdit: createEditRender(),
|
||||
renderTableCell: createCellRender(getDatePickerCellValue, () => {
|
||||
return ['YYYY'];
|
||||
}),
|
||||
renderItemContent: createFormItemRender(),
|
||||
exportMethod: createExportMethod(getDatePickerCellValue, () => {
|
||||
renderFormItemContent: createFormItemRender(),
|
||||
tableExportMethod: createExportMethod(getDatePickerCellValue, () => {
|
||||
return ['YYYY'];
|
||||
}),
|
||||
};
|
||||
} as VxeGlobalRendererOptions;
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import { ComponentOptions, h } from 'vue';
|
||||
import {
|
||||
FormItemContentRenderParams,
|
||||
FormItemRenderOptions,
|
||||
VxeFormItemPropTypes,
|
||||
VxeGlobalRendererHandles,
|
||||
} from 'vxe-table';
|
||||
import XEUtils from 'xe-utils';
|
||||
@@ -160,12 +160,12 @@ export function createDefaultRender(
|
||||
defaultProps?: { [key: string]: any },
|
||||
callBack?: (
|
||||
renderOpts: VxeGlobalRendererHandles.RenderDefaultOptions,
|
||||
params: VxeGlobalRendererHandles.RenderDefaultParams,
|
||||
params: VxeGlobalRendererHandles.RenderTableDefaultParams,
|
||||
) => Record<string, any>,
|
||||
) {
|
||||
return function (
|
||||
renderOpts: VxeGlobalRendererHandles.RenderDefaultOptions,
|
||||
params: VxeGlobalRendererHandles.RenderDefaultParams,
|
||||
params: VxeGlobalRendererHandles.RenderTableDefaultParams,
|
||||
) {
|
||||
const { row, column, $table } = params;
|
||||
const { name, attrs } = renderOpts;
|
||||
@@ -195,13 +195,13 @@ export function createDefaultRender(
|
||||
export function createEditRender(
|
||||
defaultProps?: { [key: string]: any },
|
||||
callBack?: (
|
||||
renderOpts: VxeGlobalRendererHandles.RenderEditOptions,
|
||||
params: VxeGlobalRendererHandles.RenderEditParams,
|
||||
renderOpts: VxeGlobalRendererHandles.RenderTableEditOptions,
|
||||
params: VxeGlobalRendererHandles.RenderTableEditParams,
|
||||
) => Record<string, any>,
|
||||
) {
|
||||
return function (
|
||||
renderOpts: VxeGlobalRendererHandles.RenderEditOptions,
|
||||
params: VxeGlobalRendererHandles.RenderEditParams,
|
||||
renderOpts: VxeGlobalRendererHandles.RenderTableEditOptions,
|
||||
params: VxeGlobalRendererHandles.RenderTableEditParams,
|
||||
) {
|
||||
const { row, column, $table } = params;
|
||||
const { name, attrs } = renderOpts;
|
||||
@@ -232,12 +232,12 @@ export function createFilterRender(
|
||||
defaultProps?: { [key: string]: any },
|
||||
callBack?: (
|
||||
renderOpts: VxeGlobalRendererHandles.RenderFilterOptions,
|
||||
params: VxeGlobalRendererHandles.RenderFilterParams,
|
||||
params: VxeGlobalRendererHandles.RenderTableFilterParams,
|
||||
) => Record<string, any>,
|
||||
) {
|
||||
return function (
|
||||
renderOpts: VxeGlobalRendererHandles.RenderFilterOptions,
|
||||
params: VxeGlobalRendererHandles.RenderFilterParams,
|
||||
params: VxeGlobalRendererHandles.RenderTableFilterParams,
|
||||
) {
|
||||
const { column } = params;
|
||||
const { name, attrs } = renderOpts;
|
||||
@@ -287,7 +287,7 @@ export function createFilterRender(
|
||||
*/
|
||||
|
||||
export function createDefaultFilterRender() {
|
||||
return function (params: VxeGlobalRendererHandles.FilterMethodParams) {
|
||||
return function (params: VxeGlobalRendererHandles.TableFilterMethodParams) {
|
||||
const { option, row, column } = params;
|
||||
const { data } = option;
|
||||
const cellValue = XEUtils.get(row, column.field as string);
|
||||
@@ -301,11 +301,14 @@ export function createDefaultFilterRender() {
|
||||
export function createFormItemRender(
|
||||
defaultProps?: { [key: string]: any },
|
||||
callBack?: (
|
||||
renderOpts: FormItemRenderOptions,
|
||||
renderOpts: VxeFormItemPropTypes.ItemRender,
|
||||
params: FormItemContentRenderParams,
|
||||
) => Record<string, any>,
|
||||
) {
|
||||
return function (renderOpts: FormItemRenderOptions, params: FormItemContentRenderParams) {
|
||||
return function (
|
||||
renderOpts: VxeFormItemPropTypes.ItemRender,
|
||||
params: FormItemContentRenderParams,
|
||||
) {
|
||||
const args = (callBack && callBack(renderOpts, params)) ?? {};
|
||||
const { data, property, $form } = params;
|
||||
const { name } = renderOpts;
|
||||
@@ -344,13 +347,13 @@ export function createFormItemRender(
|
||||
export function createCellRender(
|
||||
getSelectCellValue: Function,
|
||||
callBack?: (
|
||||
renderOpts: VxeGlobalRendererHandles.RenderCellOptions,
|
||||
params: VxeGlobalRendererHandles.RenderCellParams,
|
||||
renderOpts: VxeGlobalRendererHandles.RenderTableCellOptions,
|
||||
params: VxeGlobalRendererHandles.RenderTableCellParams,
|
||||
) => Array<any>,
|
||||
) {
|
||||
return function (
|
||||
renderOpts: VxeGlobalRendererHandles.RenderCellOptions,
|
||||
params: VxeGlobalRendererHandles.RenderCellParams,
|
||||
renderOpts: VxeGlobalRendererHandles.RenderTableCellOptions,
|
||||
params: VxeGlobalRendererHandles.RenderTableCellParams,
|
||||
) {
|
||||
const args = (callBack && callBack(renderOpts, params)) ?? [];
|
||||
const cellLabel = getSelectCellValue && getSelectCellValue(renderOpts, params, ...args);
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { VXETableCore, VxeGlobalInterceptorHandles } from 'vxe-table';
|
||||
import { VxeUIExport, VxeGlobalInterceptorHandles } from 'vxe-table';
|
||||
import AAutoComplete from './AAutoComplete';
|
||||
import AInput from './AInput';
|
||||
import AInputNumber from './AInputNumber';
|
||||
@@ -50,7 +50,7 @@ function getEventTargetNode(evnt: any, container: HTMLElement, className: string
|
||||
function handleClearEvent(
|
||||
params:
|
||||
| VxeGlobalInterceptorHandles.InterceptorClearFilterParams
|
||||
| VxeGlobalInterceptorHandles.InterceptorClearActivedParams
|
||||
| VxeGlobalInterceptorHandles.InterceptorClearEditParams
|
||||
| VxeGlobalInterceptorHandles.InterceptorClearAreasParams,
|
||||
) {
|
||||
const { $event } = params;
|
||||
@@ -73,10 +73,10 @@ function handleClearEvent(
|
||||
* 基于 vxe-table 表格的适配插件,用于兼容 ant-design-vue 组件库
|
||||
*/
|
||||
export const VXETablePluginAntd = {
|
||||
install(vxetablecore: VXETableCore) {
|
||||
install(vxetablecore: VxeUIExport) {
|
||||
const { interceptor, renderer } = vxetablecore;
|
||||
|
||||
renderer.mixin({
|
||||
const customRenderComponents = {
|
||||
AAutoComplete,
|
||||
AInput,
|
||||
AInputNumber,
|
||||
@@ -99,16 +99,21 @@ export const VXETablePluginAntd = {
|
||||
AEmpty,
|
||||
AInputSearch,
|
||||
AYearPicker,
|
||||
};
|
||||
|
||||
Object.keys(customRenderComponents).forEach((name) => {
|
||||
if (renderer.get(name)) return;
|
||||
renderer.add(name, customRenderComponents[name]);
|
||||
});
|
||||
|
||||
interceptor.add('event.clearFilter', handleClearEvent);
|
||||
interceptor.add('event.clearActived', handleClearEvent);
|
||||
interceptor.add('event.clearEdit', handleClearEvent);
|
||||
interceptor.add('event.clearAreas', handleClearEvent);
|
||||
},
|
||||
};
|
||||
|
||||
if (typeof window !== 'undefined' && window.VXETable && window.VXETable.use) {
|
||||
window.VXETable.use(VXETablePluginAntd);
|
||||
if (typeof window !== 'undefined' && window.VxeUI && window.VxeUI.use) {
|
||||
window.VxeUI.use(VXETablePluginAntd);
|
||||
}
|
||||
|
||||
export default VXETablePluginAntd;
|
||||
|
@@ -2,4 +2,5 @@
|
||||
@import './variable';
|
||||
@import './toolbar';
|
||||
@import './component';
|
||||
@import 'vxe-table/styles/index';
|
||||
@import 'vxe-table/styles/all';
|
||||
@import 'vxe-pc-ui/styles/all';
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { VXETable } from '..';
|
||||
import { VxeUI } from '..';
|
||||
import componentSetting from '@/settings/componentSetting';
|
||||
|
||||
VXETable.setup(componentSetting.vxeTable);
|
||||
VxeUI.setConfig(componentSetting.vxeTable);
|
||||
|
@@ -2,7 +2,8 @@ import type { App } from 'vue';
|
||||
import { Button } from './Button';
|
||||
import { Input, Layout } from 'ant-design-vue';
|
||||
import VXETable from 'vxe-table';
|
||||
import VXEUI from 'vxe-pc-ui';
|
||||
|
||||
export function registerGlobComp(app: App) {
|
||||
app.use(Input).use(Button).use(Layout).use(VXETable);
|
||||
app.use(Input).use(Button).use(Layout).use(VXETable).use(VXEUI);
|
||||
}
|
||||
|
@@ -17,15 +17,15 @@
|
||||
// }
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background-color: rgb(0 0 0 / 5%);
|
||||
background-color: #0000000d;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
// background-color: rgba(144, 147, 153, 0.3);
|
||||
border-radius: 2px;
|
||||
// background: rgba(0, 0, 0, 0.6);
|
||||
background-color: rgb(144 147 153 / 30%);
|
||||
box-shadow: inset 0 0 6px rgb(0 0 0 / 20%);
|
||||
background-color: #9093994d;
|
||||
box-shadow: inset 0 0 6px #00000033;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { createLoading } from '@/components/Loading';
|
||||
import type { Directive, App } from 'vue';
|
||||
import type { App, Directive } from 'vue';
|
||||
|
||||
const loadingDirective: Directive = {
|
||||
mounted(el, binding) {
|
||||
@@ -28,7 +28,7 @@ const loadingDirective: Directive = {
|
||||
}
|
||||
},
|
||||
unmounted(el) {
|
||||
el?.instance?.destory();
|
||||
el?.instance?.destroy();
|
||||
},
|
||||
};
|
||||
|
||||
|
@@ -1,8 +1,8 @@
|
||||
import type { EChartsOption } from 'echarts';
|
||||
import type { Ref } from 'vue';
|
||||
import { computed, nextTick, ref, unref, watch } from 'vue';
|
||||
import { useTimeoutFn } from '@vben/hooks';
|
||||
import { tryOnUnmounted, useDebounceFn } from '@vueuse/core';
|
||||
import { unref, nextTick, watch, computed, ref } from 'vue';
|
||||
import { useEventListener } from '@/hooks/event/useEventListener';
|
||||
import { useBreakpoint } from '@/hooks/event/useBreakpoint';
|
||||
import echarts from '@/utils/lib/echarts';
|
||||
@@ -49,6 +49,10 @@ export function useECharts(
|
||||
listener: resizeFn,
|
||||
});
|
||||
removeResizeFn = removeEvent;
|
||||
|
||||
const resizeObserver = new ResizeObserver(resizeFn);
|
||||
resizeObserver.observe(el);
|
||||
|
||||
const { widthRef, screenEnum } = useBreakpoint();
|
||||
if (unref(widthRef) <= screenEnum.MD || el.offsetHeight === 0) {
|
||||
useTimeoutFn(() => {
|
||||
@@ -64,7 +68,7 @@ export function useECharts(
|
||||
useTimeoutFn(() => {
|
||||
setOptions(unref(getOptions));
|
||||
resolve(null);
|
||||
}, 30);
|
||||
}, 50);
|
||||
}
|
||||
nextTick(() => {
|
||||
useTimeoutFn(() => {
|
||||
|
33
src/layouts/default/header/components/UpgradePrompt.vue
Normal file
33
src/layouts/default/header/components/UpgradePrompt.vue
Normal file
@@ -0,0 +1,33 @@
|
||||
<script setup lang="ts">
|
||||
import { h } from 'vue';
|
||||
import { Modal } from 'ant-design-vue';
|
||||
import { useI18n } from '@/hooks/web/useI18n';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const localKey = 'vben-v5.0.0-upgrade-prompt';
|
||||
|
||||
if (!localStorage.getItem(localKey)) {
|
||||
Modal.confirm({
|
||||
title: t('layout.header.upgrade-prompt.title'),
|
||||
content: h('div', {}, [h('p', t('layout.header.upgrade-prompt.content'))]),
|
||||
onOk() {
|
||||
handleClick();
|
||||
},
|
||||
okText: t('layout.header.upgrade-prompt.ok-text'),
|
||||
cancelText: t('common.closeText'),
|
||||
});
|
||||
}
|
||||
localStorage.setItem(localKey, String(Date.now()));
|
||||
|
||||
function handleClick() {
|
||||
window.open('https://www.vben.pro', '_blank');
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
<a-button type="primary" @click="handleClick">{{
|
||||
t('layout.header.upgrade-prompt.ok-text')
|
||||
}}</a-button>
|
||||
</div>
|
||||
</template>
|
@@ -33,6 +33,8 @@
|
||||
|
||||
<!-- action -->
|
||||
<div :class="`${prefixCls}-action`">
|
||||
<UpgradePrompt class="mr-2" />
|
||||
|
||||
<AppSearch v-if="getShowSearch" :class="`${prefixCls}-action__item `" />
|
||||
|
||||
<ErrorAction v-if="getUseErrorHandle" :class="`${prefixCls}-action__item error-action`" />
|
||||
@@ -70,6 +72,7 @@
|
||||
import { createAsyncComponent } from '@/utils/factory/createAsyncComponent';
|
||||
import { propTypes } from '@/utils/propTypes';
|
||||
|
||||
import UpgradePrompt from './components/UpgradePrompt.vue';
|
||||
import LayoutMenu from '../menu/index.vue';
|
||||
import LayoutTrigger from '../trigger/index.vue';
|
||||
import { ErrorAction, FullScreen, LayoutBreadcrumb, Notify, UserDropDown } from './components';
|
||||
|
@@ -15,7 +15,12 @@
|
||||
"lockScreenPassword": "Lock screen password",
|
||||
"lockScreen": "Lock screen",
|
||||
"lockScreenBtn": "Locking",
|
||||
"home": "Home"
|
||||
"home": "Home",
|
||||
"upgrade-prompt": {
|
||||
"title": "New version released",
|
||||
"content": "Vben Admin v5.0.0 preview version has been released",
|
||||
"ok-text": "Go to new version"
|
||||
}
|
||||
},
|
||||
"multipleTab": {
|
||||
"reload": "Refresh current",
|
||||
|
@@ -177,4 +177,4 @@
|
||||
"resizeParentHeightTable": "resizeParentHeightTable",
|
||||
"vxeTable": "VxeTable"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -15,7 +15,12 @@
|
||||
"lockScreenPassword": "锁屏密码",
|
||||
"lockScreen": "锁定屏幕",
|
||||
"lockScreenBtn": "锁定",
|
||||
"home": "首页"
|
||||
"home": "首页",
|
||||
"upgrade-prompt": {
|
||||
"title": "新版本发布",
|
||||
"content": "Vben Admin v5.0.0 预览版本已发布",
|
||||
"ok-text": "前往体验新版"
|
||||
}
|
||||
},
|
||||
"multipleTab": {
|
||||
"reload": "重新加载",
|
||||
|
@@ -176,4 +176,4 @@
|
||||
"resizeParentHeightTable": "继承父元素高度",
|
||||
"vxeTable": "VxeTable"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -24,7 +24,7 @@ import { Persistent } from '@/utils/cache/persistent';
|
||||
export function initAppConfigStore() {
|
||||
const localeStore = useLocaleStore();
|
||||
const appStore = useAppStore();
|
||||
let projCfg: ProjectConfig = Persistent.getLocal(PROJ_CFG_KEY) as ProjectConfig;
|
||||
let projCfg = Persistent.getLocal<ProjectConfig>(PROJ_CFG_KEY);
|
||||
projCfg = deepMerge(projectSetting, projCfg || {});
|
||||
const darkMode = appStore.getDarkMode;
|
||||
const {
|
||||
|
@@ -61,10 +61,10 @@ export function createPermissionGuard(router: Router) {
|
||||
path: LOGIN_PATH,
|
||||
replace: true,
|
||||
};
|
||||
if (to.path) {
|
||||
if (to.fullPath) {
|
||||
redirectData.query = {
|
||||
...redirectData.query,
|
||||
redirect: to.path,
|
||||
redirect: to.fullPath,
|
||||
};
|
||||
}
|
||||
next(redirectData);
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { AppRouteModule } from '@/router/types';
|
||||
import type { MenuModule, Menu, AppRouteRecordRaw } from '@/router/types';
|
||||
import type { Menu, AppRouteRecordRaw } from '@/router/types';
|
||||
import { findPath, treeMap } from '@/utils/helper/treeHelper';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { isHttpUrl } from '@/utils/is';
|
||||
@@ -30,13 +30,12 @@ function joinParentPath(menus: Menu[], parentPath = '') {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Parsing the menu module
|
||||
export function transformMenuModule(menuModule: MenuModule): Menu {
|
||||
const menuList = [menuModule];
|
||||
|
||||
joinParentPath(menuList);
|
||||
return menuList[0];
|
||||
// 菜单路径处理
|
||||
export function transformMenuModules(routeModList: Menu[]) {
|
||||
const cloneMenuModules = cloneDeep(routeModList);
|
||||
// 路径处理
|
||||
joinParentPath(cloneMenuModules);
|
||||
return cloneMenuModules;
|
||||
}
|
||||
|
||||
// 将路由转换成菜单
|
||||
|
@@ -3,7 +3,7 @@ import type { RouteRecordNormalized } from 'vue-router';
|
||||
|
||||
import { useAppStoreWithOut } from '@/store/modules/app';
|
||||
import { usePermissionStore } from '@/store/modules/permission';
|
||||
import { transformMenuModule, getAllParentPath } from '@/router/helper/menuHelper';
|
||||
import { getAllParentPath } from '@/router/helper/menuHelper';
|
||||
import { filter } from '@/utils/helper/treeHelper';
|
||||
import { isHttpUrl } from '@/utils/is';
|
||||
import { router } from '@/router';
|
||||
@@ -12,7 +12,7 @@ import { pathToRegexp } from 'path-to-regexp';
|
||||
|
||||
const modules = import.meta.glob('../routes/modules/**/*.ts', { eager: true });
|
||||
|
||||
const menuModules: MenuModule[] = [];
|
||||
export const menuModules: MenuModule[] = [];
|
||||
|
||||
Object.keys(modules).forEach((key) => {
|
||||
const mod = (modules as Recordable)[key].default || {};
|
||||
@@ -40,17 +40,6 @@ const isRoleMode = () => {
|
||||
return getPermissionMode() === PermissionModeEnum.ROLE;
|
||||
};
|
||||
|
||||
const staticMenus: Menu[] = [];
|
||||
(() => {
|
||||
menuModules.sort((a, b) => {
|
||||
return (a.orderNo || 0) - (b.orderNo || 0);
|
||||
});
|
||||
|
||||
for (const menu of menuModules) {
|
||||
staticMenus.push(transformMenuModule(menu));
|
||||
}
|
||||
})();
|
||||
|
||||
async function getAsyncMenus() {
|
||||
const permissionStore = usePermissionStore();
|
||||
//递归过滤所有隐藏的菜单
|
||||
@@ -69,7 +58,7 @@ async function getAsyncMenus() {
|
||||
if (isRouteMappingMode()) {
|
||||
return menuFilter(permissionStore.getFrontMenuList);
|
||||
}
|
||||
return staticMenus;
|
||||
return permissionStore.getStaticMenuList;
|
||||
}
|
||||
|
||||
export const getMenus = async (): Promise<Menu[]> => {
|
||||
|
@@ -16,6 +16,7 @@ import { Persistent } from '@/utils/cache/persistent';
|
||||
import { darkMode } from '@/settings/designSetting';
|
||||
import { resetRouter } from '@/router';
|
||||
import { deepMerge } from '@/utils';
|
||||
import setting from '@/settings/projectSetting';
|
||||
|
||||
interface AppState {
|
||||
darkMode?: ThemeEnum;
|
||||
@@ -40,7 +41,12 @@ export const useAppStore = defineStore({
|
||||
return state.pageLoading;
|
||||
},
|
||||
getDarkMode(state): 'light' | 'dark' | string {
|
||||
return state.darkMode || localStorage.getItem(APP_DARK_MODE_KEY) || darkMode;
|
||||
return (
|
||||
state.darkMode ||
|
||||
localStorage.getItem(APP_DARK_MODE_KEY) ||
|
||||
setting.menuSetting.theme ||
|
||||
darkMode
|
||||
);
|
||||
},
|
||||
|
||||
getBeforeMiniInfo(state): BeforeMiniState {
|
||||
|
@@ -134,7 +134,9 @@ export const useMultipleTabStore = defineStore({
|
||||
// Existing pages, do not add tabs repeatedly
|
||||
const tabHasExits = this.tabList.some((tab, index) => {
|
||||
updateIndex = index;
|
||||
return decodeURIComponent(tab.fullPath || tab.path) === decodeURIComponent(fullPath || path);
|
||||
return (
|
||||
decodeURIComponent(tab.fullPath || tab.path) === decodeURIComponent(fullPath || path)
|
||||
);
|
||||
});
|
||||
|
||||
// If the tab already exists, perform the update operation
|
||||
@@ -158,7 +160,7 @@ export const useMultipleTabStore = defineStore({
|
||||
const realPath = meta?.realPath ?? '';
|
||||
// 获取到已经打开的动态路由数, 判断是否大于某一个值
|
||||
if (
|
||||
this.tabList.filter((e) => e.meta?.realPath ?? '' === realPath).length >= dynamicLevel
|
||||
this.tabList.filter((e) => (e.meta?.realPath ?? '') === realPath).length >= dynamicLevel
|
||||
) {
|
||||
// 关闭第一个
|
||||
const index = this.tabList.findIndex((item) => item.meta.realPath === realPath);
|
||||
|
@@ -7,13 +7,14 @@ import { useUserStore } from './user';
|
||||
import { useAppStoreWithOut } from './app';
|
||||
import { toRaw } from 'vue';
|
||||
import { transformObjToRoute, flatMultiLevelRoutes } from '@/router/helper/routeHelper';
|
||||
import { transformRouteToMenu } from '@/router/helper/menuHelper';
|
||||
import { transformRouteToMenu, transformMenuModules } from '@/router/helper/menuHelper';
|
||||
|
||||
import projectSetting from '@/settings/projectSetting';
|
||||
|
||||
import { PermissionModeEnum } from '@/enums/appEnum';
|
||||
|
||||
import { asyncRoutes } from '@/router/routes';
|
||||
import { menuModules } from '@/router/menus';
|
||||
import { ERROR_LOG_ROUTE, PAGE_NOT_FOUND_ROUTE } from '@/router/routes/basic';
|
||||
|
||||
import { filter } from '@/utils/helper/treeHelper';
|
||||
@@ -39,6 +40,7 @@ interface PermissionState {
|
||||
backMenuList: Menu[];
|
||||
// 菜单列表
|
||||
frontMenuList: Menu[];
|
||||
staticMenuList: Menu[];
|
||||
}
|
||||
|
||||
export const usePermissionStore = defineStore({
|
||||
@@ -58,6 +60,7 @@ export const usePermissionStore = defineStore({
|
||||
// menu List
|
||||
// 菜单列表
|
||||
frontMenuList: [],
|
||||
staticMenuList: [],
|
||||
}),
|
||||
getters: {
|
||||
getPermCodeList(state): string[] | number[] {
|
||||
@@ -69,6 +72,9 @@ export const usePermissionStore = defineStore({
|
||||
getFrontMenuList(state): Menu[] {
|
||||
return state.frontMenuList;
|
||||
},
|
||||
getStaticMenuList(state): Menu[] {
|
||||
return state.staticMenuList;
|
||||
},
|
||||
getLastBuildMenuTime(state): number {
|
||||
return state.lastBuildMenuTime;
|
||||
},
|
||||
@@ -90,6 +96,10 @@ export const usePermissionStore = defineStore({
|
||||
this.frontMenuList = list;
|
||||
},
|
||||
|
||||
setStaticMenuList(list: Menu[]) {
|
||||
this.staticMenuList = list;
|
||||
},
|
||||
|
||||
setLastBuildMenuTime() {
|
||||
this.lastBuildMenuTime = new Date().getTime();
|
||||
},
|
||||
@@ -171,6 +181,12 @@ export const usePermissionStore = defineStore({
|
||||
switch (permissionMode) {
|
||||
// 角色权限
|
||||
case PermissionModeEnum.ROLE:
|
||||
const staticMenuList = transformMenuModules(menuModules);
|
||||
staticMenuList.sort((a, b) => {
|
||||
return (a.orderNo || 0) - (b.orderNo || 0);
|
||||
});
|
||||
// 设置菜单列表
|
||||
this.setStaticMenuList(staticMenuList);
|
||||
// 对非一级路由进行过滤
|
||||
routes = filter(asyncRoutes, routeFilter);
|
||||
// 对一级路由根据角色权限过滤
|
||||
|
@@ -16,8 +16,6 @@ export class AxiosRetry {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
config.__retryCount += 1;
|
||||
//请求返回后config的header不正确造成重试请求失败,删除返回headers采用默认headers
|
||||
delete config.headers;
|
||||
return this.delay(waitTime).then(() => axiosInstance(config));
|
||||
}
|
||||
|
||||
|
@@ -20,14 +20,19 @@ export function getPopupContainer(node?: HTMLElement): HTMLElement {
|
||||
* @param obj
|
||||
* @returns {string}
|
||||
* eg:
|
||||
* let obj = {a: '3', b: '4'}
|
||||
* let obj = {a: '3', b: '4', c: ['1','2']}
|
||||
* setObjToUrlParams('www.baidu.com', obj)
|
||||
* ==>www.baidu.com?a=3&b=4
|
||||
* ==>www.baidu.com?a=3&b=4&c=1,2
|
||||
*/
|
||||
export function setObjToUrlParams(baseUrl: string, obj: any): string {
|
||||
let parameters = '';
|
||||
for (const key in obj) {
|
||||
parameters += key + '=' + encodeURIComponent(obj[key]) + '&';
|
||||
const value = obj[key];
|
||||
if (Array.isArray(value)) {
|
||||
parameters += `${key}=${encodeURIComponent(value.join(','))}&`;
|
||||
} else {
|
||||
parameters += `${key}=${encodeURIComponent(value)}&`;
|
||||
}
|
||||
}
|
||||
parameters = parameters.replace(/&$/, '');
|
||||
return /\?$/.test(baseUrl) ? baseUrl + parameters : baseUrl.replace(/\/?$/, '?') + parameters;
|
||||
|
@@ -1,49 +1,77 @@
|
||||
<template>
|
||||
<PageWrapper title="截图示例">
|
||||
<Row :gutter="24">
|
||||
<Col :span="3">
|
||||
<Card title="截图">
|
||||
<a-button type="primary" @click="screenShot">点击截图</a-button>
|
||||
<div class="mt-8" v-show="open">
|
||||
<a-button type="primary" @click="Dele">点击删除</a-button>
|
||||
</div>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col :span="21">
|
||||
<Card title="截图内容" v-show="open">
|
||||
<div ref="picture"></div>
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
<CollapseContainer title="截图操作">
|
||||
<a-button type="primary" class="mr-2" @click="handleScreenshot">截取当前body</a-button>
|
||||
<a-button type="primary" class="mr-2" :disabled="!showPicture" @click="handleDelScreenshot"
|
||||
>删除截图</a-button
|
||||
>
|
||||
<a-button type="primary" class="mr-2" :disabled="!showPicture" @click="handlePrintScreenshot"
|
||||
>打印截图</a-button
|
||||
>
|
||||
<a-button
|
||||
type="primary"
|
||||
class="mr-2"
|
||||
:disabled="!showPicture"
|
||||
@click="handleDownloadScreenshot"
|
||||
>下载截图</a-button
|
||||
>
|
||||
</CollapseContainer>
|
||||
|
||||
<Card title="截图内容" class="mt-4">
|
||||
<div ref="pictureRef" v-show="showPicture"></div>
|
||||
</Card>
|
||||
</PageWrapper>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { PageWrapper } from '@/components/Page';
|
||||
import html2canvas from 'html2canvas';
|
||||
import { ref } from 'vue';
|
||||
import { Card, Col, Row } from 'ant-design-vue';
|
||||
import { Card } from 'ant-design-vue';
|
||||
import { CollapseContainer } from '@/components/Container';
|
||||
import printJS from 'print-js';
|
||||
import { downloadByBase64 } from '@/utils/file/download';
|
||||
|
||||
const picture = ref();
|
||||
const open = ref(false);
|
||||
function screenShot() {
|
||||
if (open.value) {
|
||||
return;
|
||||
}
|
||||
const pictureRef = ref();
|
||||
const showPicture = ref<boolean>(false);
|
||||
const canvasUrl = ref<string>('');
|
||||
|
||||
function handleScreenshot() {
|
||||
if (showPicture.value) return;
|
||||
html2canvas(document.body, {
|
||||
backgroundColor: '#ffffff',
|
||||
allowTaint: true, //开启跨域
|
||||
useCORS: true,
|
||||
scrollY: 0,
|
||||
scrollX: 0,
|
||||
}).then(function (canvas) {
|
||||
canvas.style.width = '100%';
|
||||
canvas.style.height = '100%';
|
||||
picture.value.appendChild(canvas);
|
||||
open.value = true;
|
||||
})
|
||||
.then(function (canvas) {
|
||||
canvas.style.width = '100%';
|
||||
canvas.style.height = '100%';
|
||||
pictureRef.value.appendChild(canvas);
|
||||
showPicture.value = true;
|
||||
canvasUrl.value = canvas.toDataURL();
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log('绘制失败', err);
|
||||
});
|
||||
}
|
||||
|
||||
function handleDelScreenshot() {
|
||||
pictureRef.value.innerHTML = '';
|
||||
canvasUrl.value = '';
|
||||
showPicture.value = false;
|
||||
}
|
||||
|
||||
function handlePrintScreenshot() {
|
||||
if (!canvasUrl.value) return;
|
||||
printJS({
|
||||
printable: canvasUrl.value,
|
||||
type: 'image',
|
||||
base64: true,
|
||||
});
|
||||
}
|
||||
function Dele() {
|
||||
picture.value.innerHTML = '';
|
||||
open.value = false;
|
||||
|
||||
function handleDownloadScreenshot() {
|
||||
downloadByBase64(canvasUrl.value, 'screen_shot.png');
|
||||
}
|
||||
</script>
|
||||
|
@@ -18,8 +18,8 @@
|
||||
import { useMessage } from '@/hooks/web/useMessage';
|
||||
import { PageWrapper } from '@/components/Page';
|
||||
import { isAccountExist } from '@/api/demo/system';
|
||||
import dayjs from "dayjs"
|
||||
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
const schemas: FormSchema[] = [
|
||||
{
|
||||
field: 'field1',
|
||||
@@ -236,7 +236,7 @@
|
||||
field5: ['1'],
|
||||
field7: '1',
|
||||
field33: '2020-12-12',
|
||||
field3: dayjs('2020-12-12',"YYYY-MM-DD"),
|
||||
field3: dayjs('2020-12-12', 'YYYY-MM-DD'),
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -57,8 +57,8 @@
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { type Recordable } from '@vben/types';
|
||||
import { computed, unref, ref } from 'vue';
|
||||
import { BasicForm, ApiSelect, FormSchema } from '@/components/Form';
|
||||
import { computed, ref, unref } from 'vue';
|
||||
import { ApiSelect, BasicForm, FormSchema } from '@/components/Form';
|
||||
import { CollapseContainer } from '@/components/Container';
|
||||
import { useMessage } from '@/hooks/web/useMessage';
|
||||
import { PageWrapper } from '@/components/Page';
|
||||
@@ -472,7 +472,7 @@
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'field32',
|
||||
field: 'field32-1',
|
||||
label: '下拉远程搜索',
|
||||
helpMessage: ['ApiSelect组件', '将关键词发送到接口进行远程搜索'],
|
||||
required: true,
|
||||
@@ -482,6 +482,35 @@
|
||||
},
|
||||
defaultValue: '0',
|
||||
},
|
||||
{
|
||||
field: 'field32-2',
|
||||
label: '下拉远程搜索',
|
||||
component: 'ApiSelect',
|
||||
helpMessage: ['ApiSelect组件', '将关键词发送到接口进行远程搜索'],
|
||||
componentProps: {
|
||||
api: optionsListApi,
|
||||
showSearch: true,
|
||||
apiSearch: {
|
||||
show: true,
|
||||
searchName: 'name',
|
||||
},
|
||||
resultField: 'list',
|
||||
labelField: 'name',
|
||||
valueField: 'id',
|
||||
immediate: true,
|
||||
onChange: (e, v) => {
|
||||
console.log('ApiSelect====>:', e, v);
|
||||
},
|
||||
onOptionsChange: (options) => {
|
||||
console.log('get options', options.length, options);
|
||||
},
|
||||
},
|
||||
required: true,
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
defaultValue: '0',
|
||||
},
|
||||
{
|
||||
field: 'field33',
|
||||
component: 'ApiTreeSelect',
|
||||
|
Reference in New Issue
Block a user