Merge branch 'antd4'

pull/975/head
zhangdaiscott 2024-01-03 19:16:08 +08:00
commit 458b6bfabe
173 changed files with 9780 additions and 6666 deletions

View File

@ -4,6 +4,7 @@ VITE_USE_MOCK = true
# 发布路径 # 发布路径
VITE_PUBLIC_PATH = / VITE_PUBLIC_PATH = /
# 跨域代理,您可以配置多个 ,请注意,没有换行符 # 跨域代理,您可以配置多个 ,请注意,没有换行符
VITE_PROXY = [["/jeecgboot","http://localhost:8080/jeecg-boot"],["/upload","http://localhost:3300/upload"]] VITE_PROXY = [["/jeecgboot","http://localhost:8080/jeecg-boot"],["/upload","http://localhost:3300/upload"]]

1
.gitignore vendored
View File

@ -22,6 +22,7 @@ pnpm-debug.log*
# Editor directories and files # Editor directories and files
.idea .idea
.svn
# .vscode # .vscode
*.suo *.suo
*.ntvs* *.ntvs*

View File

@ -32,4 +32,6 @@ SOFTWARE.
违反此条款属于侵权行为,须赔偿侵权经济损失,同时立即停止著作权侵权行为。 违反此条款属于侵权行为,须赔偿侵权经济损失,同时立即停止著作权侵权行为。
总结在遵循Apache开源协议和开源协议补充条款下允许商用使用不会造成侵权行为 总结在遵循Apache开源协议和开源协议补充条款下允许商用使用不会造成侵权行为
解释权归http://www.jeecg.com 解释权归:
http://www.jeecg.com
http://guojusoft.com

View File

@ -1,11 +1,11 @@
JEECG BOOT 低代码开发平台Vue3前端 JEECG BOOT 低代码开发平台Vue3前端
=============== ===============
当前最新版本: 3.6.1发布时间2023-12-11 当前最新版本: 3.6.2发布时间2024-01-08
[![AUR](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg)](https://github.com/zhangdaiscott/jeecg-boot/blob/master/LICENSE) [![AUR](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg)](https://github.com/zhangdaiscott/jeecg-boot/blob/master/LICENSE)
[![](https://img.shields.io/badge/Author-北京国炬软件-orange.svg)](http://jeecg.com/aboutusIndex) [![](https://img.shields.io/badge/Author-北京国炬软件-orange.svg)](http://jeecg.com/aboutusIndex)
[![](https://img.shields.io/badge/Blog-官方博客-blue.svg)](https://jeecg.blog.csdn.net) [![](https://img.shields.io/badge/Blog-官方博客-blue.svg)](https://jeecg.blog.csdn.net)
[![](https://img.shields.io/badge/version-3.6.1-brightgreen.svg)](https://github.com/zhangdaiscott/jeecg-boot) [![](https://img.shields.io/badge/version-3.6.2-brightgreen.svg)](https://github.com/zhangdaiscott/jeecg-boot)
[![GitHub stars](https://img.shields.io/github/stars/zhangdaiscott/jeecg-boot.svg?style=social&label=Stars)](https://github.com/zhangdaiscott/jeecg-boot) [![GitHub stars](https://img.shields.io/github/stars/zhangdaiscott/jeecg-boot.svg?style=social&label=Stars)](https://github.com/zhangdaiscott/jeecg-boot)
[![GitHub forks](https://img.shields.io/github/forks/zhangdaiscott/jeecg-boot.svg?style=social&label=Fork)](https://github.com/zhangdaiscott/jeecg-boot) [![GitHub forks](https://img.shields.io/github/forks/zhangdaiscott/jeecg-boot.svg?style=social&label=Fork)](https://github.com/zhangdaiscott/jeecg-boot)

View File

@ -1,11 +1,21 @@
import { generateAntColors, primaryColor } from '../config/themeConfig'; import { primaryColor } from '../config/themeConfig';
import { getThemeVariables } from 'ant-design-vue/dist/theme'; // import { getThemeVariables } from 'ant-design-vue/dist/theme';
import { resolve } from 'path'; import { resolve } from 'path';
import { generate } from '@ant-design/colors';
import { theme } from 'ant-design-vue/lib';
import convertLegacyToken from 'ant-design-vue/lib/theme/convertLegacyToken';
const { defaultAlgorithm, defaultSeed } = theme;
function generateAntColors(color: string, theme: 'default' | 'dark' = 'default') {
return generate(color, {
theme,
});
}
/** /**
* less global variable * less global variable
*/ */
export function generateModifyVars(dark = false) { export function generateModifyVars() {
const palettes = generateAntColors(primaryColor); const palettes = generateAntColors(primaryColor);
const primary = palettes[5]; const primary = palettes[5];
@ -15,12 +25,14 @@ export function generateModifyVars(dark = false) {
primaryColorObj[`primary-${index + 1}`] = palettes[index]; primaryColorObj[`primary-${index + 1}`] = palettes[index];
} }
const modifyVars = getThemeVariables({ dark }); const mapToken = defaultAlgorithm(defaultSeed);
const v3Token = convertLegacyToken(mapToken);
return { return {
...modifyVars, ...v3Token,
// ...modifyVars,
// Used for global import to avoid the need to import each style file separately // Used for global import to avoid the need to import each style file separately
// reference: Avoid repeated references // reference: Avoid repeated references
hack: `${modifyVars.hack} @import (reference) "${resolve('src/design/config.less')}";`, hack: `true; @import (reference) "${resolve('src/design/config.less')}";`,
'primary-color': primary, 'primary-color': primary,
...primaryColorObj, ...primaryColorObj,
'info-color': primary, 'info-color': primary,

View File

@ -11,7 +11,6 @@ import vueSetupExtend from 'vite-plugin-vue-setup-extend-plus';
import { configHtmlPlugin } from './html'; import { configHtmlPlugin } from './html';
import { configMockPlugin } from './mock'; import { configMockPlugin } from './mock';
import { configCompressPlugin } from './compress'; import { configCompressPlugin } from './compress';
import { configStyleImportPlugin } from './styleImport';
import { configVisualizerConfig } from './visualizer'; import { configVisualizerConfig } from './visualizer';
import { configThemePlugin } from './theme'; import { configThemePlugin } from './theme';
import { configSvgIconsPlugin } from './svgSprite'; import { configSvgIconsPlugin } from './svgSprite';
@ -49,9 +48,6 @@ export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean) {
// vite-plugin-purge-icons // vite-plugin-purge-icons
vitePlugins.push(purgeIcons()); vitePlugins.push(purgeIcons());
// vite-plugin-style-import
vitePlugins.push(configStyleImportPlugin(isBuild));
// rollup-plugin-visualizer // rollup-plugin-visualizer
vitePlugins.push(configVisualizerConfig()); vitePlugins.push(configVisualizerConfig());

View File

@ -57,7 +57,7 @@ export function configThemePlugin(isBuild: boolean): PluginOption[] {
vite_theme_plugin, vite_theme_plugin,
antdDarkThemePlugin({ antdDarkThemePlugin({
preloadFiles: [ preloadFiles: [
path.resolve(process.cwd(), 'node_modules/ant-design-vue/dist/antd.less'), // path.resolve(process.cwd(), 'node_modules/ant-design-vue/dist/reset.css'),
//path.resolve(process.cwd(), 'node_modules/ant-design-vue/dist/antd.dark.less'), //path.resolve(process.cwd(), 'node_modules/ant-design-vue/dist/antd.dark.less'),
path.resolve(process.cwd(), 'src/design/index.less'), path.resolve(process.cwd(), 'src/design/index.less'),
], ],

View File

@ -166,6 +166,7 @@
</div> </div>
</div> </div>
<script type="module" src="/src/main.ts"></script> <script type="module" src="/src/main.ts"></script>
<!-- 百度统计 -->
<script> <script>
var _hmt = _hmt || []; var _hmt = _hmt || [];
(function() { (function() {
@ -175,5 +176,6 @@
s.parentNode.insertBefore(hm, s); s.parentNode.insertBefore(hm, s);
})(); })();
</script> </script>
</body> </body>
</html> </html>

View File

@ -1,10 +1,10 @@
{ {
"name": "jeecgboot-vue3", "name": "jeecgboot-vue3",
"version": "3.6.1", "version": "3.6.2",
"author": { "author": {
"name": "北京国炬信息技术有限公司", "name": "北京国炬信息技术有限公司",
"email": "jeecgos@163.com", "email": "jeecgos@163.com",
"url": "http://guojusoft.com" "url": "https://github.com/jeecgboot/jeecgboot-vue3"
}, },
"scripts": { "scripts": {
"pinstall": "pnpm install", "pinstall": "pnpm install",
@ -21,8 +21,7 @@
"husky:install": "husky install" "husky:install": "husky install"
}, },
"dependencies": { "dependencies": {
"@jeecg/online": "3.6.0-beta", "@jeecg/online": "3.6.2-beta",
"@qiaoqiaoyun/drag-free": "^1.1.4",
"@iconify/iconify": "^3.1.1", "@iconify/iconify": "^3.1.1",
"@ant-design/colors": "^7.0.0", "@ant-design/colors": "^7.0.0",
"@ant-design/icons-vue": "^6.1.0", "@ant-design/icons-vue": "^6.1.0",
@ -32,8 +31,9 @@
"@vue/shared": "^3.3.4", "@vue/shared": "^3.3.4",
"@vueuse/shared": "^10.4.1", "@vueuse/shared": "^10.4.1",
"@vueuse/core": "^10.4.1", "@vueuse/core": "^10.4.1",
"@tinymce/tinymce-vue": "^4.0.7",
"@zxcvbn-ts/core": "^3.0.3", "@zxcvbn-ts/core": "^3.0.3",
"ant-design-vue": "^3.2.20", "ant-design-vue": "^4.0.6",
"axios": "^1.5.0", "axios": "^1.5.0",
"china-area-data": "^5.0.1", "china-area-data": "^5.0.1",
"clipboard": "^2.0.11", "clipboard": "^2.0.11",
@ -61,7 +61,7 @@
"resize-observer-polyfill": "^1.5.1", "resize-observer-polyfill": "^1.5.1",
"showdown": "^2.1.0", "showdown": "^2.1.0",
"sortablejs": "^1.15.0", "sortablejs": "^1.15.0",
"tinymce": "^5.10.3", "tinymce": "^6.6.2",
"vditor": "^3.9.5", "vditor": "^3.9.5",
"vue": "^3.3.4", "vue": "^3.3.4",
"vue-cropper": "^0.6.2", "vue-cropper": "^0.6.2",
@ -150,7 +150,6 @@
"vite-plugin-mkcert": "^1.16.0", "vite-plugin-mkcert": "^1.16.0",
"vite-plugin-mock": "^2.9.6", "vite-plugin-mock": "^2.9.6",
"vite-plugin-purge-icons": "^0.9.2", "vite-plugin-purge-icons": "^0.9.2",
"vite-plugin-style-import": "^2.0.0",
"vite-plugin-svg-icons": "^2.0.1", "vite-plugin-svg-icons": "^2.0.1",
"@rys-fe/vite-plugin-theme": "^0.8.6", "@rys-fe/vite-plugin-theme": "^0.8.6",
"vite-plugin-vue-setup-extend-plus": "^0.1.0", "vite-plugin-vue-setup-extend-plus": "^0.1.0",

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
<template> <template>
<ConfigProvider :locale="getAntdLocale"> <ConfigProvider :theme="appTheme" :locale="getAntdLocale">
<AppProvider> <AppProvider>
<RouterView /> <RouterView />
</AppProvider> </AppProvider>
@ -7,20 +7,73 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { watch, ref } from 'vue';
import { theme } from 'ant-design-vue';
import { ConfigProvider } from 'ant-design-vue'; import { ConfigProvider } from 'ant-design-vue';
import { AppProvider } from '/@/components/Application'; import { AppProvider } from '/@/components/Application';
import { useTitle } from '/@/hooks/web/useTitle'; import { useTitle } from '/@/hooks/web/useTitle';
import { useLocale } from '/@/locales/useLocale'; import { useLocale } from '/@/locales/useLocale';
import { useAppStore } from '/@/store/modules/app';
import { useRootSetting } from '/@/hooks/setting/useRootSetting';
import { ThemeEnum } from '/@/enums/appEnum';
import { changeTheme } from '/@/logics/theme/index';
const appStore = useAppStore();
// //
import 'dayjs/locale/zh-cn'; import 'dayjs/locale/zh-cn';
// support Multi-language // support Multi-language
const { getAntdLocale } = useLocale(); const { getAntdLocale } = useLocale();
useTitle(); useTitle();
// update-begin--author:liaozhiyang---date:20231218---forQQYUN-6366antd4.x
const appTheme: any = ref({});
const { getDarkMode } = useRootSetting();
watch(
() => getDarkMode.value,
(newValue) => {
delete appTheme.value.algorithm;
if (newValue === ThemeEnum.DARK) {
appTheme.value.algorithm = theme.darkAlgorithm;
}
appTheme.value = {
...appTheme.value,
};
},
{ immediate: true }
);
watch(
appStore.getProjectConfig,
(newValue) => {
const primary = newValue.themeColor;
appTheme.value = {
...appTheme.value,
...{
token: {
colorPrimary: primary,
wireframe: true,
fontSize: 14,
colorSuccess: '#55D187',
colorInfo: primary,
borderRadius: 2,
sizeStep: 4,
sizeUnit: 4,
colorWarning: '#EFBD47',
colorError: '#ED6F6F',
},
},
};
},
{ immediate: true }
);
setTimeout(() => {
appStore.getProjectConfig?.themeColor && changeTheme(appStore.getProjectConfig.themeColor);
}, 300);
// update-end--author:liaozhiyang---date:20231218---forQQYUN-6366antd4.x
</script> </script>
<style lang="less"> <style lang="less">
// update-begin--author:liaozhiyang---date:20230803---forQQYUN-5839windihtml2canvas // update-begin--author:liaozhiyang---date:20230803---forQQYUN-5839windihtml2canvas
img{display:inline-block;} img {
// update-end--author:liaozhiyang---date:20230803---forQQYUN-5839windihtml2canvas display: inline-block;
}
// update-end--author:liaozhiyang---date:20230803---forQQYUN-5839windihtml2canvas
</style> </style>

View File

@ -178,7 +178,7 @@
&-input { &-input {
width: 100%; width: 100%;
height: 48px; height: 48px;
font-size: 1.5em; font-size: 1.3em;
color: #1c1e21; color: #1c1e21;
border-radius: 6px; border-radius: 6px;
@ -222,7 +222,7 @@
font-size: 14px; font-size: 14px;
color: @text-color-base; color: @text-color-base;
cursor: pointer; cursor: pointer;
background-color: @component-background; // background-color: @component-background;
border-radius: 4px; border-radius: 4px;
box-shadow: 0 1px 3px 0 #d4d9e1; box-shadow: 0 1px 3px 0 #d4d9e1;
align-items: center; align-items: center;

View File

@ -53,6 +53,10 @@
cursor: move; cursor: move;
user-select: none; user-select: none;
&.is-drawer {
cursor: default;
}
&-normal { &-normal {
font-size: 14px; font-size: 14px;
font-weight: 500; font-weight: 500;

View File

@ -30,13 +30,30 @@
// get inherit binding value // get inherit binding value
const getBindValues = computed(() => { const getBindValues = computed(() => {
return Object.assign( // update-begin--author:liaozhiyang---date:20231228---forissues/936
const result: any = Object.assign(
{ {
okText: t('common.okText'), okText: t('common.okText'),
cancelText: t('common.cancelText'), cancelText: t('common.cancelText'),
}, },
{ ...props, ...unref(attrs) } { ...props, ...unref(attrs) }
); );
if (result.onConfirm) {
const confirm = result.confirm;
result.onConfirm = () => {
return new Promise<void>((resolve) => {
confirm()
?.finally(() => {
resolve();
})
.catch((err) => {
console.log(err);
});
});
};
}
return result;
// update-end--author:liaozhiyang---date:20231228---forissues/936
}); });
return () => { return () => {

View File

@ -40,7 +40,7 @@
components: { Drawer, ScrollContainer, DrawerFooter, DrawerHeader }, components: { Drawer, ScrollContainer, DrawerFooter, DrawerHeader },
inheritAttrs: false, inheritAttrs: false,
props: basicProps, props: basicProps,
emits: ['visible-change', 'ok', 'close', 'register'], emits: ['visible-change', 'open-change', 'ok', 'close', 'register'],
setup(props, { emit }) { setup(props, { emit }) {
const visibleRef = ref(false); const visibleRef = ref(false);
const attrs = useAttrs(); const attrs = useAttrs();
@ -63,12 +63,14 @@
}); });
const getProps = computed((): DrawerProps => { const getProps = computed((): DrawerProps => {
// update-begin--author:liaozhiyang---date:20231218---forQQYUN-6366antd4.x
const opt = { const opt = {
placement: 'right', placement: 'right',
...unref(attrs), ...unref(attrs),
...unref(getMergeProps), ...unref(getMergeProps),
visible: unref(visibleRef), open: unref(visibleRef),
}; };
// update-end--author:liaozhiyang---date:20231218---forQQYUN-6366antd4.x
opt.title = undefined; opt.title = undefined;
let { isDetail, width, wrapClassName, getContainer } = opt; let { isDetail, width, wrapClassName, getContainer } = opt;
if (isDetail) { if (isDetail) {
@ -123,11 +125,20 @@
{ deep: true } { deep: true }
); );
watch(
() => props.open,
(newVal, oldVal) => {
if (newVal !== oldVal) visibleRef.value = newVal;
},
{ deep: true }
);
watch( watch(
() => visibleRef.value, () => visibleRef.value,
(visible) => { (visible) => {
nextTick(() => { nextTick(() => {
emit('visible-change', visible); emit('visible-change', visible);
emit('open-change', visible);
instance && drawerInstance.emitVisible?.(visible, instance.uid); instance && drawerInstance.emitVisible?.(visible, instance.uid);
}); });
} }
@ -152,6 +163,9 @@
if (Reflect.has(props, 'visible')) { if (Reflect.has(props, 'visible')) {
visibleRef.value = !!props.visible; visibleRef.value = !!props.visible;
} }
if (Reflect.has(props, 'open')) {
visibleRef.value = !!props.open;
}
} }
function handleOk() { function handleOk() {

View File

@ -1,5 +1,5 @@
<template> <template>
<BasicTitle v-if="!isDetail" :class="prefixCls"> <BasicTitle v-if="!isDetail" :class="[prefixCls, 'is-drawer']">
<slot name="title"></slot> <slot name="title"></slot>
{{ !$slots.title ? title : '' }} {{ !$slots.title ? title : '' }}
</BasicTitle> </BasicTitle>

View File

@ -31,6 +31,7 @@ export const basicProps = {
loadingText: { type: String }, loadingText: { type: String },
showDetailBack: { type: Boolean, default: true }, showDetailBack: { type: Boolean, default: true },
visible: { type: Boolean }, visible: { type: Boolean },
open: { type: Boolean },
loading: { type: Boolean }, loading: { type: Boolean },
maskClosable: { type: Boolean, default: true }, maskClosable: { type: Boolean, default: true },
getContainer: { getContainer: {

View File

@ -11,6 +11,7 @@ export interface ReturnMethods extends DrawerInstance {
openDrawer: <T = any>(visible?: boolean, data?: T, openOnSet?: boolean) => void; openDrawer: <T = any>(visible?: boolean, data?: T, openOnSet?: boolean) => void;
closeDrawer: () => void; closeDrawer: () => void;
getVisible?: ComputedRef<boolean>; getVisible?: ComputedRef<boolean>;
getOpen?: ComputedRef<boolean>;
} }
export type RegisterFn = (drawerInstance: DrawerInstance, uuid?: string) => void; export type RegisterFn = (drawerInstance: DrawerInstance, uuid?: string) => void;
@ -20,6 +21,7 @@ export interface ReturnInnerMethods extends DrawerInstance {
changeLoading: (loading: boolean) => void; changeLoading: (loading: boolean) => void;
changeOkLoading: (loading: boolean) => void; changeOkLoading: (loading: boolean) => void;
getVisible?: ComputedRef<boolean>; getVisible?: ComputedRef<boolean>;
getOpen?: ComputedRef<boolean>;
} }
export type UseDrawerReturnType = [RegisterFn, ReturnMethods]; export type UseDrawerReturnType = [RegisterFn, ReturnMethods];
@ -74,6 +76,7 @@ export interface DrawerProps extends DrawerFooterProps {
loading?: boolean; loading?: boolean;
showDetailBack?: boolean; showDetailBack?: boolean;
visible?: boolean; visible?: boolean;
open?: boolean;
/** /**
* Built-in ScrollContainer component configuration * Built-in ScrollContainer component configuration
* @type ScrollContainerOptions * @type ScrollContainerOptions

View File

@ -58,10 +58,16 @@ export function useDrawer(): UseDrawerReturnType {
return visibleData[~~unref(uid)]; return visibleData[~~unref(uid)];
}), }),
getOpen: computed((): boolean => {
return visibleData[~~unref(uid)];
}),
openDrawer: <T = any>(visible = true, data?: T, openOnSet = true): void => { openDrawer: <T = any>(visible = true, data?: T, openOnSet = true): void => {
// update-begin--author:liaozhiyang---date:20231218---for【QQYUN-6366】升级到antd4.x
getInstance()?.setDrawerProps({ getInstance()?.setDrawerProps({
visible: visible, open: visible,
}); });
// update-end--author:liaozhiyang---date:20231218---for【QQYUN-6366】升级到antd4.x
if (!data) return; if (!data) return;
if (openOnSet) { if (openOnSet) {
@ -75,7 +81,9 @@ export function useDrawer(): UseDrawerReturnType {
} }
}, },
closeDrawer: () => { closeDrawer: () => {
getInstance()?.setDrawerProps({ visible: false }); // update-begin--author:liaozhiyang---date:20231218---for【QQYUN-6366】升级到antd4.x
getInstance()?.setDrawerProps({ open: false });
// update-end--author:liaozhiyang---date:20231218---for【QQYUN-6366】升级到antd4.x
}, },
}; };
@ -133,9 +141,11 @@ export const useDrawerInner = (callbackFn?: Fn): UseDrawerInnerReturnType => {
getVisible: computed((): boolean => { getVisible: computed((): boolean => {
return visibleData[~~unref(uidRef)]; return visibleData[~~unref(uidRef)];
}), }),
getOpen: computed((): boolean => {
return visibleData[~~unref(uidRef)];
}),
closeDrawer: () => { closeDrawer: () => {
getInstance()?.setDrawerProps({ visible: false }); getInstance()?.setDrawerProps({ open: false });
}, },
setDrawerProps: (props: Partial<DrawerProps>) => { setDrawerProps: (props: Partial<DrawerProps>) => {

View File

@ -202,6 +202,22 @@
if (characterInx !== -1 && !rules[characterInx].validator) { if (characterInx !== -1 && !rules[characterInx].validator) {
rules[characterInx].message = rules[characterInx].message || t('component.form.maxTip', [rules[characterInx].max] as Recordable); rules[characterInx].message = rules[characterInx].message || t('component.form.maxTip', [rules[characterInx].max] as Recordable);
} }
// update-begin--author:liaozhiyang---date:20241226---forQQYUN-7495patternantd使InputNumber
rules.forEach((item) => {
if (typeof item.pattern === 'string') {
try {
const reg = new Function('item', `return ${item.pattern}`)(item);
if (Object.prototype.toString.call(reg) === '[object RegExp]') {
item.pattern = reg;
} else {
item.pattern = new RegExp(item.pattern);
}
} catch (error) {
item.pattern = new RegExp(item.pattern);
}
}
});
// update-end--author:liaozhiyang---date:20231226---forQQYUN-7495patternantd使InputNumber
return rules; return rules;
} }
@ -249,7 +265,10 @@
const { autoSetPlaceHolder, size } = props.formProps; const { autoSetPlaceHolder, size } = props.formProps;
const propsData: Recordable = { const propsData: Recordable = {
allowClear: true, allowClear: true,
getPopupContainer: (trigger: Element) => trigger.parentNode, getPopupContainer: (trigger: Element) => {
return trigger?.parentNode;
},
size, size,
...unref(getComponentsProps), ...unref(getComponentsProps),
disabled: unref(getDisable), disabled: unref(getDisable),

View File

@ -61,6 +61,18 @@ export function handleInputNumberValue(component?: ComponentType, val?: any) {
} }
return val; return val;
} }
/**
*liaozhiyang
*2023-12-26
*
*/
export function handleInputStringValue(component?: ComponentType, val?: any) {
if (!component) return val;
if (['InputNumber'].includes(component) && typeof val === 'string') {
return Number(val);
}
return val;
}
/** /**
* *

View File

@ -4,7 +4,7 @@ import type { NamePath, ValidateOptions } from 'ant-design-vue/lib/form/interfac
import { unref, toRaw } from 'vue'; import { unref, toRaw } from 'vue';
import { isArray, isFunction, isObject, isString } from '/@/utils/is'; import { isArray, isFunction, isObject, isString } from '/@/utils/is';
import { deepMerge, getValueType } from '/@/utils'; import { deepMerge, getValueType } from '/@/utils';
import { dateItemType, handleInputNumberValue } from '../helper'; import { dateItemType, handleInputNumberValue, handleInputStringValue } from '../helper';
import { dateUtil } from '/@/utils/dateUtil'; import { dateUtil } from '/@/utils/dateUtil';
import { cloneDeep, uniqBy } from 'lodash-es'; import { cloneDeep, uniqBy } from 'lodash-es';
import { error } from '/@/utils/log'; import { error } from '/@/utils/log';
@ -65,6 +65,9 @@ export function useFormEvents({
const hasKey = Reflect.has(values, key); const hasKey = Reflect.has(values, key);
value = handleInputNumberValue(schema?.component, value); value = handleInputNumberValue(schema?.component, value);
// update-begin--author:liaozhiyang---date:20231226---for【QQYUN-7535】popup回填字段inputNumber组件验证错误
value = handleInputStringValue(schema?.component, value);
// update-end--author:liaozhiyang---date:20231226---for【QQYUN-7535】popup回填字段inputNumber组件验证错误
// 0| '' is allow // 0| '' is allow
if (hasKey && fields.includes(key)) { if (hasKey && fields.includes(key)) {
// time type // time type

View File

@ -44,7 +44,7 @@
allowClear: propTypes.bool.def(false), allowClear: propTypes.bool.def(false),
getPopupContainer: { getPopupContainer: {
type: Function, type: Function,
default: (node) => node.parentNode, default: (node) => node?.parentNode,
}, },
}, },
emits: ['change', 'update:value','update:area','update:city','update:province'], emits: ['change', 'update:value','update:area','update:city','update:province'],

View File

@ -60,7 +60,7 @@
// //
fullScreen: propTypes.bool.def(false), fullScreen: propTypes.bool.def(false),
// z-index // z-index
zIndex: propTypes.any.def(999), zIndex: propTypes.any.def(1500),
theme: propTypes.string.def('idea'), theme: propTypes.string.def('idea'),
language: propTypes.string.def(''), language: propTypes.string.def(''),
// //

View File

@ -71,7 +71,7 @@
stringToNumber: propTypes.bool, stringToNumber: propTypes.bool,
getPopupContainer: { getPopupContainer: {
type: Function, type: Function,
default: (node) => node.parentNode, default: (node) => node?.parentNode,
}, },
// //
showChooseOption: propTypes.bool.def(true), showChooseOption: propTypes.bool.def(true),

View File

@ -25,7 +25,7 @@
</a-button> </a-button>
</div> </div>
</a-upload> </a-upload>
<a-modal :visible="previewVisible" :footer="null" @cancel="handleCancel()"> <a-modal :open="previewVisible" :footer="null" @cancel="handleCancel()">
<img alt="example" style="width: 100%" :src="previewImage" /> <img alt="example" style="width: 100%" :src="previewImage" />
</a-modal> </a-modal>
</div> </div>

View File

@ -2,14 +2,14 @@
<div> <div>
<BasicModal v-bind="$attrs" @register="register" title="导入EXCEL" :width="600" @cancel="handleClose" :confirmLoading="uploading" destroyOnClose> <BasicModal v-bind="$attrs" @register="register" title="导入EXCEL" :width="600" @cancel="handleClose" :confirmLoading="uploading" destroyOnClose>
<!--是否校验--> <!--是否校验-->
<div style="margin: 0 5px 1px" v-if="online"> <div style="margin: 0 5px 5px" v-if="online">
<span style="display: inline-block; height: 32px; line-height: 32px; vertical-align: middle">是否开启校验:</span> <span style="display: inline-block; height: 32px; line-height: 32px; vertical-align: middle">是否开启校验:</span>
<span style="margin-left: 6px"> <span style="margin-left: 6px">
<a-switch :checked="validateStatus == 1" @change="handleChangeValidateStatus" checked-children="" un-checked-children="" size="small" /> <a-switch :checked="validateStatus == 1" @change="handleChangeValidateStatus" checked-children="" un-checked-children="" />
</span> </span>
</div> </div>
<!--上传--> <!--上传-->
<a-upload name="file" accept=".xls,.xlsx" :multiple="true" :fileList="fileList" :remove="handleRemove" :beforeUpload="beforeUpload"> <a-upload name="file" accept=".xls,.xlsx" :multiple="true" :fileList="fileList" @remove="handleRemove" :beforeUpload="beforeUpload">
<a-button preIcon="ant-design:upload-outlined">选择导入文件</a-button> <a-button preIcon="ant-design:upload-outlined">选择导入文件</a-button>
</a-upload> </a-upload>
<!--页脚--> <!--页脚-->
@ -81,7 +81,10 @@
// //
function handleClose() { function handleClose() {
closeModal() && reset(); // update-begin--author:liaozhiyang---date:20231226---forQQYUN-7477
closeModal();
reset();
// update-end--author:liaozhiyang---date:20231226---forQQYUN-7477
} }
// //
@ -139,6 +142,8 @@
} else { } else {
createMessage.warning(res.message); createMessage.warning(res.message);
} }
}).catch(() => {
uploading.value = false;
}); });
} }

View File

@ -1,7 +1,7 @@
<template> <template>
<a-popover <a-popover
trigger="contextmenu" trigger="contextmenu"
v-model:visible="visible" v-model:open="visible"
:overlayClassName="`${prefixCls}-popover`" :overlayClassName="`${prefixCls}-popover`"
:getPopupContainer="getPopupContainer" :getPopupContainer="getPopupContainer"
:placement="position" :placement="position"
@ -80,7 +80,7 @@
// //
function getPopupContainer(node) { function getPopupContainer(node) {
if (!props.popContainer) { if (!props.popContainer) {
return node.parentNode; return node?.parentNode;
} else if (typeof props.popContainer === 'function') { } else if (typeof props.popContainer === 'function') {
return props.popContainer(node); return props.popContainer(node);
} else { } else {

View File

@ -115,7 +115,10 @@
//popup //popup
let values = {}; let values = {};
for (let item of fieldConfig) { for (let item of fieldConfig) {
let val = rows.map((row) => row[item.source]).join(','); let val = rows.map((row) => row[item.source]);
// update-begin--author:liaozhiyang---date:20230831---forQQYUN-7535numberjoinstring
val = val.length == 1 ? val[0] : val.join(',');
// update-begin--author:liaozhiyang---date:20230831---forQQYUN-7535numberjoinstring
item.target.split(',').forEach((target) => { item.target.split(',').forEach((target) => {
values[target] = val; values[target] = val;
}); });

View File

@ -63,7 +63,7 @@
pageSize: propTypes.number.def(10), pageSize: propTypes.number.def(10),
getPopupContainer: { getPopupContainer: {
type: Function, type: Function,
default: (node) => node.parentNode, default: (node) => node?.parentNode,
}, },
//YSelect //YSelect
//update-begin-author:liusq date:2023-04-04 for:[issue/286] //update-begin-author:liusq date:2023-04-04 for:[issue/286]
@ -288,7 +288,7 @@
if (typeof props.getPopupContainer === 'function') { if (typeof props.getPopupContainer === 'function') {
return props.getPopupContainer(node); return props.getPopupContainer(node);
} else { } else {
return node.parentNode; return node?.parentNode;
} }
} }
// update-end-author:taoyan date:20220407 for: getPopupContainer popContainer // update-end-author:taoyan date:20220407 for: getPopupContainer popContainer

View File

@ -118,7 +118,7 @@
function getParentContainer(node) { function getParentContainer(node) {
if (!props.popContainer) { if (!props.popContainer) {
return node.parentNode; return node?.parentNode;
} else { } else {
return document.querySelector(props.popContainer); return document.querySelector(props.popContainer);
} }

View File

@ -41,12 +41,14 @@
() => props.value, () => props.value,
(val) => { (val) => {
if (!props.query) { if (!props.query) {
if (!val) { // update-begin--author:liaozhiyang---date:20231226---forQQYUN-7473options使[0,1]
if (!val && !props.options.includes(val)) {
checked.value = false; checked.value = false;
emitValue(props.options[1]); emitValue(props.options[1]);
} else { } else {
checked.value = props.options[0] == val; checked.value = props.options[0] == val;
} }
// update-end--author:liaozhiyang---date:20231226---forQQYUN-7473options使[0,1]
} }
}, },
{ immediate: true } { immediate: true }

View File

@ -3,7 +3,7 @@
allowClear allowClear
labelInValue labelInValue
style="width: 100%" style="width: 100%"
:getPopupContainer="(node) => node.parentNode" :getPopupContainer="(node) => node?.parentNode"
:dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }" :dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }"
:placeholder="placeholder" :placeholder="placeholder"
:loadData="asyncLoadTreeData" :loadData="asyncLoadTreeData"

View File

@ -1,7 +1,7 @@
<!--部门选择框--> <!--部门选择框-->
<template> <template>
<div> <div>
<BasicModal v-bind="$attrs" @register="register" :title="modalTitle" width="500px" @ok="handleOk" destroyOnClose @visible-change="visibleChange"> <BasicModal v-bind="$attrs" @register="register" :title="modalTitle" width="500px" :maxHeight="maxHeight" @ok="handleOk" destroyOnClose @visible-change="visibleChange">
<BasicTree <BasicTree
ref="treeRef" ref="treeRef"
:treeData="treeData" :treeData="treeData"
@ -55,6 +55,12 @@
type: String, type: String,
default: '部门选择', default: '部门选择',
}, },
// update-begin--author:liaozhiyang---date:20231220---forQQYUN-7678
maxHeight: {
type: Number,
default: 500,
},
// update-end--author:liaozhiyang---date:20231220---forQQYUN-7678
value: propTypes.oneOfType([propTypes.string, propTypes.array]) value: propTypes.oneOfType([propTypes.string, propTypes.array])
}, },
emits: ['register', 'getSelectResult'], emits: ['register', 'getSelectResult'],

View File

@ -5,7 +5,7 @@
v-bind="$attrs" v-bind="$attrs"
@register="register" @register="register"
:title="modalTitle" :title="modalTitle"
width="900px" width="1100px"
wrapClassName="j-user-select-modal" wrapClassName="j-user-select-modal"
@ok="handleOk" @ok="handleOk"
destroyOnClose destroyOnClose
@ -90,7 +90,7 @@
//form //form
const formConfig = { const formConfig = {
labelCol: { labelCol: {
span: 8, span: 4,
}, },
baseColProps: { baseColProps: {
xs: 24, xs: 24,

View File

@ -3,8 +3,9 @@
<template #renderItem="{ item }"> <template #renderItem="{ item }">
<a-list-item style="padding: 3px 0"> <a-list-item style="padding: 3px 0">
<div class="user-select-user-info" @click="(e) => onClickUser(e, item)"> <div class="user-select-user-info" @click="(e) => onClickUser(e, item)">
<div> <div style="margin-left: 10px">
<a-checkbox v-model:checked="checkStatus[item.id]" /> <a-checkbox v-model:checked="checkStatus[item.id]" v-if="multi" />
<a-radio v-model:checked="checkStatus[item.id]" v-else />
</div> </div>
<div> <div>
<a-avatar v-if="item.avatar" :src="getFileAccessHttpUrl(item.avatar)"></a-avatar> <a-avatar v-if="item.avatar" :src="getFileAccessHttpUrl(item.avatar)"></a-avatar>
@ -38,6 +39,10 @@
export default { export default {
name: 'UserList', name: 'UserList',
props: { props: {
multi: {
type: Boolean,
default: false,
},
dataList: { dataList: {
type: Array, type: Array,
default: () => [], default: () => [],

View File

@ -20,7 +20,7 @@
</a-col> </a-col>
<a-col :span="12" style="padding-left: 10px"> <a-col :span="12" style="padding-left: 10px">
<div :style="containerStyle"> <div :style="containerStyle">
<user-list :excludeUserIdList="excludeUserIdList" :dataList="userDataList" :selectedIdList="selectedIdList" @selected="onSelectUser" @unSelect="unSelectUser" /> <user-list :multi="multi" :excludeUserIdList="excludeUserIdList" :dataList="userDataList" :selectedIdList="selectedIdList" @selected="onSelectUser" @unSelect="unSelectUser" />
</div> </div>
</a-col> </a-col>
</a-row> </a-row>
@ -50,6 +50,10 @@
excludeUserIdList:{ excludeUserIdList:{
type: Array, type: Array,
default: () => [], default: () => [],
},
multi: {
type: Boolean,
default: false,
} }
}, },
emits: ['loaded', 'selected', 'unSelect'], emits: ['loaded', 'selected', 'unSelect'],

View File

@ -11,7 +11,7 @@
</a-col> </a-col>
<a-col :span="12" style="padding-left: 10px"> <a-col :span="12" style="padding-left: 10px">
<div :style="containerStyle"> <div :style="containerStyle">
<user-list :excludeUserIdList="excludeUserIdList" :dataList="userDataList" :selectedIdList="selectedIdList" @selected="onSelectUser" @unSelect="unSelectUser" /> <user-list :multi="multi" :excludeUserIdList="excludeUserIdList" :dataList="userDataList" :selectedIdList="selectedIdList" @selected="onSelectUser" @unSelect="unSelectUser" />
</div> </div>
</a-col> </a-col>
</a-row> </a-row>
@ -41,6 +41,10 @@
excludeUserIdList:{ excludeUserIdList:{
type: Array, type: Array,
default: () => [], default: () => [],
},
multi: {
type: Boolean,
default: false,
} }
}, },
emits: ['selected', 'unSelect'], emits: ['selected', 'unSelect'],

View File

@ -35,7 +35,7 @@
<a-tabs v-model:activeKey="myActiveKey" :centered="true" @change="onChangeTab"> <a-tabs v-model:activeKey="myActiveKey" :centered="true" @change="onChangeTab">
<!-- 所有用户 --> <!-- 所有用户 -->
<a-tab-pane key="1" tab="全部" forceRender> <a-tab-pane key="1" tab="全部" forceRender>
<user-list :excludeUserIdList="excludeUserIdList" :dataList="userDataList" :selectedIdList="selectedIdList" depart @selected="onSelectUser" @unSelect="unSelectUser" /> <user-list :multi="multi" :excludeUserIdList="excludeUserIdList" :dataList="userDataList" :selectedIdList="selectedIdList" depart @selected="onSelectUser" @unSelect="unSelectUser" />
</a-tab-pane> </a-tab-pane>
<!-- 部门用户 --> <!-- 部门用户 -->

View File

@ -31,7 +31,7 @@ export function useSelectBiz(getList, props) {
if (selectValues['change'] == false && !isEmpty(selectValues['value'])) { if (selectValues['change'] == false && !isEmpty(selectValues['value'])) {
//update-end-author:liusq---date:2023-10-19--for: [issues/788]判断有设置数值才去加载 //update-end-author:liusq---date:2023-10-19--for: [issues/788]判断有设置数值才去加载
//update-begin---author:wangshuai ---date:20220412 for[VUEN-672]发文草稿箱编辑时拟稿人显示用户名------------ //update-begin---author:wangshuai ---date:20220412 for[VUEN-672]发文草稿箱编辑时拟稿人显示用户名------------
let params = {}; let params = { isMultiTranslate: 'true' };
params[props.rowKey] = selectValues['value'].join(','); params[props.rowKey] = selectValues['value'].join(',');
//update-end---author:wangshuai ---date:20220412 for[VUEN-672]发文草稿箱编辑时拟稿人显示用户名-------------- //update-end---author:wangshuai ---date:20220412 for[VUEN-672]发文草稿箱编辑时拟稿人显示用户名--------------
loadingEcho.value = isFirstLoadEcho; loadingEcho.value = isFirstLoadEcho;

View File

@ -59,9 +59,9 @@ export interface FormProps {
// Submit form on reset // Submit form on reset
submitOnReset?: boolean; submitOnReset?: boolean;
// Col configuration for the entire form // Col configuration for the entire form
labelCol?: Partial<ColEx>; labelCol?: Partial<ColEx> | null;
// Col configuration for the entire form // Col configuration for the entire form
wrapperCol?: Partial<ColEx>; wrapperCol?: Partial<ColEx> | null;
// General row style // General row style
baseRowStyle?: CSSProperties; baseRowStyle?: CSSProperties;

View File

@ -113,6 +113,7 @@
theme: getDarkMode.value === 'dark' ? 'dark' : 'classic', theme: getDarkMode.value === 'dark' ? 'dark' : 'classic',
lang: unref(getCurrentLang), lang: unref(getCurrentLang),
mode: 'sv', mode: 'sv',
cdn: 'https://cdn.jsdelivr.net/npm/vditor@3.9.6',
fullscreen: { fullscreen: {
index: 520, index: 520,
}, },

View File

@ -27,6 +27,7 @@
:loading="getProps.loading" :loading="getProps.loading"
:loading-tip="getProps.loadingTip" :loading-tip="getProps.loadingTip"
:minHeight="getProps.minHeight" :minHeight="getProps.minHeight"
:maxHeight="getProps.maxHeight"
:height="getWrapperHeight" :height="getWrapperHeight"
:visible="visibleRef" :visible="visibleRef"
:modalFooterHeight="footer !== undefined && !footer ? 0 : undefined" :modalFooterHeight="footer !== undefined && !footer ? 0 : undefined"
@ -69,7 +70,7 @@
components: { Modal, ModalWrapper, ModalClose, ModalFooter, ModalHeader }, components: { Modal, ModalWrapper, ModalClose, ModalFooter, ModalHeader },
inheritAttrs: false, inheritAttrs: false,
props: basicProps, props: basicProps,
emits: ['visible-change', 'height-change', 'cancel', 'ok', 'register', 'update:visible', 'fullScreen'], emits: ['visible-change', 'open-change', 'height-change', 'cancel', 'ok', 'register', 'update:visible', 'update:open', 'fullScreen'],
setup(props, { emit, attrs , slots}) { setup(props, { emit, attrs , slots}) {
const visibleRef = ref(false); const visibleRef = ref(false);
const propsRef = ref<Partial<ModalProps> | null>(null); const propsRef = ref<Partial<ModalProps> | null>(null);
@ -131,16 +132,18 @@
}); });
const getBindValue = computed((): Recordable => { const getBindValue = computed((): Recordable => {
// update-begin--author:liaozhiyang---date:20231218---forQQYUN-6366antd4.x
const attr = { const attr = {
...attrs, ...attrs,
...unref(getMergeProps), ...unref(getMergeProps),
visible: unref(visibleRef), open: unref(visibleRef),
wrapClassName: unref(getWrapClassName), wrapClassName: unref(getWrapClassName),
}; };
if (unref(fullScreenRef)) { if (unref(fullScreenRef)) {
return omit(attr, ['height', 'title']); return omit(attr, ['height', 'title', 'visible']);
} }
return omit(attr, 'title'); return omit(attr, ['title', 'visible']);
// update-end--author:liaozhiyang---date:20231218---forQQYUN-6366antd4.x
}); });
const getWrapperHeight = computed(() => { const getWrapperHeight = computed(() => {
@ -156,11 +159,16 @@
visibleRef.value = !!props.visible; visibleRef.value = !!props.visible;
}); });
watchEffect(() => {
visibleRef.value = !!props.open;
});
watch( watch(
() => unref(visibleRef), () => unref(visibleRef),
(v) => { (v) => {
emit('visible-change', v); emit('visible-change', v);
emit('update:visible', v); emit('update:visible', v);
emit('update:open', v);
instance && modalMethods.emitVisible?.(v, instance.uid); instance && modalMethods.emitVisible?.(v, instance.uid);
nextTick(() => { nextTick(() => {
if (props.scrollTop && v && unref(modalWrapperRef)) { if (props.scrollTop && v && unref(modalWrapperRef)) {
@ -197,6 +205,9 @@
if (Reflect.has(props, 'visible')) { if (Reflect.has(props, 'visible')) {
visibleRef.value = !!props.visible; visibleRef.value = !!props.visible;
} }
if (Reflect.has(props, 'open')) {
visibleRef.value = !!props.open;
}
if (Reflect.has(props, 'defaultFullscreen')) { if (Reflect.has(props, 'defaultFullscreen')) {
fullScreenRef.value = !!props.defaultFullscreen; fullScreenRef.value = !!props.defaultFullscreen;
} }
@ -272,7 +283,9 @@
} }
.jeecg-modal-content{ .jeecg-modal-content{
>.scroll-container{ >.scroll-container{
padding: 14px; //update-begin---author:wangshuai---date:2023-12-05---for:QQYUN-7297---
padding: 6px;
//update-end---author:wangshuai---date:2023-12-05---for:QQYUN-7297---
} }
} }
/*update-end-author:taoyan date:2022-7-27 for:modal评论区域样式*/ /*update-end-author:taoyan date:2022-7-27 for:modal评论区域样式*/

View File

@ -4,17 +4,18 @@ import { basicProps } from '../props';
import { useModalDragMove } from '../hooks/useModalDrag'; import { useModalDragMove } from '../hooks/useModalDrag';
import { useAttrs } from '/@/hooks/core/useAttrs'; import { useAttrs } from '/@/hooks/core/useAttrs';
import { extendSlots } from '/@/utils/helper/tsxHelper'; import { extendSlots } from '/@/utils/helper/tsxHelper';
import { omit } from 'lodash-es';
export default defineComponent({ export default defineComponent({
name: 'Modal', name: 'Modal',
inheritAttrs: false, inheritAttrs: false,
props: basicProps, props: omit(basicProps, ['visible']),
emits: ['cancel'], emits: ['cancel'],
setup(props, { slots, emit }) { setup(props, { slots, emit }) {
const { visible, draggable, destroyOnClose } = toRefs(props); const { open, draggable, destroyOnClose } = toRefs(props);
const attrs = useAttrs(); const attrs = useAttrs();
useModalDragMove({ useModalDragMove({
visible, visible: open,
destroyOnClose, destroyOnClose,
draggable, draggable,
}); });

View File

@ -18,7 +18,8 @@
useWrapper: { type: Boolean, default: true }, useWrapper: { type: Boolean, default: true },
modalHeaderHeight: { type: Number, default: 57 }, modalHeaderHeight: { type: Number, default: 57 },
modalFooterHeight: { type: Number, default: 74 }, modalFooterHeight: { type: Number, default: 74 },
minHeight: { type: Number, default: 200 }, minHeight: { type: Number, default: null },
maxHeight: { type: Number, default: null },
height: { type: Number }, height: { type: Number },
footerOffset: { type: Number, default: 0 }, footerOffset: { type: Number, default: 0 },
visible: { type: Boolean }, visible: { type: Boolean },
@ -60,10 +61,34 @@
}); });
const spinStyle = computed((): CSSProperties => { const spinStyle = computed((): CSSProperties => {
// update-begin--author:liaozhiyang---date:20231205---forQQYUN-7147Model
if (props.fullScreen) {
return { return {
minHeight: `${props.minHeight}px`, height: `${unref(realHeightRef)}px`,
[props.fullScreen ? 'height' : 'maxHeight']: `${unref(realHeightRef)}px`,
}; };
} else {
const defaultMiniHeight = 200;
if (props.height != undefined) {
let height: number = props.height;
if (props.minHeight === null) {
return {
height: `${height}px`,
};
} else {
return {
height: `${props.minHeight > height ? props.minHeight : height}px`,
};
}
} else {
return {
minHeight: `${props.minHeight === null ? defaultMiniHeight : props.minHeight}px`,
// update-begin--author:liaozhiyang---date:20231219---forQQYUN-7641basicModalMaxHeight
maxHeight: `${props.maxHeight ? props.maxHeight : unref(realHeightRef)}px`,
// update-end--author:liaozhiyang---date:20231219---forQQYUN-7641basicModalMaxHeight
};
}
}
// update-end--author:liaozhiyang---date:20231205---forQQYUN-7147Model
}); });
watchEffect(() => { watchEffect(() => {

View File

@ -55,15 +55,19 @@ export function useModal(): UseModalReturnType {
getVisible: computed((): boolean => { getVisible: computed((): boolean => {
return visibleData[~~unref(uid)]; return visibleData[~~unref(uid)];
}), }),
getOpen: computed((): boolean => {
return visibleData[~~unref(uid)];
}),
redoModalHeight: () => { redoModalHeight: () => {
getInstance()?.redoModalHeight?.(); getInstance()?.redoModalHeight?.();
}, },
openModal: <T = any>(visible = true, data?: T, openOnSet = true): void => { openModal: <T = any>(visible = true, data?: T, openOnSet = true): void => {
// update-begin--author:liaozhiyang---date:20231218---for【QQYUN-6366】升级到antd4.x
getInstance()?.setModalProps({ getInstance()?.setModalProps({
visible: visible, open: visible,
}); });
// update-end--author:liaozhiyang---date:20231218---for【QQYUN-6366】升级到antd4.x
if (!data) return; if (!data) return;
const id = unref(uid); const id = unref(uid);
@ -79,7 +83,9 @@ export function useModal(): UseModalReturnType {
}, },
closeModal: () => { closeModal: () => {
getInstance()?.setModalProps({ visible: false }); // update-begin--author:liaozhiyang---date:20231218---for【QQYUN-6366】升级到antd4.x
getInstance()?.setModalProps({ open: false });
// update-end--author:liaozhiyang---date:20231218---for【QQYUN-6366】升级到antd4.x
}, },
}; };
return [register, methods]; return [register, methods];
@ -126,13 +132,15 @@ export const useModalInner = (callbackFn?: Fn): UseModalInnerReturnType => {
getVisible: computed((): boolean => { getVisible: computed((): boolean => {
return visibleData[~~unref(uidRef)]; return visibleData[~~unref(uidRef)];
}), }),
getOpen: computed((): boolean => {
return visibleData[~~unref(uidRef)];
}),
changeOkLoading: (loading = true) => { changeOkLoading: (loading = true) => {
getInstance()?.setModalProps({ confirmLoading: loading }); getInstance()?.setModalProps({ confirmLoading: loading });
}, },
closeModal: () => { closeModal: () => {
getInstance()?.setModalProps({ visible: false }); getInstance()?.setModalProps({ open: false });
}, },
setModalProps: (props: Partial<ModalProps>) => { setModalProps: (props: Partial<ModalProps>) => {

View File

@ -1,4 +1,4 @@
.fullscreen-modal { .ant-modal-root .fullscreen-modal {
overflow: hidden; overflow: hidden;
.ant-modal { .ant-modal {
@ -30,7 +30,7 @@
padding: 14px; padding: 14px;
} }
&-title { .ant-modal-title {
font-size: 16px; font-size: 16px;
font-weight: bold; font-weight: bold;
line-height: 16px; line-height: 16px;
@ -48,7 +48,7 @@
} }
} }
&-large { .ant-modal-large {
top: 60px; top: 60px;
&--mini { &--mini {
@ -56,34 +56,33 @@
} }
} }
&-header { .ant-modal-header {
padding: 16px; padding: 16px;
} }
&-content { .ant-modal-content {
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
} }
&-footer { .ant-modal-footer {
button + button { button + button {
margin-left: 10px; margin-left: 10px;
} }
} }
&-close { .ant-modal-close {
font-weight: normal; font-weight: normal;
outline: none; outline: none;
} }
&-close-x { .ant-modal-close-x {
display: inline-block; display: inline-block;
width: 96px; width: 96px;
/* width: auto;*/
height: 56px; height: 56px;
line-height: 56px; line-height: 56px;
} }
&-confirm-body { .ant-modal-confirm-body {
.ant-modal-confirm-content { .ant-modal-confirm-content {
// color: #fff; // color: #fff;
@ -93,23 +92,23 @@
} }
} }
&-confirm-confirm.error .ant-modal-confirm-body > .anticon { .ant-modal-confirm-confirm.error .ant-modal-confirm-body > .anticon {
color: @error-color; color: @error-color;
} }
&-confirm-btns { .ant-modal-confirm-btns {
.ant-btn:last-child { .ant-btn:last-child {
margin-right: 0; margin-right: 0;
} }
} }
&-confirm-info { .ant-modal-confirm-info {
.ant-modal-confirm-body > .anticon { .ant-modal-confirm-body > .anticon {
color: @warning-color; color: @warning-color;
} }
} }
&-confirm-confirm.success { .ant-modal-confirm-confirm.success {
.ant-modal-confirm-body > .anticon { .ant-modal-confirm-body > .anticon {
color: @success-color; color: @success-color;
} }

View File

@ -75,12 +75,14 @@ export const basicProps = Object.assign({}, modalProps, {
visible: { type: Boolean }, visible: { type: Boolean },
open: { type: Boolean },
width: [String, Number] as PropType<string | number>, width: [String, Number] as PropType<string | number>,
wrapClassName: { type: String }, wrapClassName: { type: String },
zIndex: { type: Number }, zIndex: { type: Number },
maxHeight: { type: Number },
// 是否开启评论区域 // 是否开启评论区域
enableComment: { type: Boolean, default: false }, enableComment: { type: Boolean, default: false },
}); });

View File

@ -15,6 +15,7 @@ export interface ReturnMethods extends ModalMethods {
openModal: <T = any>(props?: boolean, data?: T, openOnSet?: boolean) => void; openModal: <T = any>(props?: boolean, data?: T, openOnSet?: boolean) => void;
closeModal: () => void; closeModal: () => void;
getVisible?: ComputedRef<boolean>; getVisible?: ComputedRef<boolean>;
getOpen?: ComputedRef<boolean>;
} }
export type UseModalReturnType = [RegisterFn, ReturnMethods]; export type UseModalReturnType = [RegisterFn, ReturnMethods];
@ -24,6 +25,7 @@ export interface ReturnInnerMethods extends ModalMethods {
changeLoading: (loading: boolean) => void; changeLoading: (loading: boolean) => void;
changeOkLoading: (loading: boolean) => void; changeOkLoading: (loading: boolean) => void;
getVisible?: ComputedRef<boolean>; getVisible?: ComputedRef<boolean>;
getOpen?: ComputedRef<boolean>;
redoModalHeight: () => void; redoModalHeight: () => void;
} }
@ -41,6 +43,7 @@ export interface ModalProps {
canFullscreen?: boolean; canFullscreen?: boolean;
defaultFullscreen?: boolean; defaultFullscreen?: boolean;
visible?: boolean; visible?: boolean;
open?: boolean;
// 温馨提醒信息 // 温馨提醒信息
helpMessage: string | string[]; helpMessage: string | string[];

View File

@ -16,8 +16,8 @@
placement="right" placement="right"
:overlayClassName="`${prefixCls}-menu-popover`" :overlayClassName="`${prefixCls}-menu-popover`"
v-else v-else
:visible="getIsOpend" :open="getIsOpend"
@visibleChange="handleVisibleChange" @openChange="handleVisibleChange"
:overlayStyle="getOverlayStyle" :overlayStyle="getOverlayStyle"
:align="{ offset: [0, 0] }" :align="{ offset: [0, 0] }"
> >

View File

@ -268,7 +268,7 @@
.@{menu-prefix-cls}-submenu-active { .@{menu-prefix-cls}-submenu-active {
position: relative; position: relative;
color: #fff !important; color: #fff !important;
background-color: @sider-dark-darken-bg-color !important; background-color: @primary-color !important;
&::before { &::before {
position: absolute; position: absolute;

View File

@ -48,7 +48,7 @@
<script lang="ts"> <script lang="ts">
import type { BasicTableProps, TableActionType, SizeType, ColumnChangeParam, BasicColumn } from './types/table'; import type { BasicTableProps, TableActionType, SizeType, ColumnChangeParam, BasicColumn } from './types/table';
import { defineComponent, ref, computed, unref, toRaw, inject, watchEffect, watch, onUnmounted, onMounted } from 'vue'; import { defineComponent, ref, computed, unref, toRaw, inject, watchEffect, watch, onUnmounted, onMounted, nextTick } from 'vue';
import { Table } from 'ant-design-vue'; import { Table } from 'ant-design-vue';
import { BasicForm, useForm } from '/@/components/Form/index'; import { BasicForm, useForm } from '/@/components/Form/index';
import { PageWrapperFixedHeightKey } from '/@/components/Page/injectionKey'; import { PageWrapperFixedHeightKey } from '/@/components/Page/injectionKey';
@ -370,7 +370,11 @@
return { native, custom }; return { native, custom };
}); });
// update-end--author:sunjianlei---date:220230718---forissues/179slots // update-end--author:sunjianlei---date:220230718---forissues/179slots
// update-begin--author:liaozhiyang---date:20231226---forissues/945BasicTable
nextTick(() => {
getProps.value.defaultExpandAllRows && expandAll();
})
// update-end--author:sunjianlei---date:20231226---forissues/945BasicTable
expose(tableAction); expose(tableAction);
emit('register', tableAction, formActions); emit('register', tableAction, formActions);
@ -421,8 +425,8 @@
.@{prefix-cls} { .@{prefix-cls} {
// //
.alert { .alert {
background-color: #323232; // background-color: #323232;
border-color: #424242; // border-color: #424242;
} }
} }
} }
@ -523,8 +527,8 @@
// //
.alert { .alert {
height: 38px; height: 38px;
background-color: #e6f7ff; // background-color: #e6f7ff;
border-color: #91d5ff; // border-color: #91d5ff;
} }
&--inset { &--inset {
.ant-table-wrapper { .ant-table-wrapper {

View File

@ -29,7 +29,16 @@
const { prefixCls } = useDesign('basic-table-header-cell'); const { prefixCls } = useDesign('basic-table-header-cell');
const getIsEdit = computed(() => !!props.column?.edit); const getIsEdit = computed(() => !!props.column?.edit);
const getTitle = computed(() => props.column?.customTitle || props.column?.title); const getTitle = computed(() => {
// update-begin--author:liaozhiyang---date:20231218---forQQYUN-6366antd4.x
const result = props.column?.customTitle || props.column?.title;
if (typeof result === 'string') {
return result;
} else {
return '';
}
// update-end--author:liaozhiyang---date:20231218---forQQYUN-6366antd4.x
});
const getHelpMessage = computed(() => props.column?.helpMessage); const getHelpMessage = computed(() => props.column?.helpMessage);
return { prefixCls, getIsEdit, getTitle, getHelpMessage }; return { prefixCls, getIsEdit, getTitle, getHelpMessage };

View File

@ -14,7 +14,7 @@
<slot name="toolbar"></slot> <slot name="toolbar"></slot>
<Divider type="vertical" v-if="$slots.toolbar && showTableSetting" /> <Divider type="vertical" v-if="$slots.toolbar && showTableSetting" />
<TableSetting :class="`${prefixCls}__toolbar-desktop`" style="white-space: nowrap;" :setting="tableSetting" v-if="showTableSetting" @columns-change="handleColumnChange" /> <TableSetting :class="`${prefixCls}__toolbar-desktop`" style="white-space: nowrap;" :setting="tableSetting" v-if="showTableSetting" @columns-change="handleColumnChange" />
<a-popover :overlayClassName="`${prefixCls}__toolbar-mobile`" trigger="click" placement="left" :getPopupContainer="(n) => n.parentElement"> <a-popover :overlayClassName="`${prefixCls}__toolbar-mobile`" trigger="click" placement="left" :getPopupContainer="(n) => n?.parentElement">
<template #content> <template #content>
<TableSetting mode="mobile" :setting="tableSetting" v-if="showTableSetting" @columns-change="handleColumnChange" /> <TableSetting mode="mobile" :setting="tableSetting" v-if="showTableSetting" @columns-change="handleColumnChange" />
</template> </template>

View File

@ -27,7 +27,7 @@ export const CellComponent: FunctionalComponent = (
Popover, Popover,
{ {
overlayClassName: 'edit-cell-rule-popover', overlayClassName: 'edit-cell-rule-popover',
visible: !!popoverVisible, open: !!popoverVisible,
...(getPopupContainer ? { getPopupContainer } : {}), ...(getPopupContainer ? { getPopupContainer } : {}),
}, },
{ {

View File

@ -4,10 +4,10 @@
<span>{{ t('component.table.settingColumn') }}</span> <span>{{ t('component.table.settingColumn') }}</span>
</template> </template>
<Popover <Popover
v-model:visible="popoverVisible" v-model:open="popoverVisible"
placement="bottomLeft" placement="bottomLeft"
trigger="click" trigger="click"
@visible-change="handleVisibleChange" @open-change="handleVisibleChange"
:overlayClassName="`${prefixCls}__cloumn-list`" :overlayClassName="`${prefixCls}__cloumn-list`"
:getPopupContainer="getPopupContainer" :getPopupContainer="getPopupContainer"
> >
@ -174,7 +174,7 @@
const getBindProps = computed(() => { const getBindProps = computed(() => {
let obj = {}; let obj = {};
if (props.isMobile) { if (props.isMobile) {
obj['visible'] = false; obj['open'] = false;
} }
return obj; return obj;
}); });

View File

@ -186,7 +186,7 @@ export function useColumns(
return reactive(column); return reactive(column);
}); });
// update-begin--author:liaozhiyang---date:20230919---for【QQYUN-6387】展开写法去掉报错 // update-begin--author:liaozhiyang---date:20230919---for【QQYUN-6387】展开写法去掉报错
if (propsRef.value.expandedRowKeys) { if (propsRef.value.expandedRowKeys && !propsRef.value.isTreeTable) {
let index = 0; let index = 0;
const findIndex = result.findIndex((item) => item.key === CUS_SEL_COLUMN_KEY); const findIndex = result.findIndex((item) => item.key === CUS_SEL_COLUMN_KEY);
if (findIndex != -1) { if (findIndex != -1) {

View File

@ -77,7 +77,7 @@ export interface ColumnProps<T> {
* Whether filterDropdown is visible * Whether filterDropdown is visible
* @type boolean * @type boolean
*/ */
filterDropdownVisible?: boolean; filterDropdownOpen?: boolean;
/** /**
* Whether the dataSource is filtered * Whether the dataSource is filtered
@ -181,7 +181,7 @@ export interface ColumnProps<T> {
onFilter?: (value: any, record: T) => boolean; onFilter?: (value: any, record: T) => boolean;
/** /**
* Callback executed when filterDropdownVisible is changed, Use as a filterDropdownVisible event when using template or jsx * Callback executed when filterDropdownOpen is changed, Use as a filterDropdownVisible event when using template or jsx
* @type Function * @type Function
*/ */
onFilterDropdownVisibleChange?: (visible: boolean) => void; onFilterDropdownVisibleChange?: (visible: boolean) => void;

View File

@ -414,7 +414,7 @@ export interface BasicTableProps<T = any> {
export type CellFormat = string | ((text: string, record: Recordable, index: number) => string | number) | Map<string | number, any>; export type CellFormat = string | ((text: string, record: Recordable, index: number) => string | number) | Map<string | number, any>;
// @ts-ignore // @ts-ignore
export interface BasicColumn extends ColumnProps { export interface BasicColumn extends ColumnProps<Recordable> {
children?: BasicColumn[]; children?: BasicColumn[];
filters?: { filters?: {
text: string; text: string;

View File

@ -8,52 +8,28 @@
v-show="editorRef" v-show="editorRef"
:disabled="disabled" :disabled="disabled"
/> />
<textarea :id="tinymceId" ref="elRef" :style="{ visibility: 'hidden' }" v-if="!initOptions.inline"></textarea> <Editor :id="tinymceId" ref="elRef" :disabled="disabled" :init="initOptions" :style="{ visibility: 'hidden' }" v-if="!initOptions.inline"></Editor>
<slot v-else></slot> <slot v-else></slot>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import type { Editor, RawEditorSettings } from 'tinymce';
import tinymce from 'tinymce/tinymce'; import tinymce from 'tinymce/tinymce';
import Editor from '@tinymce/tinymce-vue'
import 'tinymce/themes/silver'; import 'tinymce/themes/silver';
import 'tinymce/icons/default/icons'; import 'tinymce/icons/default/icons';
import 'tinymce/plugins/advlist'; import 'tinymce/models/dom';
import 'tinymce/plugins/anchor';
import 'tinymce/plugins/autolink'; // tinymce
import 'tinymce/plugins/autosave'; // https://www.tiny.cloud/docs/plugins/
import 'tinymce/plugins/code';
import 'tinymce/plugins/codesample';
import 'tinymce/plugins/directionality';
import 'tinymce/plugins/fullscreen'; import 'tinymce/plugins/fullscreen';
import 'tinymce/plugins/hr';
import 'tinymce/plugins/insertdatetime';
import 'tinymce/plugins/link'; import 'tinymce/plugins/link';
import 'tinymce/plugins/lists'; import 'tinymce/plugins/lists';
import 'tinymce/plugins/media';
import 'tinymce/plugins/nonbreaking';
import 'tinymce/plugins/noneditable';
import 'tinymce/plugins/pagebreak';
import 'tinymce/plugins/paste';
import 'tinymce/plugins/preview'; import 'tinymce/plugins/preview';
import 'tinymce/plugins/print';
import 'tinymce/plugins/save';
import 'tinymce/plugins/searchreplace';
import 'tinymce/plugins/spellchecker';
import 'tinymce/plugins/tabfocus';
// import 'tinymce/plugins/table';
import 'tinymce/plugins/template';
import 'tinymce/plugins/textpattern';
import 'tinymce/plugins/visualblocks';
import 'tinymce/plugins/visualchars';
import 'tinymce/plugins/wordcount';
import 'tinymce/plugins/image'; import 'tinymce/plugins/image';
import 'tinymce/plugins/table';
import 'tinymce/plugins/textcolor';
import 'tinymce/plugins/contextmenu';
import { defineComponent, computed, nextTick, ref, unref, watch, onDeactivated, onBeforeUnmount } from 'vue'; import { defineComponent, computed, nextTick, ref, unref, watch, onDeactivated, onBeforeUnmount } from 'vue';
import ImgUpload from './ImgUpload.vue'; import ImgUpload from './ImgUpload.vue';
import { toolbar, plugins, simplePlugins, simpleToolbar, menubar } from './tinymce'; import {simpleToolbar, menubar, simplePlugins} from './tinymce';
import { buildShortUUID } from '/@/utils/uuid'; import { buildShortUUID } from '/@/utils/uuid';
import { bindHandlers } from './helper'; import { bindHandlers } from './helper';
import { onMountedOrActivated } from '/@/hooks/core/onMountedOrActivated'; import { onMountedOrActivated } from '/@/hooks/core/onMountedOrActivated';
@ -74,11 +50,11 @@
toolbar: { toolbar: {
type: [Array as PropType<string[]>, String], type: [Array as PropType<string[]>, String],
default: toolbar, default: simpleToolbar,
}, },
plugins: { plugins: {
type: Array as PropType<string[]>, type: [Array as PropType<string[]>, String],
default: plugins, default: simplePlugins,
}, },
menubar: { menubar: {
type: [Object, String], type: [Object, String],
@ -105,12 +81,14 @@
export default defineComponent({ export default defineComponent({
name: 'Tinymce', name: 'Tinymce',
components: { ImgUpload }, components: { ImgUpload,Editor },
inheritAttrs: false, inheritAttrs: false,
props: tinymceProps, props: tinymceProps,
emits: ['change', 'update:modelValue', 'inited', 'init-error'], emits: ['change', 'update:modelValue', 'inited', 'init-error'],
setup(props, { emit, attrs }) { setup(props, { emit, attrs }) {
const editorRef = ref<Nullable<Editor>>(null); console.log("---Tinymce---初始化---")
const editorRef = ref<Nullable<any>>(null);
const fullscreen = ref(false); const fullscreen = ref(false);
const tinymceId = ref<string>(buildShortUUID('tiny-vue')); const tinymceId = ref<string>(buildShortUUID('tiny-vue'));
const elRef = ref<Nullable<HTMLElement>>(null); const elRef = ref<Nullable<HTMLElement>>(null);
@ -138,14 +116,14 @@
return ['zh_CN', 'en'].includes(lang) ? lang : 'zh_CN'; return ['zh_CN', 'en'].includes(lang) ? lang : 'zh_CN';
}); });
const initOptions = computed((): RawEditorSettings => { const initOptions = computed(() => {
const { height, options, toolbar, plugins, menubar } = props; const { height, options, toolbar, plugins, menubar } = props;
const publicPath = import.meta.env.VITE_PUBLIC_PATH || '/'; const publicPath = import.meta.env.VITE_PUBLIC_PATH || '/';
return { return {
selector: `#${unref(tinymceId)}`, selector: `#${unref(tinymceId)}`,
height, height,
toolbar, toolbar,
menubar: menubar, menubar: false,
plugins, plugins,
language_url: publicPath + 'resource/tinymce/langs/' + langName.value + '.js', language_url: publicPath + 'resource/tinymce/langs/' + langName.value + '.js',
language: langName.value, language: langName.value,
@ -155,10 +133,11 @@
object_resizing: true, object_resizing: true,
toolbar_mode: 'sliding', toolbar_mode: 'sliding',
auto_focus: true, auto_focus: true,
toolbar_groups: true, // toolbar_groups: true,
skin: skinName.value, skin: skinName.value,
skin_url: publicPath + 'resource/tinymce/skins/ui/' + skinName.value, skin_url: publicPath + 'resource/tinymce/skins/ui/' + skinName.value,
images_upload_handler: (blobInfo, success) => { images_upload_handler: (blobInfo, process) =>
new Promise((resolve, reject) => {
let params = { let params = {
file: blobInfo.blob(), file: blobInfo.blob(),
filename: blobInfo.filename(), filename: blobInfo.filename(),
@ -168,18 +147,20 @@
if (res.success) { if (res.success) {
if (res.message == 'local') { if (res.message == 'local') {
const img = 'data:image/jpeg;base64,' + blobInfo.base64(); const img = 'data:image/jpeg;base64,' + blobInfo.base64();
success(img); resolve(img);
} else { } else {
let img = getFileAccessHttpUrl(res.message); let img = getFileAccessHttpUrl(res.message);
success(img); resolve(img);
} }
} else {
reject('上传失败!');
} }
}; };
uploadFile(params, uploadSuccess); uploadFile(params, uploadSuccess);
}, }),
content_css: publicPath + 'resource/tinymce/skins/ui/' + skinName.value + '/content.min.css', content_css: publicPath + 'resource/tinymce/skins/ui/' + skinName.value + '/content.min.css',
...options, ...options,
setup: (editor: Editor) => { setup: (editor: any) => {
editorRef.value = editor; editorRef.value = editor;
editor.on('init', (e) => initSetup(e)); editor.on('init', (e) => initSetup(e));
}, },
@ -191,7 +172,7 @@
const getdDisabled = options && Reflect.get(options, 'readonly'); const getdDisabled = options && Reflect.get(options, 'readonly');
const editor = unref(editorRef); const editor = unref(editorRef);
// update-begin-author:taoyan date:20220407 for: disabled // update-begin-author:taoyan date:20220407 for: disabled
if (editor) { if (editor && editor?.setMode) {
editor.setMode(getdDisabled || attrs.disabled === true ? 'readonly' : 'design'); editor.setMode(getdDisabled || attrs.disabled === true ? 'readonly' : 'design');
} }
if (attrs.disabled === true) { if (attrs.disabled === true) {
@ -208,7 +189,7 @@
if (!editor) { if (!editor) {
return; return;
} }
editor.setMode(attrs.disabled ? 'readonly' : 'design'); editor?.setMode && editor.setMode(attrs.disabled ? 'readonly' : 'design');
} }
); );
@ -239,7 +220,7 @@
function initEditor() { function initEditor() {
const el = unref(elRef); const el = unref(elRef);
if (el) { if (el && el?.style && el?.style?.visibility) {
el.style.visibility = ''; el.style.visibility = '';
} }
tinymce tinymce

View File

@ -62,7 +62,7 @@
let modalProps: Partial<ModalProps> = { let modalProps: Partial<ModalProps> = {
width: (opt.width ?? 500) as number, width: (opt.width ?? 500) as number,
title: (opt.title ?? 'prompt') as string, title: (opt.title ?? 'prompt') as string,
visible: unref(visible), open: unref(visible),
confirmLoading: unref(loading), confirmLoading: unref(loading),
}; };
let finalProps: Recordable = { let finalProps: Recordable = {

View File

@ -1,5 +1,5 @@
<template> <template>
<a-popover :visible="visible" :placement="placement" overlayClassName="j-vxe-popover-overlay" :overlayStyle="overlayStyle"> <a-popover :open="visible" :placement="placement" overlayClassName="j-vxe-popover-overlay" :overlayStyle="overlayStyle">
<template #title> <template #title>
<div class="j-vxe-popover-title"> <div class="j-vxe-popover-title">
<div>子表</div> <div>子表</div>

View File

@ -4,7 +4,7 @@
allowClear allowClear
:format="dateFormat" :format="dateFormat"
:showTime="isDatetime" :showTime="isDatetime"
dropdownClassName="j-vxe-date-picker" popupClassName="j-vxe-date-picker"
style="min-width: 0" style="min-width: 0"
v-model:open="openPicker" v-model:open="openPicker"
v-bind="cellProps" v-bind="cellProps"

View File

@ -3,12 +3,12 @@
:value="innerTimeValue" :value="innerTimeValue"
allowClear allowClear
:format="format" :format="format"
dropdownClassName="j-vxe-time-picker" popupClassName="j-vxe-time-picker"
style="min-width: 0" style="min-width: 0"
v-model:open="openPicker" v-model:open="openPicker"
v-bind="cellProps" v-bind="cellProps"
@change="handleChange" @change="handleChange"
:getPopupContainer="(node) => node.parentNode" :getPopupContainer="(node) => node?.parentNode"
/> />
</template> </template>

View File

@ -90,7 +90,8 @@ export const vxeProps = () => ({
keyboardEdit: propTypes.bool.def(false), keyboardEdit: propTypes.bool.def(false),
// update-begin--author:liaozhiyang---date:20231013---for【QQYUN-5133】JVxeTable 行编辑升级 // update-begin--author:liaozhiyang---date:20231013---for【QQYUN-5133】JVxeTable 行编辑升级
// 横向虚拟滚动配置(不支持展开行) // 横向虚拟滚动配置(不支持展开行)
scrollX: propTypes.object.def(() => ({ enabled: true })), // 【QQYUN-7676】x滚动条滚动时字典变成了id
scrollX: propTypes.object.def(() => ({ enabled: false })),
// 纵向虚拟滚动配置(不支持展开行) // 纵向虚拟滚动配置(不支持展开行)
scrollY: propTypes.object.def(() => ({ enabled: true })), scrollY: propTypes.object.def(() => ({ enabled: true })),
// update-end--author:liaozhiyang---date:20231013---for【QQYUN-5133】JVxeTable 行编辑升级 // update-end--author:liaozhiyang---date:20231013---for【QQYUN-5133】JVxeTable 行编辑升级

View File

@ -206,7 +206,13 @@ export function usePopBiz(ob, tableRef?) {
width: 60, width: 60,
align: 'center', align: 'center',
customRender: function ({ text }) { customRender: function ({ text }) {
// update-begin--author:liaozhiyang---date:20231226---for【QQYUN-7584】popup有合计时序号列会出现NaN
if (text == undefined) {
return '';
} else {
return parseInt(text) + 1; return parseInt(text) + 1;
}
// update-end--author:liaozhiyang---date:20231226---for【QQYUN-7584】popup有合计时序号列会出现NaN
}, },
}); });
} }
@ -777,7 +783,7 @@ export function usePopBiz(ob, tableRef?) {
title: '', title: '',
okText: '关闭', okText: '关闭',
width: '100%', width: '100%',
visible: false, open: false,
destroyOnClose: true, destroyOnClose: true,
style: dialogStyle, style: dialogStyle,
// dialogStyle: dialogStyle, // dialogStyle: dialogStyle,
@ -791,8 +797,8 @@ export function usePopBiz(ob, tableRef?) {
cancelButtonProps: { style: { display: 'none' } }, cancelButtonProps: { style: { display: 'none' } },
}, },
on: { on: {
ok: () => (hrefComponent.value.model.visible = false), ok: () => (hrefComponent.value.model.open = false),
cancel: () => (hrefComponent.value.model.visible = false), cancel: () => (hrefComponent.value.model.open = false),
}, },
is: <any>null, is: <any>null,
params: {}, params: {},
@ -816,7 +822,7 @@ export function usePopBiz(ob, tableRef?) {
} else { } else {
hrefComponent.value.params = {}; hrefComponent.value.params = {};
} }
hrefComponent.value.model.visible = true; hrefComponent.value.model.open = true;
hrefComponent.value.model.title = '操作'; hrefComponent.value.model.title = '操作';
hrefComponent.value.is = markRaw(defineAsyncComponent(() => importViewsFile(path))); hrefComponent.value.is = markRaw(defineAsyncComponent(() => importViewsFile(path)));
} }

View File

@ -15,7 +15,7 @@
<template v-if="item.toUserId"> <template v-if="item.toUserId">
<span>回复</span> <span>回复</span>
<span>{{ item.toUserId_dictText }}</span> <span>{{ item.toUserId_dictText }}</span>
<Tooltip class="comment-last-content" @visibleChange="(v)=>visibleChange(v, item)"> <Tooltip class="comment-last-content" @openChange="(v)=>visibleChange(v, item)">
<template #title> <template #title>
<div v-html="getHtml(item.commentId_dictText)"></div> <div v-html="getHtml(item.commentId_dictText)"></div>
</template> </template>
@ -320,7 +320,7 @@
.comment-last-content { .comment-last-content {
margin-left: 5px; margin-left: 5px;
&:hover{ &:hover{
color: #1890ff; color: @primary-color;
} }
} }
} }

View File

@ -25,7 +25,7 @@
<upload-chunk ref="uploadRef" :visible="uploadVisible" @select="selectFirstFile"></upload-chunk> <upload-chunk ref="uploadRef" :visible="uploadVisible" @select="selectFirstFile"></upload-chunk>
</div> </div>
<UserSelectModal labelKey="realname" rowKey="username" @register="registerModal" @getSelectResult="setValue" isRadioSelection></UserSelectModal> <UserSelectModal labelKey="realname" rowKey="username" @register="registerModal" @getSelectResult="setValue" isRadioSelection></UserSelectModal>
<a-modal v-model:visible="visibleEmoji" :footer="null" wrapClassName="emoji-modal" :closable="false" :width="490"> <a-modal v-model:open="visibleEmoji" :footer="null" wrapClassName="emoji-modal" :closable="false" :width="490">
<template #title> <template #title>
<span></span> <span></span>
</template> </template>

View File

@ -2,7 +2,7 @@ import type { App } from 'vue';
import { Icon } from './Icon'; import { Icon } from './Icon';
import AIcon from '/@/components/jeecg/AIcon.vue'; import AIcon from '/@/components/jeecg/AIcon.vue';
//Tinymce富文本 //Tinymce富文本
import Editor from '/@/components/Tinymce/src/Editor.vue'; import Editor from '/@/components/Tinymce/src/Editor.vue'
import { Button, JUploadButton } from './Button'; import { Button, JUploadButton } from './Button';
@ -60,20 +60,16 @@ import {
} from 'ant-design-vue'; } from 'ant-design-vue';
const compList = [AntButton.Group, Icon, AIcon, JUploadButton]; const compList = [AntButton.Group, Icon, AIcon, JUploadButton];
//敲敲云—仪表盘设计器(拖拽设计)
import DragEngine from '@qiaoqiaoyun/drag-free';
import('@qiaoqiaoyun/drag-free/lib/index.css');
console.log('---初始化--- 全局注册仪表盘--------------');
export function registerGlobComp(app: App) { export function registerGlobComp(app: App) {
compList.forEach((comp) => { compList.forEach((comp) => {
app.component(comp.name || comp.displayName, comp); app.component(comp.name || comp.displayName, comp);
}); });
//仪表盘依赖Tinymce需要提前加载没办法按需加载了 //仪表盘依赖Tinymce需要提前加载没办法按需加载了
app.component(Editor.name, Editor); app.component(Editor.name, Editor);
app app.use(Select)
.use(Select)
.use(Alert) .use(Alert)
.use(Button) .use(Button)
.use(Breadcrumb) .use(Breadcrumb)
@ -118,9 +114,7 @@ export function registerGlobComp(app: App) {
.use(InputNumber) .use(InputNumber)
.use(Carousel) .use(Carousel)
.use(Popconfirm) .use(Popconfirm)
.use(DragEngine)
.use(Skeleton) .use(Skeleton)
.use(Cascader) .use(Cascader)
.use(Rate); .use(Rate);
console.log("注册antd组件完成");
} }

View File

@ -1,6 +1,6 @@
@import './pagination.less'; @import './pagination.less';
@import './input.less'; @import './input.less';
@import './btn.less'; //@import './btn.less';
// @import './table.less'; // @import './table.less';
// TODO beta.11 fix // TODO beta.11 fix
@ -13,11 +13,11 @@
display: unset; display: unset;
} }
} }
//update-begin---author:scott ---date:2023-08-28 for【QQYUN-6374】UnoCSS替代windicss导致应用样式问题-- //update-begin---author:scott ---date:2023-08-28 for<EFBFBD><EFBFBD><EFBFBD><EFBFBD>QQYUN-6374<37><34>UnoCSS<53><53><EFBFBD>windicss<73><73><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD>--
/*span.anticon:not(.app-iconify) { /*span.anticon:not(.app-iconify) {
vertical-align: 0.125em !important; vertical-align: 0.125em !important;
}*/ }*/
//update-end---author:scott ---date::2023-08-28 for【QQYUN-6374】UnoCSS替代windicss导致应用样式问题-- //update-end---author:scott ---date::2023-08-28 for<EFBFBD><EFBFBD><EFBFBD><EFBFBD>QQYUN-6374<37><34>UnoCSS<53><53><EFBFBD>windicss<73><73><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD>--
.ant-back-top { .ant-back-top {
right: 20px; right: 20px;
@ -64,3 +64,64 @@
border-top: 0 !important; border-top: 0 !important;
border-left: 0 !important; border-left: 0 !important;
} }
// update-begin--author:liaozhiyang---date:20231218---for【QQYUN-6366】升级到antd4.x
.ant-modal {
.ant-modal-close {
position: absolute;
top: 0;
right: 0;
width: auto;
height: auto;
}
.ant-modal-content {
padding: 0;
}
}
.ant-input-affix-wrapper > input.ant-input {
font-size: 14px;
}
.ant-pagination-options-size-changer.ant-select {
display: inline-block;
width: auto;
}
.ant-tree-select-dropdown .ant-select-tree .ant-select-tree-list-holder-inner {
align-items: stretch;
}
.ant-list .ant-list-item {padding-left: 0;padding-right: 0;}
.ant-list-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px 0;
color: #000000d9;
}
/** anticon-down跟3.x保持一致*/
.ant-dropdown-trigger>.anticon.anticon-down, .ant-dropdown-link>.anticon.anticon-down, .ant-dropdown-button>.anticon.anticon-down {
font-size: 10px;
vertical-align: baseline;
}
/** 表格排序箭头尺寸保持跟3.x一致 */
.ant-table-wrapper .ant-table-column-sorter-up, .ant-table-wrapper .ant-table-column-sorter-down {
font-size: 11px;
}
/** 表格头部文字颜色跟3.x版本保持一致 */
.ant-table-wrapper .ant-table-thead >tr>th, .ant-table-wrapper .ant-table-thead >tr>td {
color: #000000d9;
font-weight: 500;
}
html[data-theme='dark'] .ant-table-wrapper .ant-table-thead >tr>th, .ant-table-wrapper .ant-table-thead >tr>td {
color:rgba(255,255,255,.65);
}
/** 下拉菜单文字和图标折叠了 */
.ant-dropdown .ant-dropdown-menu .ant-dropdown-menu-title-content, .ant-dropdown-menu-submenu .ant-dropdown-menu .ant-dropdown-menu-title-content{
flex: auto;
white-space:nowrap;
}
// update-end--author:liaozhiyang---date:20231218---for【QQYUN-6366】升级到antd4.x

View File

@ -22,6 +22,8 @@ html,
body { body {
width: 100%; width: 100%;
height: 100%; height: 100%;
// body添加行高保持跟3.x一致
line-height: 1.5715;
&.color-weak { &.color-weak {
filter: invert(80%); filter: invert(80%);
@ -82,3 +84,8 @@ img, video {
} }
// update-end--author:liaozhiyang---date:20231013---for【QQYUN-5133】升级之后提示样式跟之前一致 // update-end--author:liaozhiyang---date:20231013---for【QQYUN-5133】升级之后提示样式跟之前一致
// update-begin--author:liaozhiyang---date:20231116---for【QQYUN-7011】online表单多了一个蓝色的边框
// .vxe-table.vxe-table--render-default .vxe-body--column.col--selected {
// box-shadow: none;
// }
// update-end--author:liaozhiyang---date:20231116---for【QQYUN-7011】online表单多了一个蓝色的边框

View File

@ -1,6 +1,6 @@
<template> <template>
<div :class="prefixCls"> <div :class="prefixCls">
<Popover v-model:visible="popoverVisible" title="" trigger="click" :overlayClassName="`${prefixCls}__overlay`"> <Popover v-model:open="popoverVisible" title="" trigger="click" :overlayClassName="`${prefixCls}__overlay`">
<Badge :count="count" :overflowCount="9" :offset="[-4, 10]" :numberStyle="numberStyle"> <Badge :count="count" :overflowCount="9" :offset="[-4, 10]" :numberStyle="numberStyle">
<BellOutlined /> <BellOutlined />
</Badge> </Badge>

View File

@ -236,6 +236,9 @@
} }
&-dropdown-overlay { &-dropdown-overlay {
// update-begin--author:liaozhiyang---date:20231226---forQQYUN-7512
width: 160px;
// update-end--author:liaozhiyang---date:20231226---forQQYUN-7512
.ant-dropdown-menu-item { .ant-dropdown-menu-item {
min-width: 160px; min-width: 160px;
} }

View File

@ -219,9 +219,10 @@
// //
@prefix-cls: ~'@{namespace}-layout-header'; @prefix-cls: ~'@{namespace}-layout-header';
.@{prefix-cls} { .ant-layout .@{prefix-cls} {
display: flex; display: flex;
padding: 0 8px; padding: 0 8px;
height: 48px;
align-items: center; align-items: center;
.headerIntroductionClass { .headerIntroductionClass {
@ -241,7 +242,7 @@
.headerIntroductionClass { .headerIntroductionClass {
color: rgba(255, 255, 255, 0.6); color: rgba(255, 255, 255, 0.6);
} }
.anticon { .anticon, .truncate {
color: rgba(255, 255, 255, 0.8); color: rgba(255, 255, 255, 0.8);
} }
} }

View File

@ -48,4 +48,9 @@
width: 126px; width: 126px;
} }
} }
html[data-theme='dark'] {
.@{prefix-cls} {
color: rgba(255, 255, 255, 0.8);
}
}
</style> </style>

View File

@ -65,4 +65,9 @@
width: 126px; width: 126px;
} }
} }
html[data-theme='dark'] {
.@{prefix-cls} {
color: rgba(255, 255, 255, 0.8);
}
}
</style> </style>

View File

@ -63,4 +63,9 @@
justify-content: space-between; justify-content: space-between;
margin: 16px 0; margin: 16px 0;
} }
html[data-theme='dark'] {
.@{prefix-cls} {
color: rgba(255, 255, 255, 0.8);
}
}
</style> </style>

View File

@ -62,7 +62,9 @@
flex-wrap: wrap; flex-wrap: wrap;
margin: 16px 0; margin: 16px 0;
justify-content: space-around; justify-content: space-around;
// update-begin--author:liaozhiyang---date:20231220---forQQYUN-7677antd4
line-height: 1.3;
// update-end--author:liaozhiyang---date:20231220---forQQYUN-7677antd4
&__item { &__item {
width: 20px; width: 20px;
height: 20px; height: 20px;

View File

@ -125,7 +125,7 @@
z-index: @layout-sider-fixed-z-index; z-index: @layout-sider-fixed-z-index;
&--fixed { &--fixed {
position: fixed; position: fixed !important;
top: 0; top: 0;
left: 0; left: 0;
height: 100%; height: 100%;

View File

@ -5,7 +5,7 @@
:class="prefixCls" :class="prefixCls"
:width="getMenuWidth" :width="getMenuWidth"
:getContainer="null" :getContainer="null"
:visible="!getCollapsed" :open="!getCollapsed"
@close="handleClose" @close="handleClose"
> >
<Sider /> <Sider />

View File

@ -98,9 +98,7 @@ html[data-theme='light'] {
.ant-tabs-tab:not(.ant-tabs-tab-active) { .ant-tabs-tab:not(.ant-tabs-tab-active) {
&:hover { &:hover {
background-color: #ecf5ff;
color: @primary-color; color: @primary-color;
border-color: #b3d8ff;
} }
} }

View File

@ -145,3 +145,11 @@
@import './tabs.theme.card.less'; @import './tabs.theme.card.less';
@import './tabs.theme.smooth.less'; @import './tabs.theme.smooth.less';
</style> </style>
<style lang="less" scoped>
@prefix-cls: ~'@{namespace}-multiple-tabs';
.@{prefix-cls} {
:deep(.anticon) {
display: inline-block;
}
}
</style>

View File

@ -2,8 +2,14 @@ import { getThemeColors, generateColors } from '../../../build/config/themeConfi
import { replaceStyleVariables } from '@rys-fe/vite-plugin-theme/es/client'; import { replaceStyleVariables } from '@rys-fe/vite-plugin-theme/es/client';
import { mixLighten, mixDarken, tinycolor } from '@rys-fe/vite-plugin-theme/es/colorUtils'; import { mixLighten, mixDarken, tinycolor } from '@rys-fe/vite-plugin-theme/es/colorUtils';
import { useAppStore } from '/@/store/modules/app';
export async function changeTheme(color: string) { export async function changeTheme(color: string) {
// update-begin--author:liaozhiyang---date:20231218---for【QQYUN-6366】升级到antd4.x
const appStore = useAppStore();
appStore.setProjectConfig({ themeColor: color });
// update-end--author:liaozhiyang---date:20231218---for【QQYUN-6366】升级到antd4.x
const colors = generateColors({ const colors = generateColors({
mixDarken, mixDarken,
mixLighten, mixLighten,

View File

@ -1,7 +1,9 @@
import 'uno.css'; import 'uno.css';
import '/@/design/index.less'; import '/@/design/index.less';
import 'ant-design-vue/dist/reset.css';
// 注册图标 // 注册图标
import 'virtual:svg-icons-register'; import 'virtual:svg-icons-register';
import App from './App.vue'; import App from './App.vue';
import { createApp } from 'vue'; import { createApp } from 'vue';
import { initAppConfigStore } from '/@/logics/initAppConfig'; import { initAppConfigStore } from '/@/logics/initAppConfig';
@ -17,11 +19,6 @@ import { useSso } from '/@/hooks/web/useSso';
// 注册online模块lib // 注册online模块lib
import { registerPackages } from '/@/utils/monorepo/registerPackages'; import { registerPackages } from '/@/utils/monorepo/registerPackages';
// 在本地开发中引入的,以提高浏览器响应速度
if (import.meta.env.DEV) {
// @ts-ignore
import('ant-design-vue/dist/antd.less');
}
async function bootstrap() { async function bootstrap() {
// 创建应用实例 // 创建应用实例
const app = createApp(App); const app = createApp(App);

View File

@ -39,6 +39,7 @@ export const LoginRoute: AppRouteRecordRaw = {
}, },
}; };
//update-begin---author:wangshuai ---date:20220629 forauth2登录页面路由------------
export const Oauth2LoginRoute: AppRouteRecordRaw = { export const Oauth2LoginRoute: AppRouteRecordRaw = {
path: '/oauth2-app/login', path: '/oauth2-app/login',
name: 'oauth2-app-login', name: 'oauth2-app-login',
@ -49,6 +50,7 @@ export const Oauth2LoginRoute: AppRouteRecordRaw = {
title: t('routes.oauth2.login'), title: t('routes.oauth2.login'),
}, },
}; };
//update-end---author:wangshuai ---date:20220629 forauth2登录页面路由------------
/** /**
* token * token

View File

@ -466,14 +466,6 @@ const comp: AppRouteModule = {
title: t('routes.demo.feat.copy'), title: t('routes.demo.feat.copy'),
}, },
}, },
{
path: 'codemirror',
name: 'codemirrorDemo',
component: () => import('/@/views/demo/codemirror/index.vue'),
meta: {
title: t('routes.demo.feat.codemirror'),
},
},
{ {
path: 'ripple', path: 'ripple',
name: 'RippleDemo', name: 'RippleDemo',

View File

@ -2,7 +2,7 @@
export const GITHUB_URL = 'https://github.com/jeecgboot/jeecg-boot'; export const GITHUB_URL = 'https://github.com/jeecgboot/jeecg-boot';
// vue-Jeecg-admin-next-doc // vue-Jeecg-admin-next-doc
export const DOC_URL = 'http://help.jeecg.com'; export const DOC_URL = 'https://help.jeecg.com';
// site url // site url
export const SITE_URL = 'http://www.jeecg.com'; export const SITE_URL = 'http://www.jeecg.com';

View File

@ -488,9 +488,15 @@ export async function userExitChangeLoginTenantId(tenantId){
} }
} }
} }
let loginTenantId = getTenantId();
userStore.setTenant(currentTenantId); userStore.setTenant(currentTenantId);
//切换租户后要刷新首页
//update-begin---author:wangshuai---date:2023-11-07---for:【QQYUN-7005】退租户判断退出的租户ID与当前租户ID一致再刷新---
//租户为空,说明没有租户了,需要刷新页面。或者当前租户和退出的租户一致则需要刷新浏览器
if(!currentTenantId || tenantId == loginTenantId){
window.location.reload(); window.location.reload();
}
//update-end---author:wangshuai---date:2023-11-07---for:【QQYUN-7005】退租户判断退出的租户ID与当前租户ID一致再刷新---
} }
/** /**

View File

@ -245,6 +245,7 @@ function createAxios(opt?: Partial<CreateAxiosOptions>) {
// authentication schemese.g: Bearer // authentication schemese.g: Bearer
// authenticationScheme: 'Bearer', // authenticationScheme: 'Bearer',
authenticationScheme: '', authenticationScheme: '',
//接口超时设置
timeout: 10 * 1000, timeout: 10 * 1000,
// 基础接口地址 // 基础接口地址
// baseURL: globSetting.apiUrl, // baseURL: globSetting.apiUrl,

View File

@ -0,0 +1,81 @@
<!-- 标题与字段布局 -->
<template>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" @submit="handleSubmit" style="margin: 20px auto"/>
</template>
<script lang="ts" setup>
//
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
//
const formSchemas: FormSchema[] = [
{
label: '姓名',
field: 'name',
component: 'Input',
},
{
label: '年龄',
field: 'password',
component: 'InputNumber',
},
{
label: '生日',
field: 'birthday',
component: 'DatePicker',
},
{
label: '头像',
field: 'avatar',
component: 'JImageUpload',
},
];
/**
* BasicForm绑定注册;
*/
const [registerForm] = useForm({
//
schemas: formSchemas,
showActionButtonGroup: false,
actionColOptions: { span: 12 },
//
labelCol: {
xs: 2,
sm: 2,
md: 2,
lg: 9,
xl: 3,
xxl: 2,
},
//
wrapperCol: {
xs: 15,
sm: 14,
md: 16,
lg: 17,
xl: 19,
xxl: 20,
},
});
/**
* 点击提交按钮的value值
* @param values
*/
function handleSubmit(values: any) {
console.log('提交按钮数据::::', values);
}
</script>
<style scoped>
/** 时间和数字输入框样式 */
:deep(.ant-input-number) {
width: 100%;
}
:deep(.ant-picker) {
width: 100%;
}
</style>

View File

@ -0,0 +1,70 @@
<!-- 固定label标题的宽度 -->
<template>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" @submit="handleSubmit" style="margin-top: 20px" />
</template>
<script lang="ts" setup>
//
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
//
const formSchemas: FormSchema[] = [
{
label: '姓名',
field: 'name',
component: 'Input',
},
{
label: '年龄',
field: 'password',
component: 'InputNumber',
},
{
label: '生日',
field: 'birthday',
component: 'DatePicker',
},
{
label: '头像',
field: 'avatar',
component: 'JImageUpload',
},
];
/**
* BasicForm绑定注册;
*/
const [registerForm] = useForm({
//
schemas: formSchemas,
showResetButton: false,
submitButtonOptions: { text: '提交', preIcon: '' },
actionColOptions: { span: 17 },
//使labelWidth
labelWidth: '150px',
//使labelCol
labelCol: { style: { width: '150px' } },
//left:right
labelAlign: 'right',
});
/**
* 点击提交按钮的value值
* @param values
*/
function handleSubmit(values: any) {
console.log('提交按钮数据::::', values);
}
</script>
<style scoped>
/** 时间和数字输入框样式 */
:deep(.ant-input-number) {
width: 100%;
}
:deep(.ant-picker) {
width: 100%;
}
</style>

View File

@ -0,0 +1,143 @@
<!-- 动态增减表单 -->
<template>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" style="margin-top: 20px;" @submit="handleSubmit">
<!-- 添加input的插槽 -->
<template #addForm="{ field }">
<a-button v-if="Number(field) === 0" @click="addField" style="width: 50px">+</a-button>
<a-button v-if="Number(field) > 0" @click="delField(field)" style="width: 50px">-</a-button>
</template>
</BasicForm>
<!-- <div style="margin: 20px auto; text-align: center">
<a-button @click="addField"></a-button>
</div>-->
</template>
<script lang="ts" setup>
//
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
import { CollapseContainer } from '/@/components/Container';
import { ref } from '@vue/runtime-core';
//
const formSchemas: FormSchema[] = [
{
field: 'name1',
label: '姓名1',
component: 'Input',
// ifShow:false,
colProps: {
span: 8,
},
},
{
field: 'age1',
label: '年龄1',
component: 'InputNumber',
// ifShow:false,
colProps: {
span: 8,
},
},
{
field: '0',
component: 'Input',
// ifShow:false,
label: ' ',
colProps: {
span: 8,
},
slot: 'addForm',
},
];
/**
* BasicForm绑定注册;
* appendSchemaByField:增加表单项字段
*
* removeSchemaByFiled:减少表单项字段
*/
const [registerForm, { appendSchemaByField, removeSchemaByFiled }] = useForm({
schemas: formSchemas,
showResetButton: false,
labelWidth: '150px',
// showSubmitButton:false
submitButtonOptions: { text: '提交', preIcon: '' },
actionColOptions: { span: 17 },
});
//
let n = ref<number>(2);
/**
* 添加字段
* appendSchemaByField类型: ( schema: FormSchema, prefixField: string | undefined, first?: boolean | undefined ) => Promise<void>
* 说明: 插入到指定 filed 后面如果没传指定 field则插入到最后, first = true 时插入到第一个位置
*/
async function addField() {
//schemas
await appendSchemaByField(
{
field: `name${n.value}`,
component: 'Input',
label: '字段' + n.value,
colProps: {
span: 8,
},
},
''
);
await appendSchemaByField(
{
field: `sex${n.value}`,
component: 'InputNumber',
label: '字段' + n.value,
colProps: {
span: 8,
},
},
''
);
await appendSchemaByField(
{
field: `${n.value}`,
component: 'Input',
label: ' ',
colProps: {
span: 8,
},
slot: 'addForm',
},
''
);
n.value++;
}
/**
* 删除字段
* 类型: (field: string | string[]) => Promise<void>
* 说明: 根据 field 删除 Schema
* @param field 当前字段名称
*/
function delField(field) {
//
removeSchemaByFiled([`name${field}`, `sex${field}`, `${field}`]);
n.value--;
}
/**
* 点击提交按钮的value值
* @param values
*/
function handleSubmit(values: any) {
console.log('提交按钮数据::::', values);
}
</script>
<style scoped>
/** 数字输入框样式 */
:deep(.ant-input-number) {
width: 100%;
}
</style>

View File

@ -0,0 +1,66 @@
<!-- 操作按钮 -->
<template>
<div style="margin: 20px auto; text-align: center">
<!-- 通过setProps 可以设置 userForm 中的属性 -->
<!-- showActionButtonGroup 显示或者隐藏查询重置按钮 -->
<a-button @click="setProps({ showActionButtonGroup: false })" class="mr-2"> 隐藏操作按钮 </a-button>
<a-button @click="setProps({ showActionButtonGroup: true })" class="mr-2"> 显示操作按钮 </a-button>
<!-- showActionButtonGroup 显示或者隐藏重置按钮 -->
<a-button @click="setProps({ showResetButton: false })" class="mr-2"> 隐藏重置按钮 </a-button>
<a-button @click="setProps({ showResetButton: true })" class="mr-2"> 显示重置按钮 </a-button>
<!-- showActionButtonGroup 显示或者隐藏查询按钮 -->
<a-button @click="setProps({ showSubmitButton: false })" class="mr-2"> 隐藏查询按钮 </a-button>
<a-button @click="setProps({ showSubmitButton: true })" class="mr-2"> 显示查询按钮 </a-button>
</div>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" @submit="handleSubmit" style="margin-top: 50px; margin-left: 50px" />
</template>
<script lang="ts" setup>
//
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
import { CollapseContainer } from '/@/components/Container';
/**
* BasicForm绑定注册;
* setProps方法可以动态设置useForm中的属性
*/
const [registerForm, { setProps }] = useForm({
//
submitButtonOptions: { text: '查询', preIcon: '' },
//
resetButtonOptions: { text: '重置', preIcon: '' },
//
actionColOptions: { span: 17 },
//
submitFunc: customSubmitFunc,
//
resetFunc: customSubmitFunc,
//
showActionButtonGroup: true,
});
/**
* 查询按钮点击事件
*/
async function customSubmitFunc() {
console.log('查询按钮点击事件,此处处理查询按钮的逻辑');
}
/**
* 重置按钮点击事件
*/
async function customResetFunc() {
console.log('重置按钮点击事件,此处处理重置按钮的逻辑');
}
/**
* 点击提交按钮的value值
* @param values
*/
function handleSubmit(values: any) {
console.log('提交按钮数据::::', values);
}
</script>
<style scoped></style>

View File

@ -0,0 +1,95 @@
<!-- 操作禁用表单 -->
<template>
<div style="margin: 20px auto; text-align: center">
<!-- all 触发或清空所有验证visitor 只触发或者清空来访人员验证 -->
<a-button @click="triggerFormRule('all')" class="mr-2"> 触发表单验证 </a-button>
<a-button @click="cancelFormRule('all')" class="mr-2"> 清空表单验证 </a-button>
<a-button @click="triggerFormRule('visitor')" class="mr-2"> 只验证来访人员 </a-button>
<a-button @click="cancelFormRule('visitor')" class="mr-2"> 只清空来访人员验证 </a-button>
</div>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" style="margin-top: 20px;" />
</template>
<script lang="ts" setup>
//
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
//
const formSchemas: FormSchema[] = [
{
field: 'visitor',
label: '来访人员',
component: 'Input',
required: true,
},
{
field: 'accessed',
label: '来访日期',
component: 'DatePicker',
required: true,
},
{
field: 'phone',
label: '来访人手机号',
component: 'Input',
required: true,
},
];
/**
* BasicForm绑定注册;
* clearValidate 清除所有验证支持取消验证其中几个字段 clearValidate(['visitor',...])
* validate 验证所有,支持验证其中几个字段validate(['visitor',...])
* validateFields 只支持验证其中几个字段如validateFields(['visitor',...])
*/
const [registerForm, { clearValidate, validateFields, validate }] = useForm({
schemas: formSchemas,
labelWidth: '150px',
//
showActionButtonGroup: false,
//input
autoFocusFirstItem: true,
});
/**
* 触发表单验证
* @param type all 所有验证 visitor 只验证来访人员
*/
async function triggerFormRule(type) {
if (type == 'all') {
//
await validate();
} else {
//访
//visitor 访formSchemas field
await validateFields(['visitor']);
}
}
/**
* 触发表单验证
* @param type all 所有验证 visitor 只验证来访人员
*/
async function cancelFormRule(type) {
if (type == 'all') {
//
await clearValidate();
} else {
//访
//visitor 访formSchemas field
await clearValidate(['visitor']);
}
}
</script>
<style scoped>
/** 时间和数字输入框样式 */
:deep(.ant-input-number) {
width: 100%;
}
:deep(.ant-picker) {
width: 100%;
}
</style>

View File

@ -0,0 +1,58 @@
<!-- 操作禁用表单 -->
<template>
<div style="margin: 20px auto; text-align: center">
<!-- 通过setProps 可以设置 userForm 中的属性 -->
<!-- 表单大小默认为 default -->
<a-button @click="setProps({ size: 'large' })" class="mr-2"> 更改大小为最大 </a-button>
<a-button @click="setProps({ size: 'default' })" class="mr-2"> 还原大小 </a-button>
<a-button @click="setProps({ size: 'small' })" class="mr-2"> 更改大小为最小 </a-button>
<!-- disabled表单禁用 -->
<a-button @click="setProps({ disabled: true })" class="mr-2"> 禁用表单 </a-button>
<a-button @click="setProps({ disabled: false })" class="mr-2"> 解除禁用 </a-button>
<!-- compact 是否为紧凑表单 -->
<a-button @click="setProps({ compact: true })" class="mr-2"> 紧凑表单 </a-button>
<a-button @click="setProps({ compact: false })" class="mr-2"> 还原正常间距 </a-button>
</div>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" style="margin-top: 20px;" />
</template>
<script lang="ts" setup>
//
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
import { CollapseContainer } from '/@/components/Container';
//
const formSchemas: FormSchema[] = [
{
field: 'visitor',
label: '来访人员',
component: 'Input',
},
{
field: 'accessed',
label: '来访日期',
component: 'DatePicker',
},
{
field: 'phone',
label: '来访人手机号',
component: 'Input',
},
];
/**
* BasicForm绑定注册;
* setProps方法可以动态设置useForm中的属性
*/
const [registerForm, { setProps }] = useForm({
schemas: formSchemas,
labelWidth: '150px',
//
showActionButtonGroup: false,
//input
autoFocusFirstItem: true,
});
</script>
<style scoped></style>

View File

@ -0,0 +1,34 @@
<!-- 操作表单值 -->
<template>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" style="margin-top: 20px;" />
</template>
<script lang="ts" setup>
//
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
import { schemas } from './example.data';
/**
* BasicForm绑定注册;
*/
const [registerForm, { getFieldsValue, setFieldsValue, resetFields, validate }] = useForm({
schemas: schemas,
labelWidth: '150px',
//
showActionButtonGroup: false,
//input
autoFocusFirstItem: true,
});
</script>
<style scoped>
/** 时间和数字输入框样式 */
:deep(.ant-input-number) {
width: 100%;
}
:deep(.ant-picker) {
width: 100%;
}
</style>

View File

@ -0,0 +1,63 @@
<!-- 控件属性 -->
<template>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" style="margin-top: 20px" />
</template>
<script lang="ts" setup>
//
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
//
const formSchemas: FormSchema[] = [
{
label: '员工姓名',
field: 'name',
component: 'Input',
componentProps: {
disabled: true,
},
defaultValue: '张三',
},
{
label: '性别',
field: 'sex',
component: 'Select',
//
componentProps: {
options: [
{ label: '男', value: 1 },
{ label: '女', value: 2 },
{ label: '未知', value: 3 },
],
},
//
defaultValue: 3,
},
{
label: '年龄',
field: 'age',
component: 'Input',
},
{
label: '入职时间',
subLabel: '( 选填 )',
field: 'entryTime',
component: 'TimePicker',
},
];
/**
* BasicForm绑定注册;
*/
const [registerForm] = useForm({
//
schemas: formSchemas,
labelWidth: '150px',
showResetButton: false,
submitButtonOptions: { text: '提交', preIcon: '' },
actionColOptions: { span: 17 },
});
</script>
<style scoped></style>

View File

@ -0,0 +1,32 @@
<!-- 自定义组件 -->
<template>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" style="margin-top: 20px" />
</template>
<script lang="ts" setup>
//
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
//
const formSchemas: FormSchema[] = [
{
field: 'custom',
label: '自定义组件',
//
component: 'JInput',
},
];
/**
* BasicForm绑定注册;
*/
const [registerForm] = useForm({
//
schemas: formSchemas,
labelWidth: '150px',
showActionButtonGroup: false,
});
</script>
<style scoped></style>

View File

@ -0,0 +1,32 @@
<!-- 操作表单值 -->
<template>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" style="margin-top: 20px" />
</template>
<script lang="ts" setup>
//
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
import { schemas } from './exampleCustom.data';
/**
* BasicForm绑定注册;
*/
const [registerForm, { getFieldsValue, setFieldsValue, resetFields, validate }] = useForm({
schemas: schemas,
labelWidth: '150px',
//
showActionButtonGroup: false,
});
</script>
<style scoped>
/** 时间和数字输入框样式 */
:deep(.ant-input-number) {
width: 100%;
}
:deep(.ant-picker) {
width: 100%;
}
</style>

View File

@ -0,0 +1,64 @@
<!-- 插槽 -->
<template>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" style="margin-top: 20px" @submit="handleSubmit">
<!-- #name对应的是formSchemas对应slot(name)插槽 -->
<template #name="{ model, field }">
<JInput v-model:value="model[field]" />
</template>
</BasicForm>
</template>
<script lang="ts" setup>
//
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
//CustomDemo
import JInput from "/@/components/Form/src/jeecg/components/JInput.vue";
//
const formSchemas: FormSchema[] = [
{
field: 'name',
label: '姓名',
component: 'Input',
slot:'name'
},
{
field: 'phone',
label: '联系方式',
component: 'Input',
},
{
field: 'feedback',
label: '问题反馈',
component: 'InputTextArea',
},
];
/**
* BasicForm绑定注册;
*/
const [registerForm] = useForm({
//
schemas: formSchemas,
showResetButton: false,
labelWidth: '150px',
submitButtonOptions: { text: '提交', preIcon: '' },
actionColOptions: { span: 17 },
});
/**
* 提交信息
*/
function handleSubmit(values) {
console.log("values::",values);
}
</script>
<style scoped>
.font-color {
font-size: 13px;
color: #a1a1a1;
margin-bottom: 5px;
}
</style>

Some files were not shown because too many files have changed in this diff Show More