3.7.0大版本发布
							parent
							
								
									a9247d28a6
								
							
						
					
					
						commit
						894778a152
					
				
							
								
								
									
										4
									
								
								.env
								
								
								
								
							
							
						
						
									
										4
									
								
								.env
								
								
								
								
							| 
						 | 
				
			
			@ -4,8 +4,8 @@ VITE_PORT = 3100
 | 
			
		|||
#  网站标题
 | 
			
		||||
VITE_GLOB_APP_TITLE = JeecgBoot 企业级低代码平台
 | 
			
		||||
 | 
			
		||||
# 简称,用于配置文件名字 不要出现空格、数字开头等特殊字符
 | 
			
		||||
VITE_GLOB_APP_SHORT_NAME = JeecgBootAdmin
 | 
			
		||||
# 简称,此变量只能是字符/下划线
 | 
			
		||||
VITE_GLOB_APP_SHORT_NAME = JeecgBoot_Pro
 | 
			
		||||
 | 
			
		||||
# 单点登录服务端地址
 | 
			
		||||
VITE_GLOB_APP_CAS_BASE_URL=http://cas.test.com:8443/cas
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,11 +1,11 @@
 | 
			
		|||
JEECG BOOT 低代码开发平台(Vue3前端)
 | 
			
		||||
===============
 | 
			
		||||
当前最新版本: 3.6.3(发布时间:2024-03-11)
 | 
			
		||||
当前最新版本: 3.7.0(发布时间:2024-06-17)
 | 
			
		||||
 | 
			
		||||
[](https://github.com/zhangdaiscott/jeecg-boot/blob/master/LICENSE)
 | 
			
		||||
[](http://jeecg.com/aboutusIndex)
 | 
			
		||||
[](https://jeecg.blog.csdn.net)
 | 
			
		||||
[](https://github.com/zhangdaiscott/jeecg-boot)
 | 
			
		||||
[](https://github.com/zhangdaiscott/jeecg-boot)
 | 
			
		||||
[](https://github.com/zhangdaiscott/jeecg-boot)
 | 
			
		||||
[](https://github.com/zhangdaiscott/jeecg-boot)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,6 +30,8 @@ const demoList = (() => {
 | 
			
		|||
      avatar: Random.image('400x400', Random.color(), Random.color(), Random.first()),
 | 
			
		||||
      imgArr: getRandomPics(Math.ceil(Math.random() * 3) + 1),
 | 
			
		||||
      imgs: getRandomPics(Math.ceil(Math.random() * 3) + 1),
 | 
			
		||||
      age: Math.ceil(Math.random() * 30) + 1,
 | 
			
		||||
      score: Math.ceil(Math.random() * 80) + 1,
 | 
			
		||||
      date: `@date('yyyy-MM-dd')`,
 | 
			
		||||
      time: `@time('HH:mm')`,
 | 
			
		||||
      'no|100000-10000000': 100000,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										86
									
								
								package.json
								
								
								
								
							
							
						
						
									
										86
									
								
								package.json
								
								
								
								
							| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
{
 | 
			
		||||
  "name": "jeecgboot-vue3",
 | 
			
		||||
  "version": "3.6.3",
 | 
			
		||||
  "version": "3.7.0",
 | 
			
		||||
  "author": {
 | 
			
		||||
    "name": "北京国炬信息技术有限公司",
 | 
			
		||||
    "email": "jeecgos@163.com",
 | 
			
		||||
| 
						 | 
				
			
			@ -25,12 +25,12 @@
 | 
			
		|||
    "@iconify/iconify": "^3.1.1",
 | 
			
		||||
    "@ant-design/colors": "^7.0.2",
 | 
			
		||||
    "@ant-design/icons-vue": "^7.0.1",
 | 
			
		||||
    "@vue/shared": "^3.3.4",
 | 
			
		||||
    "@vueuse/core": "^10.7.1",
 | 
			
		||||
    "@tinymce/tinymce-vue": "^4.0.7",
 | 
			
		||||
    "@vue/shared": "^3.4.19",
 | 
			
		||||
    "@vueuse/core": "^10.8.0",
 | 
			
		||||
    "@tinymce/tinymce-vue": "4.0.7",
 | 
			
		||||
    "@zxcvbn-ts/core": "^3.0.4",
 | 
			
		||||
    "ant-design-vue": "^4.1.2",
 | 
			
		||||
    "axios": "^1.6.4",
 | 
			
		||||
    "axios": "^1.6.7",
 | 
			
		||||
    "china-area-data": "^5.0.1",
 | 
			
		||||
    "clipboard": "^2.0.11",
 | 
			
		||||
    "codemirror": "^5.65.3",
 | 
			
		||||
| 
						 | 
				
			
			@ -40,16 +40,16 @@
 | 
			
		|||
    "dayjs": "^1.11.10",
 | 
			
		||||
    "dom-align": "^1.12.4",
 | 
			
		||||
    "echarts": "^5.4.3",
 | 
			
		||||
    "emoji-mart-vue-fast": "^15.0.0",
 | 
			
		||||
    "emoji-mart-vue-fast": "^15.0.1",
 | 
			
		||||
    "enquire.js": "^2.1.6",
 | 
			
		||||
    "intro.js": "^7.2.0",
 | 
			
		||||
    "lodash-es": "^4.17.21",
 | 
			
		||||
    "lodash.get": "^4.4.2",
 | 
			
		||||
    "markdown-it": "^14.0.0",
 | 
			
		||||
    "markdown-it-link-attributes": "^4.0.1",
 | 
			
		||||
    "@traptitech/markdown-it-katex": "^3.6.0",
 | 
			
		||||
    "event-source-polyfill": "^1.0.31",
 | 
			
		||||
    "highlight.js": "^11.9.0",
 | 
			
		||||
    "@traptitech/markdown-it-katex": "^3.6.0",
 | 
			
		||||
    "md5": "^2.3.0",
 | 
			
		||||
    "mockjs": "^1.1.0",
 | 
			
		||||
    "nprogress": "^0.2.0",
 | 
			
		||||
| 
						 | 
				
			
			@ -60,49 +60,49 @@
 | 
			
		|||
    "qrcode": "^1.5.3",
 | 
			
		||||
    "resize-observer-polyfill": "^1.5.1",
 | 
			
		||||
    "showdown": "^2.1.0",
 | 
			
		||||
    "sortablejs": "^1.15.1",
 | 
			
		||||
    "tinymce": "^6.6.2",
 | 
			
		||||
    "vditor": "^3.9.8",
 | 
			
		||||
    "vue": "^3.4.15",
 | 
			
		||||
    "sortablejs": "^1.15.2",
 | 
			
		||||
    "tinymce": "6.6.2",
 | 
			
		||||
    "vditor": "^3.9.9",
 | 
			
		||||
    "vue": "^3.4.19",
 | 
			
		||||
    "vue-cropper": "^0.6.4",
 | 
			
		||||
    "vue-cropperjs": "^5.0.0",
 | 
			
		||||
    "vue-i18n": "^9.8.0",
 | 
			
		||||
    "vue-i18n": "^9.9.1",
 | 
			
		||||
    "vue-infinite-scroll": "^2.0.2",
 | 
			
		||||
    "vue-print-nb-jeecg": "^1.0.12",
 | 
			
		||||
    "vue-router": "^4.2.5",
 | 
			
		||||
    "vue-router": "^4.3.0",
 | 
			
		||||
    "vue-types": "^5.1.1",
 | 
			
		||||
    "vuedraggable": "^4.1.0",
 | 
			
		||||
    "vxe-table": "4.5.17",
 | 
			
		||||
    "vxe-table-plugin-antd": "3.1.0",
 | 
			
		||||
    "xe-utils": "3.5.14",
 | 
			
		||||
    "vxe-table": "4.6.14",
 | 
			
		||||
    "vxe-table-plugin-antd": "4.0.5",
 | 
			
		||||
    "xe-utils": "3.5.26",
 | 
			
		||||
    "xss": "^1.0.14"
 | 
			
		||||
  },
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "@commitlint/cli": "^18.4.3",
 | 
			
		||||
    "@commitlint/config-conventional": "^18.4.3",
 | 
			
		||||
    "@iconify/json": "^2.2.164",
 | 
			
		||||
    "@commitlint/cli": "^18.6.1",
 | 
			
		||||
    "@commitlint/config-conventional": "^18.6.2",
 | 
			
		||||
    "@iconify/json": "^2.2.185",
 | 
			
		||||
    "@purge-icons/generated": "^0.10.0",
 | 
			
		||||
    "@types/codemirror": "^5.60.15",
 | 
			
		||||
    "@types/crypto-js": "^4.2.1",
 | 
			
		||||
    "@types/crypto-js": "^4.2.2",
 | 
			
		||||
    "@types/fs-extra": "^11.0.4",
 | 
			
		||||
    "@types/inquirer": "^9.0.7",
 | 
			
		||||
    "@types/intro.js": "^5.1.5",
 | 
			
		||||
    "@types/jest": "^29.5.11",
 | 
			
		||||
    "@types/jest": "^29.5.12",
 | 
			
		||||
    "@types/lodash-es": "^4.17.12",
 | 
			
		||||
    "@types/mockjs": "^1.0.10",
 | 
			
		||||
    "@types/node": "^20.10.6",
 | 
			
		||||
    "@types/node": "^20.11.19",
 | 
			
		||||
    "@types/nprogress": "^0.2.3",
 | 
			
		||||
    "@types/qrcode": "^1.5.5",
 | 
			
		||||
    "@types/qs": "^6.9.11",
 | 
			
		||||
    "@types/showdown": "^2.0.6",
 | 
			
		||||
    "@types/sortablejs": "^1.15.7",
 | 
			
		||||
    "@types/sortablejs": "^1.15.8",
 | 
			
		||||
    "@typescript-eslint/eslint-plugin": "^6.17.0",
 | 
			
		||||
    "@typescript-eslint/parser": "^6.17.0",
 | 
			
		||||
    "@vitejs/plugin-vue": "^4.3.3",
 | 
			
		||||
    "@vitejs/plugin-vue-jsx": "^3.1.0",
 | 
			
		||||
    "@vue/compiler-sfc": "^3.4.4",
 | 
			
		||||
    "@vue/test-utils": "^2.4.3",
 | 
			
		||||
    "autoprefixer": "^10.4.16",
 | 
			
		||||
    "@vue/test-utils": "^2.4.4",
 | 
			
		||||
    "autoprefixer": "^10.4.17",
 | 
			
		||||
    "commitizen": "^4.3.0",
 | 
			
		||||
    "conventional-changelog-cli": "^4.1.0",
 | 
			
		||||
    "cross-env": "^7.0.3",
 | 
			
		||||
| 
						 | 
				
			
			@ -112,48 +112,50 @@
 | 
			
		|||
    "eslint": "^8.56.0",
 | 
			
		||||
    "eslint-config-prettier": "^9.1.0",
 | 
			
		||||
    "eslint-define-config": "^2.1.0",
 | 
			
		||||
    "eslint-plugin-jest": "^27.6.1",
 | 
			
		||||
    "eslint-plugin-prettier": "^5.1.2",
 | 
			
		||||
    "eslint-plugin-vue": "^9.19.2",
 | 
			
		||||
    "eslint-plugin-jest": "^27.9.0",
 | 
			
		||||
    "eslint-plugin-prettier": "^5.1.3",
 | 
			
		||||
    "eslint-plugin-vue": "^9.21.1",
 | 
			
		||||
    "esno": "^4.0.0",
 | 
			
		||||
    "fs-extra": "^11.2.0",
 | 
			
		||||
    "http-server": "^14.1.1",
 | 
			
		||||
    "husky": "^8.0.3",
 | 
			
		||||
    "inquirer": "^9.2.12",
 | 
			
		||||
    "inquirer": "^9.2.15",
 | 
			
		||||
    "is-ci": "^3.0.1",
 | 
			
		||||
    "jest": "^29.7.0",
 | 
			
		||||
    "less": "^4.2.0",
 | 
			
		||||
    "lint-staged": "15.2.0",
 | 
			
		||||
    "lint-staged": "15.2.2",
 | 
			
		||||
    "npm-run-all": "^4.1.5",
 | 
			
		||||
    "picocolors": "^1.0.0",
 | 
			
		||||
    "postcss": "^8.4.32",
 | 
			
		||||
    "postcss-html": "^1.5.0",
 | 
			
		||||
    "postcss": "^8.4.35",
 | 
			
		||||
    "postcss-html": "^1.6.0",
 | 
			
		||||
    "postcss-less": "^6.0.0",
 | 
			
		||||
    "prettier": "^3.1.1",
 | 
			
		||||
    "pretty-quick": "^3.1.3",
 | 
			
		||||
    "prettier": "^3.2.5",
 | 
			
		||||
    "pretty-quick": "^4.0.0",
 | 
			
		||||
    "rimraf": "^5.0.5",
 | 
			
		||||
    "rollup": "^4.9.2",
 | 
			
		||||
    "rollup": "^4.12.0",
 | 
			
		||||
    "rollup-plugin-visualizer": "^5.12.0",
 | 
			
		||||
    "stylelint": "^16.1.0",
 | 
			
		||||
    "stylelint": "^16.2.1",
 | 
			
		||||
    "stylelint-config-prettier": "^9.0.5",
 | 
			
		||||
    "stylelint-config-recommended": "^14.0.0",
 | 
			
		||||
    "stylelint-config-recommended-vue": "^1.5.0",
 | 
			
		||||
    "stylelint-config-standard": "^36.0.0",
 | 
			
		||||
    "stylelint-order": "^6.0.4",
 | 
			
		||||
    "ts-jest": "^29.1.1",
 | 
			
		||||
    "ts-jest": "^29.1.2",
 | 
			
		||||
    "ts-node": "^10.9.2",
 | 
			
		||||
    "typescript": "^4.9.5",
 | 
			
		||||
    "vite": "^4.4.9",
 | 
			
		||||
    "vite": "^5.2.11",
 | 
			
		||||
    "vite-plugin-compression": "^0.5.1",
 | 
			
		||||
    "vite-plugin-html": "^3.2.1",
 | 
			
		||||
    "vite-plugin-mkcert": "^1.17.1",
 | 
			
		||||
    "vite-plugin-html": "^3.2.2",
 | 
			
		||||
    "vite-plugin-mkcert": "^1.17.3",
 | 
			
		||||
    "vite-plugin-mock": "^2.9.6",
 | 
			
		||||
    "vite-plugin-optimize-persist": "^0.1.2",
 | 
			
		||||
    "vite-plugin-package-config": "^0.1.1",
 | 
			
		||||
    "vite-plugin-purge-icons": "^0.10.0",
 | 
			
		||||
    "vite-plugin-svg-icons": "^2.0.1",
 | 
			
		||||
    "@rys-fe/vite-plugin-theme": "^0.8.6",
 | 
			
		||||
    "vite-plugin-vue-setup-extend-plus": "^0.1.0",
 | 
			
		||||
    "unocss": "^0.58.3",
 | 
			
		||||
    "vue-eslint-parser": "^9.3.2",
 | 
			
		||||
    "unocss": "^0.58.5",
 | 
			
		||||
    "vue-eslint-parser": "^9.4.2",
 | 
			
		||||
    "vue-tsc": "^1.8.27"
 | 
			
		||||
  },
 | 
			
		||||
  "repository": {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										11451
									
								
								pnpm-lock.yaml
								
								
								
								
							
							
						
						
									
										11451
									
								
								pnpm-lock.yaml
								
								
								
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										25
									
								
								src/App.vue
								
								
								
								
							
							
						
						
									
										25
									
								
								src/App.vue
								
								
								
								
							| 
						 | 
				
			
			@ -25,6 +25,20 @@
 | 
			
		|||
  const { getAntdLocale } = useLocale();
 | 
			
		||||
 | 
			
		||||
  useTitle();
 | 
			
		||||
  /**
 | 
			
		||||
   * 2024-04-07
 | 
			
		||||
   * liaozhiyang
 | 
			
		||||
   * 暗黑模式下默认文字白色,白天模式默认文字 #333
 | 
			
		||||
   * */
 | 
			
		||||
  const modeAction = (data) => {
 | 
			
		||||
    if (data.token) {
 | 
			
		||||
      if (getDarkMode.value === ThemeEnum.DARK) {
 | 
			
		||||
        Object.assign(data.token, { colorTextBase: 'fff' });
 | 
			
		||||
      } else {
 | 
			
		||||
        Object.assign(data.token, { colorTextBase: '#333' });
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
  // update-begin--author:liaozhiyang---date:20231218---for:【QQYUN-6366】升级到antd4.x
 | 
			
		||||
  const appTheme: any = ref({});
 | 
			
		||||
  const { getDarkMode } = useRootSetting();
 | 
			
		||||
| 
						 | 
				
			
			@ -40,6 +54,7 @@
 | 
			
		|||
        changeTheme(appStore.getProjectConfig.themeColor);
 | 
			
		||||
      }
 | 
			
		||||
      // update-end--author:liaozhiyang---date:20240322---for:【QQYUN-8570】生产环境暗黑模式下主题色不生效
 | 
			
		||||
      modeAction(appTheme.value);
 | 
			
		||||
      appTheme.value = {
 | 
			
		||||
        ...appTheme.value,
 | 
			
		||||
      };
 | 
			
		||||
| 
						 | 
				
			
			@ -50,23 +65,28 @@
 | 
			
		|||
    appStore.getProjectConfig,
 | 
			
		||||
    (newValue) => {
 | 
			
		||||
      const primary = newValue.themeColor;
 | 
			
		||||
      appTheme.value = {
 | 
			
		||||
      const result = {
 | 
			
		||||
        ...appTheme.value,
 | 
			
		||||
        ...{
 | 
			
		||||
          token: {
 | 
			
		||||
            colorPrimary: primary,
 | 
			
		||||
            wireframe: true,
 | 
			
		||||
            fontSize: 14,
 | 
			
		||||
            colorTextBase: '#333',
 | 
			
		||||
            colorSuccess: '#55D187',
 | 
			
		||||
            colorInfo: primary,
 | 
			
		||||
            borderRadius: 2,
 | 
			
		||||
            borderRadius: 4,
 | 
			
		||||
            sizeStep: 4,
 | 
			
		||||
            sizeUnit: 4,
 | 
			
		||||
            colorWarning: '#EFBD47',
 | 
			
		||||
            colorError: '#ED6F6F',
 | 
			
		||||
            fontFamily:
 | 
			
		||||
              '-apple-system,BlinkMacSystemFont,Segoe UI,PingFang SC,Hiragino Sans GB,Microsoft YaHei,Helvetica Neue,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol',
 | 
			
		||||
          },
 | 
			
		||||
        },
 | 
			
		||||
      };
 | 
			
		||||
      appTheme.value = result;
 | 
			
		||||
      modeAction(result);
 | 
			
		||||
    },
 | 
			
		||||
    { immediate: true }
 | 
			
		||||
  );
 | 
			
		||||
| 
						 | 
				
			
			@ -74,6 +94,7 @@
 | 
			
		|||
    appStore.getProjectConfig?.themeColor && changeTheme(appStore.getProjectConfig.themeColor);
 | 
			
		||||
  }, 300);
 | 
			
		||||
  // update-end--author:liaozhiyang---date:20231218---for:【QQYUN-6366】升级到antd4.x
 | 
			
		||||
 | 
			
		||||
</script>
 | 
			
		||||
<style lang="less">
 | 
			
		||||
  // update-begin--author:liaozhiyang---date:20230803---for:【QQYUN-5839】windi会影响到html2canvas绘制的图片样式
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,7 @@ import { setAuthCache } from '/@/utils/auth';
 | 
			
		|||
import { TOKEN_KEY } from '/@/enums/cacheEnum';
 | 
			
		||||
import { router } from '/@/router';
 | 
			
		||||
import { PageEnum } from '/@/enums/pageEnum';
 | 
			
		||||
import { ExceptionEnum } from "@/enums/exceptionEnum";
 | 
			
		||||
 | 
			
		||||
const { createErrorModal } = useMessage();
 | 
			
		||||
enum Api {
 | 
			
		||||
| 
						 | 
				
			
			@ -123,8 +124,13 @@ export function getCaptcha(params) {
 | 
			
		|||
      if (res.success) {
 | 
			
		||||
        resolve(true);
 | 
			
		||||
      } else {
 | 
			
		||||
        createErrorModal({ title: '错误提示', content: res.message || '未知问题' });
 | 
			
		||||
        reject();
 | 
			
		||||
        //update-begin---author:wangshuai---date:2024-04-18---for:【QQYUN-9005】同一个IP,1分钟超过5次短信,则提示需要验证码---
 | 
			
		||||
        if(res.code != ExceptionEnum.PHONE_SMS_FAIL_CODE){
 | 
			
		||||
          createErrorModal({ title: '错误提示', content: res.message || '未知问题' });
 | 
			
		||||
          reject();
 | 
			
		||||
        }
 | 
			
		||||
        reject(res);
 | 
			
		||||
        //update-end---author:wangshuai---date:2024-04-18---for:【QQYUN-9005】同一个IP,1分钟超过5次短信,则提示需要验证码---
 | 
			
		||||
      }
 | 
			
		||||
    }).catch((res)=>{
 | 
			
		||||
      createErrorModal({ title: '错误提示', content: res.message || '未知问题' });
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1713356465646" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5683" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><path d="M320.067666 286.437731c53.150524-53.15564 126.532835-86.077447 207.455889-86.077447 89.598644 0 172.483376 40.805358 227.39501 108.063181l-101.596909 101.603049 251.597225 0L904.918881 158.424172l-90.333378 90.361007C743.985562 166.207439 639.765919 116.493178 527.524578 116.493178c-104.055914 0-198.409862 42.322921-266.757506 110.670565-49.444109 49.455365-84.98865 112.251573-100.999298 182.862771l86.263689 0C260.052804 362.352725 285.750069 320.744072 320.067666 286.437731L320.067666 286.437731z" fill="#272636" p-id="5684"></path><path d="M734.974327 701.344393c-53.151547 53.15564-126.533858 86.083587-207.450772 86.083587-89.599667 0-172.488493-40.810474-227.402173-108.069321l101.603049-101.596909L150.122089 577.76175 150.122089 829.358975l90.333378-90.333378c70.601988 82.555228 174.820608 132.270513 287.067065 132.270513 104.055914 0 198.402699-42.306548 266.750343-110.650099 49.360198-49.397037 84.866876-112.477724 100.920504-182.883237L808.689213 577.762773C794.560424 624.99654 768.983909 667.338904 734.974327 701.344393L734.974327 701.344393z" fill="#272636" p-id="5685"></path></svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 1.4 KiB  | 
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 3.4 KiB  | 
| 
						 | 
				
			
			@ -6,7 +6,7 @@
 | 
			
		|||
  <div class="anticon" :class="getAppLogoClass" @click="goHome">
 | 
			
		||||
    <img src="../../../assets/images/logo.png" />
 | 
			
		||||
    <div class="ml-2 truncate md:opacity-100" :class="getTitleClass" v-show="showTitle">
 | 
			
		||||
      {{ title }}
 | 
			
		||||
      {{ shortTitle }}
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
| 
						 | 
				
			
			@ -37,7 +37,8 @@
 | 
			
		|||
  const { prefixCls } = useDesign('app-logo');
 | 
			
		||||
  const { getCollapsedShowTitle } = useMenuSetting();
 | 
			
		||||
  const userStore = useUserStore();
 | 
			
		||||
  const { title } = useGlobSetting();
 | 
			
		||||
  const { title, shortTitle } = useGlobSetting();
 | 
			
		||||
  
 | 
			
		||||
  const go = useGo();
 | 
			
		||||
 | 
			
		||||
  const getAppLogoClass = computed(() => [prefixCls, props.theme, { 'collapsed-show-title': unref(getCollapsedShowTitle) }]);
 | 
			
		||||
| 
						 | 
				
			
			@ -83,8 +84,8 @@
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    &__title {
 | 
			
		||||
      font-size: 16px;
 | 
			
		||||
      font-weight: 700;
 | 
			
		||||
      font-size: 18px;
 | 
			
		||||
      font-weight: 600;
 | 
			
		||||
      transition: all 0.5s;
 | 
			
		||||
      line-height: normal;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,7 @@ import { useGo } from '/@/hooks/web/usePage';
 | 
			
		|||
import { useScrollTo } from '/@/hooks/event/useScrollTo';
 | 
			
		||||
import { onKeyStroke, useDebounceFn } from '@vueuse/core';
 | 
			
		||||
import { useI18n } from '/@/hooks/web/useI18n';
 | 
			
		||||
import { URL_HASH_TAB } from '/@/utils';
 | 
			
		||||
 | 
			
		||||
export interface SearchResult {
 | 
			
		||||
  name: string;
 | 
			
		||||
| 
						 | 
				
			
			@ -154,7 +155,10 @@ export function useMenuSearch(refs: Ref<HTMLElement[]>, scrollWrap: Ref<ElRef>,
 | 
			
		|||
 | 
			
		||||
    // update-begin--author:liaozhiyang---date:20230803---for:【QQYUN-8369】搜索区分大小写,外部链接新页打开
 | 
			
		||||
    if (to.internalOrExternal) {
 | 
			
		||||
      window.open(to.path, '_blank');
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20240402---for:【QQYUN-8773】配置外部网址在顶部菜单模式和搜索打不开
 | 
			
		||||
      const path = to.path.replace(URL_HASH_TAB, '#');
 | 
			
		||||
      window.open(path, '_blank');
 | 
			
		||||
      // update-end--author:liaozhiyang---date:20240402---for:【QQYUN-8773】配置外部网址在顶部菜单模式和搜索打不开
 | 
			
		||||
    } else {
 | 
			
		||||
      go(to.path);
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,6 +2,8 @@
 | 
			
		|||
  <Button v-bind="$attrs" :disabled="isStart" @click="handleStart" :loading="loading">
 | 
			
		||||
    {{ getButtonText }}
 | 
			
		||||
  </Button>
 | 
			
		||||
  <!-- 图片验证码弹窗 -->
 | 
			
		||||
  <CaptchaModal @register="captchaRegisterModal" @ok="handleStart" />
 | 
			
		||||
</template>
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
  import { defineComponent, ref, watchEffect, computed, unref } from 'vue';
 | 
			
		||||
| 
						 | 
				
			
			@ -9,6 +11,11 @@
 | 
			
		|||
  import { useCountdown } from './useCountdown';
 | 
			
		||||
  import { isFunction } from '/@/utils/is';
 | 
			
		||||
  import { useI18n } from '/@/hooks/web/useI18n';
 | 
			
		||||
  import { useModal } from "@/components/Modal";
 | 
			
		||||
  import { createAsyncComponent } from "@/utils/factory/createAsyncComponent";
 | 
			
		||||
  import { ExceptionEnum } from "@/enums/exceptionEnum";
 | 
			
		||||
  const CaptchaModal = createAsyncComponent(() => import('/@/components/jeecg/captcha/CaptchaModal.vue'));
 | 
			
		||||
  const [captchaRegisterModal, { openModal: openCaptchaModal }] = useModal();
 | 
			
		||||
 | 
			
		||||
  const props = {
 | 
			
		||||
    value: { type: [Object, Number, String, Array] },
 | 
			
		||||
| 
						 | 
				
			
			@ -21,7 +28,7 @@
 | 
			
		|||
 | 
			
		||||
  export default defineComponent({
 | 
			
		||||
    name: 'CountButton',
 | 
			
		||||
    components: { Button },
 | 
			
		||||
    components: { Button, CaptchaModal },
 | 
			
		||||
    props,
 | 
			
		||||
    setup(props) {
 | 
			
		||||
      const loading = ref(false);
 | 
			
		||||
| 
						 | 
				
			
			@ -45,7 +52,13 @@
 | 
			
		|||
        if (beforeStartFunc && isFunction(beforeStartFunc)) {
 | 
			
		||||
          loading.value = true;
 | 
			
		||||
          try {
 | 
			
		||||
            const canStart = await beforeStartFunc();
 | 
			
		||||
            //update-begin---author:wangshuai---date:2024-04-18---for:【QQYUN-9005】同一个IP,1分钟超过5次短信,则提示需要验证码---
 | 
			
		||||
            const canStart = await beforeStartFunc().catch((res) =>{
 | 
			
		||||
              if(res.code === ExceptionEnum.PHONE_SMS_FAIL_CODE){
 | 
			
		||||
                openCaptchaModal(true, {});
 | 
			
		||||
              }
 | 
			
		||||
            });
 | 
			
		||||
            //update-end---author:wangshuai---date:2024-04-18---for:【QQYUN-9005】同一个IP,1分钟超过5次短信,则提示需要验证码---
 | 
			
		||||
            canStart && start();
 | 
			
		||||
          } finally {
 | 
			
		||||
            loading.value = false;
 | 
			
		||||
| 
						 | 
				
			
			@ -54,7 +67,7 @@
 | 
			
		|||
          start();
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      return { handleStart, currentCount, loading, getButtonText, isStart };
 | 
			
		||||
      return { handleStart, currentCount, loading, getButtonText, isStart, captchaRegisterModal };
 | 
			
		||||
    },
 | 
			
		||||
  });
 | 
			
		||||
</script>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,6 +35,7 @@
 | 
			
		|||
  import { basicProps } from './props';
 | 
			
		||||
  import { useDesign } from '/@/hooks/web/useDesign';
 | 
			
		||||
  import { useAttrs } from '/@/hooks/core/useAttrs';
 | 
			
		||||
  import { cloneDeep } from 'lodash-es';
 | 
			
		||||
 | 
			
		||||
  export default defineComponent({
 | 
			
		||||
    components: { Drawer, ScrollContainer, DrawerFooter, DrawerHeader },
 | 
			
		||||
| 
						 | 
				
			
			@ -59,9 +60,9 @@
 | 
			
		|||
      instance && emit('register', drawerInstance, instance.uid);
 | 
			
		||||
 | 
			
		||||
      const getMergeProps = computed((): DrawerProps => {
 | 
			
		||||
        // update-begin--author:liaozhiyang---date:20240320---for:【QQYUN-8389】vue3.4以上版本导致角色抽屉隐藏footer逻辑错误(去掉toRow,否者props变化不会触发computed)
 | 
			
		||||
        return { ...deepMerge(props, unref(propsRef)) };
 | 
			
		||||
        // update-end--author:liaozhiyang---date:20240320---for:【QQYUN-8389】vue3.4以上版本导致角色抽屉隐藏footer逻辑错误(去掉toRow,否者props变化不会触发computed)
 | 
			
		||||
        // update-begin--author:liaozhiyang---date:20240320---for:【QQYUN-8389】vue3.4以上版本导致角色抽屉隐藏footer逻辑错误(toRaw改成cloneDeep,否则props的变化不会触发computed)
 | 
			
		||||
        return { ...deepMerge(cloneDeep(props), unref(propsRef)) };
 | 
			
		||||
        // update-end--author:liaozhiyang---date:20240320---for:【QQYUN-8389】vue3.4以上版本导致角色抽屉隐藏footer逻辑错误(toRaw改成cloneDeep,否则props的变化不会触发computed)
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      const getProps = computed((): DrawerProps => {
 | 
			
		||||
| 
						 | 
				
			
			@ -88,6 +89,7 @@
 | 
			
		|||
            opt.getContainer = `.${prefixVar}-layout-content` as any;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        console.log('getProps:opt',opt);
 | 
			
		||||
        return opt as DrawerProps;
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,6 +12,8 @@
 | 
			
		|||
          :formModel="formModel"
 | 
			
		||||
          :setFormModel="setFormModel"
 | 
			
		||||
          :validateFields="validateFields"
 | 
			
		||||
          :clearValidate="clearValidate"
 | 
			
		||||
          v-auth="schema.auth"
 | 
			
		||||
        >
 | 
			
		||||
          <template #[item]="data" v-for="item in Object.keys($slots)">
 | 
			
		||||
            <slot :name="item" v-bind="data || {}"></slot>
 | 
			
		||||
| 
						 | 
				
			
			@ -109,6 +111,7 @@
 | 
			
		|||
          prefixCls,
 | 
			
		||||
          {
 | 
			
		||||
            [`${prefixCls}--compact`]: unref(getProps).compact,
 | 
			
		||||
            'jeecg-form-detail-effect': unref(getProps).disabled
 | 
			
		||||
          },
 | 
			
		||||
        ];
 | 
			
		||||
      });
 | 
			
		||||
| 
						 | 
				
			
			@ -142,7 +145,10 @@
 | 
			
		|||
            if (!Array.isArray(defaultValue)) {
 | 
			
		||||
              //update-begin---author:wangshuai ---date:20221124  for:[issues/215]列表页查询框(日期选择框)设置初始时间,一进入页面时,后台报日期转换类型错误的------------
 | 
			
		||||
              if(valueFormat){
 | 
			
		||||
                schema.defaultValue = dateUtil(defaultValue).format(valueFormat);
 | 
			
		||||
                // schema.defaultValue = dateUtil(defaultValue).format(valueFormat);
 | 
			
		||||
                // update-begin--author:liaozhiyang---date:20240529---for:【TV360X-346 】时间组件填写默认值有问题
 | 
			
		||||
                schema.defaultValue = dateUtil(defaultValue, valueFormat).format(valueFormat);
 | 
			
		||||
                // update-end--author:liaozhiyang---date:20240529---for:【TV360X-346 】时间组件填写默认值有问题
 | 
			
		||||
              }else{
 | 
			
		||||
                schema.defaultValue = dateUtil(defaultValue);
 | 
			
		||||
              }
 | 
			
		||||
| 
						 | 
				
			
			@ -152,7 +158,9 @@
 | 
			
		|||
              defaultValue.forEach((item) => {
 | 
			
		||||
                //update-begin---author:wangshuai ---date:20221124  for:[issues/215]列表页查询框(日期选择框)设置初始时间,一进入页面时,后台报日期转换类型错误的------------
 | 
			
		||||
                if(valueFormat){
 | 
			
		||||
                  def.push(dateUtil(item).format(valueFormat));
 | 
			
		||||
                  // update-begin--author:liaozhiyang---date:20240529---for:【TV360X-346 】时间组件填写默认值有问题
 | 
			
		||||
                  def.push(dateUtil(item, valueFormat).format(valueFormat));
 | 
			
		||||
                  // update-end--author:liaozhiyang---date:20240529---for:【TV360X-346 】时间组件填写默认值有问题
 | 
			
		||||
                }else{
 | 
			
		||||
                  def.push(dateUtil(item));
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -346,10 +354,11 @@
 | 
			
		|||
      &-with-help {
 | 
			
		||||
        margin-bottom: 0;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      &:not(.ant-form-item-with-help) {
 | 
			
		||||
        margin-bottom: 20px;
 | 
			
		||||
      }
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20240514---for:【QQYUN-9241】form表单上下间距大点
 | 
			
		||||
      //&:not(.ant-form-item-with-help) {
 | 
			
		||||
      //  margin-bottom: 24px;
 | 
			
		||||
      //}
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20240514---for:【QQYUN-9241】form表单上下间距大点
 | 
			
		||||
 | 
			
		||||
      &.suffix-item {
 | 
			
		||||
        .ant-form-item-children {
 | 
			
		||||
| 
						 | 
				
			
			@ -370,7 +379,7 @@
 | 
			
		|||
      }
 | 
			
		||||
    }
 | 
			
		||||
    /*【美化表单】form的字体改小一号*/
 | 
			
		||||
    .ant-form-item-label > label{
 | 
			
		||||
/*    .ant-form-item-label > label{
 | 
			
		||||
      font-size: 13px;
 | 
			
		||||
    }
 | 
			
		||||
    .ant-form-item .ant-select {
 | 
			
		||||
| 
						 | 
				
			
			@ -384,7 +393,7 @@
 | 
			
		|||
    }
 | 
			
		||||
    .ant-input {
 | 
			
		||||
      font-size: 13px;
 | 
			
		||||
    }
 | 
			
		||||
    }*/
 | 
			
		||||
    /*【美化表单】form的字体改小一号*/
 | 
			
		||||
    
 | 
			
		||||
    .ant-form-explain {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -45,7 +45,7 @@ import JImageUpload from './jeecg/components/JImageUpload.vue';
 | 
			
		|||
import JDictSelectTag from './jeecg/components/JDictSelectTag.vue';
 | 
			
		||||
import JSelectDept from './jeecg/components/JSelectDept.vue';
 | 
			
		||||
import JAreaSelect from './jeecg/components/JAreaSelect.vue';
 | 
			
		||||
// import JEditor from './jeecg/components/JEditor.vue';
 | 
			
		||||
import JEditor from './jeecg/components/JEditor.vue';
 | 
			
		||||
// import JMarkdownEditor from './jeecg/components/JMarkdownEditor.vue';
 | 
			
		||||
import JSelectInput from './jeecg/components/JSelectInput.vue';
 | 
			
		||||
// import JCodeEditor from './jeecg/components/JCodeEditor.vue';
 | 
			
		||||
| 
						 | 
				
			
			@ -72,7 +72,9 @@ import JRangeNumber from './jeecg/components/JRangeNumber.vue';
 | 
			
		|||
import UserSelect from './jeecg/components/userSelect/index.vue';
 | 
			
		||||
import JRangeDate from './jeecg/components/JRangeDate.vue'
 | 
			
		||||
import JRangeTime from './jeecg/components/JRangeTime.vue'
 | 
			
		||||
import JInputSelect from './jeecg/components/JInputSelect.vue'
 | 
			
		||||
import RoleSelectInput from './jeecg/components/roleSelect/RoleSelectInput.vue';
 | 
			
		||||
import {DatePickerInFilter, CascaderPcaInFilter} from "@/components/InFilter";
 | 
			
		||||
 | 
			
		||||
const componentMap = new Map<ComponentType, Component>();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -104,6 +106,7 @@ componentMap.set('MonthPicker', DatePicker.MonthPicker);
 | 
			
		|||
componentMap.set('RangePicker', DatePicker.RangePicker);
 | 
			
		||||
componentMap.set('WeekPicker', DatePicker.WeekPicker);
 | 
			
		||||
componentMap.set('TimePicker', TimePicker);
 | 
			
		||||
componentMap.set('DatePickerInFilter', DatePickerInFilter);
 | 
			
		||||
componentMap.set('StrengthMeter', StrengthMeter);
 | 
			
		||||
componentMap.set('IconPicker', IconPicker);
 | 
			
		||||
componentMap.set('InputCountDown', CountdownInput);
 | 
			
		||||
| 
						 | 
				
			
			@ -112,6 +115,7 @@ componentMap.set('Upload', BasicUpload);
 | 
			
		|||
componentMap.set('Divider', Divider);
 | 
			
		||||
 | 
			
		||||
//注册自定义组件
 | 
			
		||||
 | 
			
		||||
componentMap.set(
 | 
			
		||||
  'JAreaLinkage',
 | 
			
		||||
  createAsyncComponent(() => import('./jeecg/components/JAreaLinkage.vue'))
 | 
			
		||||
| 
						 | 
				
			
			@ -123,10 +127,11 @@ componentMap.set('JImageUpload', JImageUpload);
 | 
			
		|||
componentMap.set('JDictSelectTag', JDictSelectTag);
 | 
			
		||||
componentMap.set('JSelectDept', JSelectDept);
 | 
			
		||||
componentMap.set('JAreaSelect', JAreaSelect);
 | 
			
		||||
componentMap.set(
 | 
			
		||||
  'JEditor',
 | 
			
		||||
  createAsyncComponent(() => import('./jeecg/components/JEditor.vue'))
 | 
			
		||||
);
 | 
			
		||||
// componentMap.set(
 | 
			
		||||
//   'JEditor',
 | 
			
		||||
//   createAsyncComponent(() => import('./jeecg/components/JEditor.vue'))
 | 
			
		||||
// );
 | 
			
		||||
componentMap.set('JEditor', JEditor);
 | 
			
		||||
componentMap.set(
 | 
			
		||||
  'JMarkdownEditor',
 | 
			
		||||
  createAsyncComponent(() => import('./jeecg/components/JMarkdownEditor.vue'))
 | 
			
		||||
| 
						 | 
				
			
			@ -158,10 +163,12 @@ componentMap.set('JUpload', JUpload);
 | 
			
		|||
componentMap.set('JSearchSelect', JSearchSelect);
 | 
			
		||||
componentMap.set('JAddInput', JAddInput);
 | 
			
		||||
componentMap.set('JRangeNumber', JRangeNumber);
 | 
			
		||||
componentMap.set('CascaderPcaInFilter', CascaderPcaInFilter);
 | 
			
		||||
componentMap.set('UserSelect', UserSelect);
 | 
			
		||||
componentMap.set('RangeDate', JRangeDate);
 | 
			
		||||
componentMap.set('RangeTime', JRangeTime);
 | 
			
		||||
componentMap.set('RoleSelect', RoleSelectInput);
 | 
			
		||||
componentMap.set('JInputSelect', JInputSelect);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,7 +16,8 @@
 | 
			
		|||
  import { useItemLabelWidth } from '../hooks/useLabelWidth';
 | 
			
		||||
  import { useI18n } from '/@/hooks/web/useI18n';
 | 
			
		||||
  import { useAppInject } from '/@/hooks/web/useAppInject';
 | 
			
		||||
 | 
			
		||||
  import { usePermission } from '/@/hooks/web/usePermission';
 | 
			
		||||
  import Middleware from './Middleware.vue';
 | 
			
		||||
  export default defineComponent({
 | 
			
		||||
    name: 'BasicFormItem',
 | 
			
		||||
    inheritAttrs: false,
 | 
			
		||||
| 
						 | 
				
			
			@ -51,6 +52,12 @@
 | 
			
		|||
      formActionType: {
 | 
			
		||||
        type: Object as PropType<FormActionType>,
 | 
			
		||||
      },
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20240605---for:【TV360X-857】解决禁用状态下触发校验
 | 
			
		||||
      clearValidate: {
 | 
			
		||||
        type: Function,
 | 
			
		||||
        default: null,
 | 
			
		||||
      },
 | 
			
		||||
      // update-end-author:liaozhiyang---date:20240605---for:【TV360X-857】解决禁用状态下触发校验
 | 
			
		||||
    },
 | 
			
		||||
    setup(props, { slots }) {
 | 
			
		||||
      const { t } = useI18n();
 | 
			
		||||
| 
						 | 
				
			
			@ -93,6 +100,11 @@
 | 
			
		|||
 | 
			
		||||
      const getDisable = computed(() => {
 | 
			
		||||
        const { disabled: globDisabled } = props.formProps;
 | 
			
		||||
        // update-begin--author:liaozhiyang---date:20240530---for:【TV360X-594】表单全局禁用则dynamicDisabled不生效
 | 
			
		||||
        if (!!globDisabled) {
 | 
			
		||||
          return globDisabled;
 | 
			
		||||
        }
 | 
			
		||||
        // update-end--author:liaozhiyang---date:20240530---for:【TV360X-594】表单全局禁用则dynamicDisabled不生效
 | 
			
		||||
        const { dynamicDisabled } = props.schema;
 | 
			
		||||
        const { disabled: itemDisabled = false } = unref(getComponentsProps);
 | 
			
		||||
        let disabled = !!globDisabled || itemDisabled;
 | 
			
		||||
| 
						 | 
				
			
			@ -144,12 +156,62 @@
 | 
			
		|||
        isShow = isShow && itemIsAdvanced;
 | 
			
		||||
        return { isShow, isIfShow };
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20240530---for:【TV360X-434】validator校验执行两次
 | 
			
		||||
      let vSwitchArr: any = [],
 | 
			
		||||
        prevValidatorArr: any = [];
 | 
			
		||||
      const hijackValidator = (rules) => {
 | 
			
		||||
        vSwitchArr = [];
 | 
			
		||||
        prevValidatorArr = [];
 | 
			
		||||
        rules.forEach((item, index) => {
 | 
			
		||||
          const fn = item.validator;
 | 
			
		||||
          vSwitchArr.push(true);
 | 
			
		||||
          prevValidatorArr.push(null);
 | 
			
		||||
          if (isFunction(fn)) {
 | 
			
		||||
            item.validator = (rule, value, callback) => {
 | 
			
		||||
              if (vSwitchArr[index]) {
 | 
			
		||||
                vSwitchArr[index] = false;
 | 
			
		||||
                setTimeout(() => {
 | 
			
		||||
                  vSwitchArr[index] = true;
 | 
			
		||||
                }, 100);
 | 
			
		||||
                const result = fn(rule, value, callback);
 | 
			
		||||
                prevValidatorArr[index] = result;
 | 
			
		||||
                return result;
 | 
			
		||||
              } else {
 | 
			
		||||
                return prevValidatorArr[index];
 | 
			
		||||
              }
 | 
			
		||||
            };
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
      };
 | 
			
		||||
      // update-end--author:liaozhiyang---date:20240530---for:【TV360X-434】validator校验执行两次
 | 
			
		||||
      function handleRules(): ValidationRule[] {
 | 
			
		||||
        const { rules: defRules = [], component, rulesMessageJoinLabel, label, dynamicRules, required } = props.schema;
 | 
			
		||||
 | 
			
		||||
        const { rules: defRules = [], component, rulesMessageJoinLabel, label, dynamicRules, required, auth, field } = props.schema;
 | 
			
		||||
        // update-begin--author:liaozhiyang---date:20240605---for:【TV360X-857】解决禁用状态下触发校验
 | 
			
		||||
        const { disabled: globDisabled } = props.formProps;
 | 
			
		||||
        const { disabled: itemDisabled = false } = unref(getComponentsProps);
 | 
			
		||||
        if (!!globDisabled || !!itemDisabled) {
 | 
			
		||||
          props.clearValidate(field);
 | 
			
		||||
          return [];
 | 
			
		||||
        }
 | 
			
		||||
        // update-end--author:liaozhiyang---date:20240605---for:【TV360X-857】解决禁用状态下触发校验
 | 
			
		||||
        // update-begin--author:liaozhiyang---date:20240531---for:【TV360X-842】必填项v-auth、show隐藏的情况下表单无法提交
 | 
			
		||||
        const { hasPermission } = usePermission();
 | 
			
		||||
        const { isShow } = getShow();
 | 
			
		||||
        if ((auth && !hasPermission(auth)) || !isShow) {
 | 
			
		||||
          return [];
 | 
			
		||||
        }
 | 
			
		||||
        // update-end--author:liaozhiyang---date:20240531---for:【TV360X-842】必填项v-auth、show隐藏的情况下表单无法提交
 | 
			
		||||
        if (isFunction(dynamicRules)) {
 | 
			
		||||
          return dynamicRules(unref(getValues)) as ValidationRule[];
 | 
			
		||||
          // update-begin--author:liaozhiyang---date:20240514---for:【issues/1244】标识了必填,但是必填标识没显示
 | 
			
		||||
          const ruleArr = dynamicRules(unref(getValues)) as ValidationRule[];
 | 
			
		||||
          if (required) {
 | 
			
		||||
            ruleArr.unshift({ required: true });
 | 
			
		||||
          }
 | 
			
		||||
          // update-begin--author:liaozhiyang---date:20240530---for:【TV360X-434】validator校验执行两次
 | 
			
		||||
          hijackValidator(ruleArr);
 | 
			
		||||
          // update-end--author:liaozhiyang---date:20240530---for:【TV360X-434】validator校验执行两次
 | 
			
		||||
          return ruleArr;
 | 
			
		||||
          // update-end--author:liaozhiyang---date:20240514---for:【issues/1244】标识了必填,但是必填标识没显示
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let rules: ValidationRule[] = cloneDeep(defRules) as ValidationRule[];
 | 
			
		||||
| 
						 | 
				
			
			@ -237,11 +299,14 @@
 | 
			
		|||
          }
 | 
			
		||||
        });
 | 
			
		||||
        // update-end--author:liaozhiyang---date:20231226---for:【QQYUN-7495】pattern由字符串改成正则传递给antd(因使用InputNumber时发现正则无效)
 | 
			
		||||
        // update-begin--author:liaozhiyang---date:20240530---for:【TV360X-434】validator校验执行两次
 | 
			
		||||
        hijackValidator(rules);
 | 
			
		||||
        // update-end--author:liaozhiyang---date:20240530---for:【TV360X-434】validator校验执行两次
 | 
			
		||||
        return rules;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      function renderComponent() {
 | 
			
		||||
        const { renderComponentContent, component, field, changeEvent = 'change', valueField, componentProps } = props.schema;
 | 
			
		||||
        const { renderComponentContent, component, field, changeEvent = 'change', valueField, componentProps, dynamicRules } = props.schema;
 | 
			
		||||
 | 
			
		||||
        const isCheck = component && ['Switch', 'Checkbox'].includes(component);
 | 
			
		||||
        // update-begin--author:liaozhiyang---date:20231013---for:【QQYUN-6679】input去空格
 | 
			
		||||
| 
						 | 
				
			
			@ -272,7 +337,9 @@
 | 
			
		|||
            }
 | 
			
		||||
            // update-end--author:liaozhiyang---date:20231013---for:【QQYUN-6679】input去空格
 | 
			
		||||
            props.setFormModel(field, value);
 | 
			
		||||
            //props.validateFields([field], { triggerName: 'change' }).catch((_) => {});
 | 
			
		||||
            // update-begin--author:liaozhiyang---date:20240522---for:【TV360X-341】有值之后必填校验不消失
 | 
			
		||||
            props.validateFields([field]).catch((_) => {});
 | 
			
		||||
            // update-end--author:liaozhiyang---date:20240522--for:【TV360X-341】有值之后必填校验不消失
 | 
			
		||||
          },
 | 
			
		||||
          // onBlur: () => {
 | 
			
		||||
          //   props.validateFields([field], { triggerName: 'blur' }).catch((_) => {});
 | 
			
		||||
| 
						 | 
				
			
			@ -338,9 +405,11 @@
 | 
			
		|||
        //label宽度支持自定义
 | 
			
		||||
        const { label, helpMessage, helpComponentProps, subLabel, labelLength } = props.schema;
 | 
			
		||||
        let showLabel: string = label + '';
 | 
			
		||||
        if (labelLength && showLabel.length > 4) {
 | 
			
		||||
        // update-begin--author:liaozhiyang---date:20240517---for:【TV360X-98】label展示的文字必须和labelLength配置一致
 | 
			
		||||
        if (labelLength) {
 | 
			
		||||
          showLabel = showLabel.substr(0, labelLength);
 | 
			
		||||
        }
 | 
			
		||||
        // update-end--author:liaozhiyang---date:20240517---for:【TV360X-98】label展示的文字必须和labelLength配置一致
 | 
			
		||||
        const titleObj = { title: label };
 | 
			
		||||
        const renderLabel = subLabel ? (
 | 
			
		||||
          <span>
 | 
			
		||||
| 
						 | 
				
			
			@ -391,12 +460,17 @@
 | 
			
		|||
              {...(itemProps as Recordable)}
 | 
			
		||||
              label={renderLabelHelpMessage()}
 | 
			
		||||
              rules={handleRules()}
 | 
			
		||||
              // update-begin--author:liaozhiyang---date:20240514---for:【issues/1244】标识了必填,但是必填标识没显示
 | 
			
		||||
              validateFirst = { true }
 | 
			
		||||
              // update-end--author:liaozhiyang---date:20240514---for:【issues/1244】标识了必填,但是必填标识没显示
 | 
			
		||||
              labelCol={labelCol}
 | 
			
		||||
              wrapperCol={wrapperCol}
 | 
			
		||||
            >
 | 
			
		||||
              <div style="display:flex">
 | 
			
		||||
                {/* author: sunjianlei for: 【VUEN-744】此处加上 width: 100%; 因为要防止组件宽度超出 FormItem */}
 | 
			
		||||
                <div style="flex:1; width: 100%;">{getContent()}</div>
 | 
			
		||||
                {/* update-begin--author:liaozhiyang---date:20240510---for:【TV360X-719】表单校验不通过项滚动到可视区内 */}
 | 
			
		||||
                <Middleware>{getContent()}</Middleware>
 | 
			
		||||
                {/* update-end--author:liaozhiyang---date:20240510---for:【TV360X-719】表单校验不通过项滚动到可视区内 */}
 | 
			
		||||
                {showSuffix && <span class="suffix">{getSuffix}</span>}
 | 
			
		||||
              </div>
 | 
			
		||||
            </Form.Item>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,16 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <div :id="formItemId" style="flex: 1; width: 100%">
 | 
			
		||||
    <slot></slot>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup>
 | 
			
		||||
  import { Form } from 'ant-design-vue';
 | 
			
		||||
  import { computed } from 'vue';
 | 
			
		||||
  const formItemContext = Form.useInjectFormItemContext();
 | 
			
		||||
  const formItemId = computed(() => {
 | 
			
		||||
    return formItemContext.id.value;
 | 
			
		||||
  });
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" scoped></style>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,204 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <div :class="formDisabled ? 'jeecg-form-container-disabled jeecg-form-detail-effect' : ''">
 | 
			
		||||
    <fieldset :disabled="formDisabled">
 | 
			
		||||
      <slot name="detail"></slot>
 | 
			
		||||
    </fieldset>
 | 
			
		||||
    <slot name="edit"> </slot>
 | 
			
		||||
    <fieldset disabled>
 | 
			
		||||
      <slot></slot>
 | 
			
		||||
    </fieldset>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
  import { defineComponent, ref, watch } from 'vue';
 | 
			
		||||
 | 
			
		||||
  export default defineComponent({
 | 
			
		||||
    name: 'JForm',
 | 
			
		||||
    props: {
 | 
			
		||||
      disabled: {
 | 
			
		||||
        type: Boolean,
 | 
			
		||||
        default: false,
 | 
			
		||||
        required: false,
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
    setup(props, { emit }) {
 | 
			
		||||
      const formDisabled = ref<boolean>(props.disabled);
 | 
			
		||||
 | 
			
		||||
      watch(
 | 
			
		||||
        () => props.disabled,
 | 
			
		||||
        (value) => {
 | 
			
		||||
          formDisabled.value = value;
 | 
			
		||||
        }
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
      return {
 | 
			
		||||
        formDisabled,
 | 
			
		||||
      };
 | 
			
		||||
    },
 | 
			
		||||
  });
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped lang="less">
 | 
			
		||||
  .jeecg-form-container-disabled {
 | 
			
		||||
    cursor: not-allowed;
 | 
			
		||||
  }
 | 
			
		||||
  .jeecg-form-container-disabled fieldset[disabled] {
 | 
			
		||||
    -ms-pointer-events: none;
 | 
			
		||||
    pointer-events: none;
 | 
			
		||||
  }
 | 
			
		||||
  .jeecg-form-container-disabled :deep(.ant-select) {
 | 
			
		||||
    -ms-pointer-events: none;
 | 
			
		||||
    pointer-events: none;
 | 
			
		||||
  }
 | 
			
		||||
  // update-begin--author:liaozhiyang---date:20240605---for:【TV360X-857】online代码生成详情样式调整
 | 
			
		||||
  // begin antdv 禁用样式
 | 
			
		||||
  // .jeecg-form-container-disabled :deep(.ant-input-number),
 | 
			
		||||
  // .jeecg-form-container-disabled :deep(.ant-input),
 | 
			
		||||
  // .jeecg-form-container-disabled :deep(.ant-input-password),
 | 
			
		||||
  // .jeecg-form-container-disabled :deep(.ant-select-single .ant-select-selector),
 | 
			
		||||
  // .jeecg-form-container-disabled :deep(.ant-radio-wrapper .ant-radio-checked .ant-radio-inner),
 | 
			
		||||
  // .jeecg-form-container-disabled :deep(.ant-switch),
 | 
			
		||||
  // .jeecg-form-container-disabled :deep(.ant-picker),
 | 
			
		||||
  // .jeecg-form-container-disabled :deep(.ant-select:not(.ant-select-customize-input) .ant-select-selector),
 | 
			
		||||
  // .jeecg-form-container-disabled :deep(.ant-input-affix-wrapper),
 | 
			
		||||
  // .jeecg-form-container-disabled :deep(.tox .tox-toolbar__group),
 | 
			
		||||
  // .jeecg-form-container-disabled :deep(.tox .tox-edit-area__iframe),
 | 
			
		||||
  // .jeecg-form-container-disabled :deep(.vditor-toolbar),
 | 
			
		||||
  // .jeecg-form-container-disabled :deep(.vditor-preview),
 | 
			
		||||
  // .jeecg-form-container-disabled :deep(.jeecg-tinymce-img-upload) {
 | 
			
		||||
  //   background: rgba(51, 51, 51, 0.04);
 | 
			
		||||
  // }
 | 
			
		||||
 | 
			
		||||
  // .jeecg-form-container-disabled :deep(.ant-radio-wrapper),
 | 
			
		||||
  // .jeecg-form-container-disabled :deep(.ant-checkbox-wrapper),
 | 
			
		||||
  // .jeecg-form-container-disabled :deep(.ant-btn) {
 | 
			
		||||
  //   color: rgba(0, 0, 0, 0.65);
 | 
			
		||||
  // }
 | 
			
		||||
  // .jeecg-form-container-disabled :deep(.ant-radio-wrapper .ant-radio-inner:after),
 | 
			
		||||
  // .jeecg-form-container-disabled :deep(.ant-checkbox-checked .ant-checkbox-inner) {
 | 
			
		||||
  //   background-color: rgba(51, 51, 51, 0.25);
 | 
			
		||||
  // }
 | 
			
		||||
  // .jeecg-form-container-disabled :deep(.ant-radio-inner),
 | 
			
		||||
  // .jeecg-form-container-disabled :deep(.ant-checkbox-inner) {
 | 
			
		||||
  //   border-color: rgba(51, 51, 51, 0.25) !important;
 | 
			
		||||
  // }
 | 
			
		||||
  // .jeecg-form-container-disabled :deep(.ant-input-password > .ant-input),
 | 
			
		||||
  // .jeecg-form-container-disabled :deep(.ant-input-affix-wrapper .ant-input) {
 | 
			
		||||
  //   background: none;
 | 
			
		||||
  // }
 | 
			
		||||
  html[data-theme='light'] {
 | 
			
		||||
    .jeecg-form-detail-effect {
 | 
			
		||||
      :deep(.ant-select-selector),
 | 
			
		||||
      :deep(.ant-btn),
 | 
			
		||||
      :deep(.ant-input),
 | 
			
		||||
      :deep(.ant-input-affix-wrapper),
 | 
			
		||||
      :deep(.ant-picker),
 | 
			
		||||
      :deep(.ant-input-number) {
 | 
			
		||||
        color: rgba(51, 51, 51, 0.25) !important;
 | 
			
		||||
      }
 | 
			
		||||
      :deep(.ant-select) {
 | 
			
		||||
        color: rgba(51, 51, 51, 0.25) !important;
 | 
			
		||||
      }
 | 
			
		||||
      :deep(.ant-select-selection-item-content),:deep(.ant-select-selection-item),:deep(input) {
 | 
			
		||||
        color: rgba(51, 51, 51, 0.25) !important;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      :deep(.ant-radio-wrapper),
 | 
			
		||||
      :deep(.ant-checkbox-wrapper),
 | 
			
		||||
      :deep(.ant-btn) {
 | 
			
		||||
        color: rgba(0, 0, 0, 0.65);
 | 
			
		||||
      }
 | 
			
		||||
      :deep(.ant-radio-wrapper .ant-radio-inner:after),
 | 
			
		||||
      :deep(.ant-checkbox-checked .ant-checkbox-inner) {
 | 
			
		||||
        background-color: rgba(51, 51, 51, 0.25);
 | 
			
		||||
      }
 | 
			
		||||
      :deep(.ant-radio-inner),
 | 
			
		||||
      :deep(.ant-checkbox-inner) {
 | 
			
		||||
        border-color: rgba(51, 51, 51, 0.25) !important;
 | 
			
		||||
        background-color: rgba(51, 51, 51, 0.04) !important;
 | 
			
		||||
      }
 | 
			
		||||
      :deep(.ant-checkbox-checked .ant-checkbox-inner::after), :deep(.ant-tree-checkbox-checked .ant-tree-checkbox-inner::after){
 | 
			
		||||
        border-color: rgba(51, 51, 51, 0.25) !important;
 | 
			
		||||
      }
 | 
			
		||||
      :deep(.ant-switch) {
 | 
			
		||||
        background-color: rgba(51, 51, 51, 0.25);
 | 
			
		||||
      }
 | 
			
		||||
      :deep(.tox .tox-toolbar__group),
 | 
			
		||||
      :deep(.tox .tox-edit-area__iframe),
 | 
			
		||||
      :deep(.vditor-toolbar),
 | 
			
		||||
      :deep(.vditor-preview),
 | 
			
		||||
      :deep(.jeecg-tinymce-img-upload) {
 | 
			
		||||
        background: rgba(51, 51, 51, 0.04);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  html[data-theme='dark'] {
 | 
			
		||||
    .jeecg-form-detail-effect {
 | 
			
		||||
      :deep(.ant-select-selector),
 | 
			
		||||
      :deep(.ant-btn),
 | 
			
		||||
      :deep(.ant-input),
 | 
			
		||||
      :deep(.ant-input-affix-wrapper),
 | 
			
		||||
      :deep(.ant-picker),
 | 
			
		||||
      :deep(.ant-input-number) {
 | 
			
		||||
        color: rgba(255, 255, 255, 0.25) !important;
 | 
			
		||||
        background-color: rgba(255, 255, 255, 0.08) !important;
 | 
			
		||||
      }
 | 
			
		||||
      :deep(.ant-select) {
 | 
			
		||||
        color: rgba(255, 255, 255, 0.25) !important;
 | 
			
		||||
      }
 | 
			
		||||
      :deep(.ant-select-selection-item-content),:deep(.ant-select-selection-item),:deep(input) {
 | 
			
		||||
        color: rgba(255, 255, 255, 0.25) !important;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      :deep(.ant-radio-wrapper),
 | 
			
		||||
      :deep(.ant-checkbox-wrapper){
 | 
			
		||||
        color: rgba(255, 255, 255, 0.25);
 | 
			
		||||
      }
 | 
			
		||||
      :deep(.ant-radio-wrapper .ant-radio-inner:after),
 | 
			
		||||
      :deep(.ant-checkbox-checked .ant-checkbox-inner) {
 | 
			
		||||
        background-color: rgba(255, 255, 255, 0.08);
 | 
			
		||||
      }
 | 
			
		||||
      :deep(.ant-radio-inner),
 | 
			
		||||
      :deep(.ant-checkbox-inner) {
 | 
			
		||||
        border-color: #424242 !important;
 | 
			
		||||
        background-color: rgba(255, 255, 255, 0.08);
 | 
			
		||||
      }
 | 
			
		||||
      :deep(.ant-switch) {
 | 
			
		||||
        background-color: rgba(51, 51, 51, 0.25);
 | 
			
		||||
        opacity: 0.65;
 | 
			
		||||
      }
 | 
			
		||||
      :deep(.tox .tox-toolbar__group),
 | 
			
		||||
      :deep(.tox .tox-edit-area__iframe),
 | 
			
		||||
      :deep(.vditor-toolbar),
 | 
			
		||||
      :deep(.vditor-preview),
 | 
			
		||||
      :deep(.jeecg-tinymce-img-upload) {
 | 
			
		||||
        background: rgba(51, 51, 51, 0.04);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  // end antdv 禁用样式
 | 
			
		||||
  // update-begin--author:liaozhiyang---date:20240605---for:【TV360X-857】online代码生成详情样式调整
 | 
			
		||||
  .jeecg-form-container-disabled :deep(.ant-upload-select) {
 | 
			
		||||
    cursor: grabbing;
 | 
			
		||||
  }
 | 
			
		||||
  .jeecg-form-container-disabled :deep(.ant-upload-list) {
 | 
			
		||||
    cursor: grabbing;
 | 
			
		||||
  }
 | 
			
		||||
  .jeecg-form-container-disabled fieldset[disabled] :deep(.ant-upload-list){
 | 
			
		||||
    // -ms-pointer-events: auto !important;
 | 
			
		||||
    // pointer-events: auto !important;
 | 
			
		||||
  }
 | 
			
		||||
  .jeecg-form-container-disabled fieldset[disabled] iframe {
 | 
			
		||||
    -ms-pointer-events: auto !important;
 | 
			
		||||
    pointer-events: auto !important;
 | 
			
		||||
  }
 | 
			
		||||
  .jeecg-form-container-disabled :deep(.ant-upload-list-item-actions .anticon-delete),
 | 
			
		||||
  .jeecg-form-container-disabled :deep(.ant-upload-list-item .anticon-close) {
 | 
			
		||||
    display: none;
 | 
			
		||||
  }
 | 
			
		||||
  .jeecg-form-container-disabled :deep(.vditor-sv) {
 | 
			
		||||
    display: none !important;
 | 
			
		||||
    background: rgba(51, 51, 51, 0.04);
 | 
			
		||||
  }
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			@ -74,9 +74,11 @@ export function handleInputNumberValue(component?: ComponentType, val?: any) {
 | 
			
		|||
*/ 
 | 
			
		||||
export function handleInputStringValue(component?: ComponentType, val?: any) {
 | 
			
		||||
  if (!component) return val;
 | 
			
		||||
  if (['InputNumber'].includes(component) && typeof val === 'string') {
 | 
			
		||||
  // update-begin--author:liaozhiyang---date:20240517---for:【TV360X-13】InputNumber设置精确3位小数传入''变成了0.00
 | 
			
		||||
  if (['InputNumber'].includes(component) && typeof val === 'string' && val != '') {
 | 
			
		||||
    return Number(val);
 | 
			
		||||
  }
 | 
			
		||||
  // update-end--author:liaozhiyang---date:20240517---for:【TV360X-13】InputNumber设置精确3位小数传入''变成了0.00
 | 
			
		||||
  return val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <Cascader v-bind="attrs" :value="state" :options="getOptions" @change="handleChange" />
 | 
			
		||||
  <Cascader v-bind="attrs" :value="cascaderValue" :options="getOptions" @change="handleChange" />
 | 
			
		||||
</template>
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
  import { defineComponent, PropType, ref, reactive, watchEffect, computed, unref, watch, onMounted } from 'vue';
 | 
			
		||||
| 
						 | 
				
			
			@ -8,6 +8,8 @@
 | 
			
		|||
  import { useRuleFormItem } from '/@/hooks/component/useFormItem';
 | 
			
		||||
  import { propTypes } from '/@/utils/propTypes';
 | 
			
		||||
  import { useAttrs } from '/@/hooks/core/useAttrs';
 | 
			
		||||
  import { isArray } from '/@/utils/is';
 | 
			
		||||
 | 
			
		||||
  export default defineComponent({
 | 
			
		||||
    name: 'JAreaLinkage',
 | 
			
		||||
    components: {
 | 
			
		||||
| 
						 | 
				
			
			@ -20,12 +22,15 @@
 | 
			
		|||
      showArea: propTypes.bool.def(true),
 | 
			
		||||
      //是否是全部
 | 
			
		||||
      showAll: propTypes.bool.def(false),
 | 
			
		||||
      // 存储数据 
 | 
			
		||||
      saveCode: propTypes.oneOf(['province', 'city', 'region', 'all']).def('all'),
 | 
			
		||||
    },
 | 
			
		||||
    emits: ['options-change', 'change'],
 | 
			
		||||
    setup(props, { emit, refs }) {
 | 
			
		||||
      const emitData = ref<any[]>([]);
 | 
			
		||||
      const attrs = useAttrs();
 | 
			
		||||
      const [state] = useRuleFormItem(props, 'value', 'change', emitData);
 | 
			
		||||
      // const [state] = useRuleFormItem(props, 'value', 'change', emitData);
 | 
			
		||||
      const cascaderValue = ref([]);
 | 
			
		||||
      const getOptions = computed(() => {
 | 
			
		||||
        if (props.showArea && props.showAll) {
 | 
			
		||||
          return regionDataPlus;
 | 
			
		||||
| 
						 | 
				
			
			@ -52,20 +57,59 @@
 | 
			
		|||
       */
 | 
			
		||||
      function initValue() {
 | 
			
		||||
        let value = props.value ? props.value : [];
 | 
			
		||||
        // update-begin--author:liaozhiyang---date:20240607---for:【TV360X-501】省市区换新组件
 | 
			
		||||
        if (value && typeof value === 'string' && value != 'null' && value != 'undefined') {
 | 
			
		||||
          state.value = value.split(',');
 | 
			
		||||
          const arr = value.split(',');
 | 
			
		||||
          cascaderValue.value = transform(arr);
 | 
			
		||||
        } else if (isArray(value)) {
 | 
			
		||||
          cascaderValue.value = transform(value);
 | 
			
		||||
        }
 | 
			
		||||
        // update-end--author:liaozhiyang---date:20240607---for:【TV360X-501】省市区换新组件
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      function handleChange(array, ...args) {
 | 
			
		||||
      function transform(arr) {
 | 
			
		||||
        let result: any = [];
 | 
			
		||||
        if (props.saveCode === 'region') {
 | 
			
		||||
          // 81 香港、82 澳门
 | 
			
		||||
          const regionCode = arr[0];
 | 
			
		||||
          if (['82', '81'].includes(regionCode.substring(0, 2))) {
 | 
			
		||||
            result = [`${regionCode.substring(0, 2)}0000`, regionCode];
 | 
			
		||||
          } else {
 | 
			
		||||
            result = [`${regionCode.substring(0, 2)}0000`, `${regionCode.substring(0, 2)}${regionCode.substring(2, 4)}00`, regionCode];
 | 
			
		||||
          }
 | 
			
		||||
        } else if (props.saveCode === 'city') {
 | 
			
		||||
          const cityCode = arr[0];
 | 
			
		||||
          result = [`${cityCode.substring(0, 2)}0000`, cityCode];
 | 
			
		||||
        } else if (props.saveCode === 'province') {
 | 
			
		||||
          const provinceCode = arr[0];
 | 
			
		||||
          result = [provinceCode];
 | 
			
		||||
        } else {
 | 
			
		||||
          result = arr;
 | 
			
		||||
        }
 | 
			
		||||
        return result;
 | 
			
		||||
      }
 | 
			
		||||
      function handleChange(arr, ...args) {
 | 
			
		||||
        // update-begin--author:liaozhiyang---date:20240607---for:【TV360X-501】省市区换新组件
 | 
			
		||||
        let result: any = [];
 | 
			
		||||
        if (props.saveCode === 'region') {
 | 
			
		||||
          // 可能只有两位(选择香港时,只有省区)
 | 
			
		||||
          result = [arr[arr.length - 1]];
 | 
			
		||||
        } else if (props.saveCode === 'city') {
 | 
			
		||||
          result = [arr[1]];
 | 
			
		||||
        } else if (props.saveCode === 'province') {
 | 
			
		||||
          result = [arr[0]];
 | 
			
		||||
        } else {
 | 
			
		||||
          result = arr;
 | 
			
		||||
        }
 | 
			
		||||
        emit('change', result);
 | 
			
		||||
        // update-end--author:liaozhiyang---date:20240607---for:【TV360X-501】省市区换新组件
 | 
			
		||||
        // emitData.value = args;
 | 
			
		||||
        //update-begin-author:taoyan date:2022-6-27 for: VUEN-1424【vue3】树表、单表、jvxe、erp 、内嵌子表省市县 选择不上
 | 
			
		||||
        // 上面改的v-model:value导致选中数据没有显示
 | 
			
		||||
        state.value = array;
 | 
			
		||||
        // state.value = result;
 | 
			
		||||
        //update-end-author:taoyan date:2022-6-27 for: VUEN-1424【vue3】树表、单表、jvxe、erp 、内嵌子表省市县 选择不上
 | 
			
		||||
      }
 | 
			
		||||
      return {
 | 
			
		||||
        state,
 | 
			
		||||
        cascaderValue,
 | 
			
		||||
        attrs,
 | 
			
		||||
        regionData,
 | 
			
		||||
        getOptions,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,7 +16,7 @@
 | 
			
		|||
  </a-tree-select>
 | 
			
		||||
</template>
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
  import { defineComponent, ref, unref, watch } from 'vue';
 | 
			
		||||
  import { defineComponent, ref, unref, watch, nextTick } from 'vue';
 | 
			
		||||
  import { useRuleFormItem } from '/@/hooks/component/useFormItem';
 | 
			
		||||
  import { propTypes } from '/@/utils/propTypes';
 | 
			
		||||
  import { useAttrs } from '/@/hooks/core/useAttrs';
 | 
			
		||||
| 
						 | 
				
			
			@ -78,7 +78,7 @@
 | 
			
		|||
      const treeData = ref<any[]>([]);
 | 
			
		||||
      const treeValue = ref();
 | 
			
		||||
      const attrs = useAttrs();
 | 
			
		||||
      const [state] = useRuleFormItem(props, 'value', 'change', emitData);
 | 
			
		||||
      const [state, , , formItemContext] = useRuleFormItem(props, 'value', 'change', emitData);
 | 
			
		||||
      watch(
 | 
			
		||||
        () => props.value,
 | 
			
		||||
        () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -218,6 +218,11 @@
 | 
			
		|||
          backValue(value.value, value.label);
 | 
			
		||||
          treeValue.value = value;
 | 
			
		||||
        }
 | 
			
		||||
        // update-begin--author:liaozhiyang---date:20240429---for:【QQYUN-9110】组件有值校验没消失
 | 
			
		||||
        nextTick(() => {
 | 
			
		||||
          formItemContext?.onFieldChange();
 | 
			
		||||
        });
 | 
			
		||||
        // update-end--author:liaozhiyang---date:20240429---for:【QQYUN-9110】组件有值校验没消失
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      function getCurrTreeData() {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -42,12 +42,16 @@
 | 
			
		|||
  import 'codemirror/addon/hint/show-hint.css';
 | 
			
		||||
  import 'codemirror/addon/hint/show-hint.js';
 | 
			
		||||
  import 'codemirror/addon/hint/anyword-hint.js';
 | 
			
		||||
  // 匹配括号
 | 
			
		||||
  import 'codemirror/addon/edit/matchbrackets';
 | 
			
		||||
  import { useAttrs } from '/@/hooks/core/useAttrs';
 | 
			
		||||
  import { useDesign } from '/@/hooks/web/useDesign';
 | 
			
		||||
  import { isJsonObjectString } from '/@/utils/is.ts';
 | 
			
		||||
  // 代码提示
 | 
			
		||||
  import { useCodeHinting } from '../hooks/useCodeHinting';
 | 
			
		||||
 | 
			
		||||
  import { useRootSetting } from '/@/hooks/setting/useRootSetting';
 | 
			
		||||
  import { ThemeEnum } from '/@/enums/appEnum';
 | 
			
		||||
  export default defineComponent({
 | 
			
		||||
    name: 'JCodeEditor',
 | 
			
		||||
    // 不将 attrs 的属性绑定到 html 标签上
 | 
			
		||||
| 
						 | 
				
			
			@ -68,6 +72,7 @@
 | 
			
		|||
    },
 | 
			
		||||
    emits: ['change', 'update:value'],
 | 
			
		||||
    setup(props, { emit }) {
 | 
			
		||||
      const { getDarkMode } = useRootSetting();
 | 
			
		||||
      const containerRef = ref(null);
 | 
			
		||||
      const { prefixCls } = useDesign('code-editer');
 | 
			
		||||
      const CodeMirror = window.CodeMirror || _CodeMirror;
 | 
			
		||||
| 
						 | 
				
			
			@ -82,7 +87,9 @@
 | 
			
		|||
        // 缩进格式
 | 
			
		||||
        tabSize: 2,
 | 
			
		||||
        // 主题,对应主题库 JS 需要提前引入
 | 
			
		||||
        theme: props.theme,
 | 
			
		||||
        // update-begin--author:liaozhiyang---date:20240327---for:【QQYUN-8639】暗黑主题适配
 | 
			
		||||
        theme: getDarkMode.value == ThemeEnum.DARK ? 'monokai' : props.theme,
 | 
			
		||||
        // update-end--author:liaozhiyang---date:20240327---for:【QQYUN-8639】暗黑主题适配
 | 
			
		||||
        smartIndent: true, // 是否智能缩进
 | 
			
		||||
        // 显示行号
 | 
			
		||||
        lineNumbers: true,
 | 
			
		||||
| 
						 | 
				
			
			@ -97,13 +104,19 @@
 | 
			
		|||
        // update-begin--author:liaozhiyang---date:20231201---for:【issues/869】JCodeEditor组件初始化时没有设置mode
 | 
			
		||||
        mode: props.language,
 | 
			
		||||
        // update-begin--author:liaozhiyang---date:20231201---for:【issues/869】JCodeEditor组件初始化时没有设置mode
 | 
			
		||||
        //代码格式化
 | 
			
		||||
        // update-begin--author:liaozhiyang---date:20240603---for:【TV360X-898】代码生成之后的预览改成只读
 | 
			
		||||
        readOnly: props.disabled,
 | 
			
		||||
        // update-end--author:liaozhiyang---date:20240603---for:【TV360X-898】代码生成之后的预览改成只读
 | 
			
		||||
        // 匹配括号
 | 
			
		||||
        matchBrackets: true,
 | 
			
		||||
        extraKeys: {
 | 
			
		||||
          Tab: function autoFormat(editor) {
 | 
			
		||||
            //var totalLines = editor.lineCount();
 | 
			
		||||
            //editor.autoFormatRange({line:0, ch:0}, {line:totalLines});
 | 
			
		||||
            setValue(innerValue, false);
 | 
			
		||||
          },
 | 
			
		||||
          // Tab: function autoFormat(editor) {
 | 
			
		||||
          //   //var totalLines = editor.lineCount();
 | 
			
		||||
          //   //editor.autoFormatRange({line:0, ch:0}, {line:totalLines});
 | 
			
		||||
          //   setValue(innerValue, false);
 | 
			
		||||
          // },
 | 
			
		||||
          'Cmd-/': (cm) => comment(cm),
 | 
			
		||||
          'Ctrl-/': (cm) => comment(cm),
 | 
			
		||||
        },
 | 
			
		||||
      });
 | 
			
		||||
      // 内部存储值,初始为 props.value
 | 
			
		||||
| 
						 | 
				
			
			@ -146,6 +159,11 @@
 | 
			
		|||
      );
 | 
			
		||||
      onMounted(() => {
 | 
			
		||||
        initialize();
 | 
			
		||||
        // update-begin--author:liaozhiyang---date:20240318---for:【QQYUN-8473】代码编辑器首次加载会有遮挡
 | 
			
		||||
        setTimeout(() => {
 | 
			
		||||
          refresh();
 | 
			
		||||
        }, 150);
 | 
			
		||||
        // update-end--author:liaozhiyang---date:20240318---for:【QQYUN-8473】代码编辑器首次加载会有遮挡
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
| 
						 | 
				
			
			@ -160,6 +178,15 @@
 | 
			
		|||
        coder?.setValue(value ?? '');
 | 
			
		||||
        innerValue = value;
 | 
			
		||||
        trigger && emitChange(innerValue);
 | 
			
		||||
        // update-begin--author:liaozhiyang---date:20240510---for:【QQYUN-9231】代码编辑器有遮挡
 | 
			
		||||
        setTimeout(() => {
 | 
			
		||||
          refresh();
 | 
			
		||||
          // 再次刷下防止小概率下遮挡问题
 | 
			
		||||
          setTimeout(() => {
 | 
			
		||||
            refresh();
 | 
			
		||||
          }, 600);
 | 
			
		||||
        }, 400);
 | 
			
		||||
        // update-end--author:liaozhiyang---date:20240510---for:【QQYUN-9231】代码编辑器有遮挡
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      //编辑器值修改事件
 | 
			
		||||
| 
						 | 
				
			
			@ -221,6 +248,24 @@
 | 
			
		|||
      }
 | 
			
		||||
      //update-end-author:taoyan date:2022-10-18 for: VUEN-2480【严重bug】online vue3测试的问题 8、online js增强样式问题
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * 2024-04-01
 | 
			
		||||
       * liaozhiyang
 | 
			
		||||
       * 代码批量注释
 | 
			
		||||
       */
 | 
			
		||||
      function comment(cm) {
 | 
			
		||||
        var selection = cm.getSelection();
 | 
			
		||||
        var start = cm.getCursor('start');
 | 
			
		||||
        var end = cm.getCursor('end');
 | 
			
		||||
        var isCommented = selection.startsWith('//');
 | 
			
		||||
        if (isCommented) {
 | 
			
		||||
          // 如果已经被注释,取消注释
 | 
			
		||||
          cm.replaceRange(selection.replace(/\n\/\/\s/g, '\n').replace(/^\/\/\s/, ''), start, end);
 | 
			
		||||
        } else {
 | 
			
		||||
          // 添加注释
 | 
			
		||||
          cm.replaceRange('// ' + selection.replace(/\n(?=.)/g, '\n// '), start, end);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return {
 | 
			
		||||
        state,
 | 
			
		||||
| 
						 | 
				
			
			@ -312,9 +357,19 @@
 | 
			
		|||
      border: 1px solid #ddd;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  .CodeMirror-hints.idea {
 | 
			
		||||
  .CodeMirror-hints.idea,
 | 
			
		||||
  .CodeMirror-hints.monokai {
 | 
			
		||||
    z-index: 1001;
 | 
			
		||||
    max-width: 600px;
 | 
			
		||||
    max-height: 300px;
 | 
			
		||||
  }
 | 
			
		||||
  // update-begin--author:liaozhiyang---date:20240327---for:【QQYUN-8639】暗黑主题适配
 | 
			
		||||
  html[data-theme='dark'] {
 | 
			
		||||
    .@{prefix-cls} {
 | 
			
		||||
      .CodeMirror {
 | 
			
		||||
        border: 1px solid #3a3a3a;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  // update-end--author:liaozhiyang---date:20240327---for:【QQYUN-8639】暗黑主题适配
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,10 +3,11 @@
 | 
			
		|||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
  import { computed, defineComponent } from 'vue';
 | 
			
		||||
  import { computed, defineComponent, nextTick } from 'vue';
 | 
			
		||||
 | 
			
		||||
  import { Tinymce } from '/@/components/Tinymce';
 | 
			
		||||
  import { propTypes } from '/@/utils/propTypes';
 | 
			
		||||
  import { Form } from 'ant-design-vue';
 | 
			
		||||
 | 
			
		||||
  export default defineComponent({
 | 
			
		||||
    name: 'JEditor',
 | 
			
		||||
| 
						 | 
				
			
			@ -21,11 +22,16 @@
 | 
			
		|||
    setup(props, { emit, attrs }) {
 | 
			
		||||
      // 合并 props 和 attrs
 | 
			
		||||
      const bindProps = computed(() => Object.assign({}, props, attrs));
 | 
			
		||||
 | 
			
		||||
      const formItemContext = Form.useInjectFormItemContext();
 | 
			
		||||
      // value change 事件
 | 
			
		||||
      function onChange(value) {
 | 
			
		||||
        emit('change', value);
 | 
			
		||||
        emit('update:value', value);
 | 
			
		||||
        // update-begin--author:liaozhiyang---date:20240429---for:【QQYUN-9110】组件有值校验没消失
 | 
			
		||||
        nextTick(() => {
 | 
			
		||||
          formItemContext?.onFieldChange();
 | 
			
		||||
        });
 | 
			
		||||
        // update-end--author:liaozhiyang---date:20240429---for:【QQYUN-9110】组件有值校验没消失
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,6 +30,7 @@
 | 
			
		|||
  import { defHttp } from '/@/utils/http/axios';
 | 
			
		||||
  import { useGlobSetting } from '/@/hooks/setting';
 | 
			
		||||
  import { useMessage } from '/@/hooks/web/useMessage';
 | 
			
		||||
  import { isObject } from '/@/utils/is';
 | 
			
		||||
 | 
			
		||||
  export default defineComponent({
 | 
			
		||||
    name: 'JImportModal',
 | 
			
		||||
| 
						 | 
				
			
			@ -116,6 +117,11 @@
 | 
			
		|||
        if (unref(foreignKeys) && unref(foreignKeys).length > 0) {
 | 
			
		||||
          formData.append('foreignKeys', unref(foreignKeys));
 | 
			
		||||
        }
 | 
			
		||||
        // update-begin--author:liaozhiyang---date:20240429---for:【issues/6124】当用户没有【Online表单开发】页面的权限时用户无权导入从表数据
 | 
			
		||||
        if (isObject(foreignKeys.value)) {
 | 
			
		||||
          formData.append('foreignKeys', JSON.stringify(foreignKeys.value));
 | 
			
		||||
        }
 | 
			
		||||
        // update-end--author:liaozhiyang---date:20240429---for:【issues/6124】当用户没有【Online表单开发】页面的权限时用户无权导入从表数据
 | 
			
		||||
        if (!!online) {
 | 
			
		||||
          formData.append('validateStatus', unref(validateStatus));
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,7 +7,7 @@
 | 
			
		|||
    :placement="position"
 | 
			
		||||
  >
 | 
			
		||||
    <template #title>
 | 
			
		||||
      <span>{{ title }}</span>
 | 
			
		||||
      <span :class="title ? 'title' : 'emptyTitle'">{{ title }}</span>
 | 
			
		||||
      <span style="float: right" title="关闭">
 | 
			
		||||
        <Icon icon="ant-design:close-outlined" @click="visible = false" />
 | 
			
		||||
      </span>
 | 
			
		||||
| 
						 | 
				
			
			@ -100,6 +100,11 @@
 | 
			
		|||
 | 
			
		||||
  .@{prefix-cls} {
 | 
			
		||||
    &-popover {
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20240520---for:【TV360X-144】jVxetable中的多行文本组件当title没有时去掉多余的线
 | 
			
		||||
      .ant-popover-title:has(.emptyTitle) {
 | 
			
		||||
        border-bottom: none;
 | 
			
		||||
      }
 | 
			
		||||
      // update-end--author:liaozhiyang---date:20240520---for:【TV360X-144】jVxetable中的多行文本组件当title没有时去掉多余的线
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    &-input {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,75 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <div class="JInputSelect">
 | 
			
		||||
    <a-input-group compact>
 | 
			
		||||
      <a-select
 | 
			
		||||
        v-bind="$attrs"
 | 
			
		||||
        :placeholder="selectPlaceholder"
 | 
			
		||||
        v-if="selectLocation === 'left'"
 | 
			
		||||
        v-model:value="selectVal"
 | 
			
		||||
        @change="handleSelectChange"
 | 
			
		||||
      >
 | 
			
		||||
        <a-select-option v-for="item in options" :key="item.value">{{ item.label }}</a-select-option>
 | 
			
		||||
      </a-select>
 | 
			
		||||
      <a-input v-bind="$attrs" :placeholder="inputPlaceholder" v-model:value="inputVal" @change="handleInputChange" />
 | 
			
		||||
      <a-select
 | 
			
		||||
        v-bind="$attrs"
 | 
			
		||||
        :placeholder="selectPlaceholder"
 | 
			
		||||
        v-if="selectLocation === 'right'"
 | 
			
		||||
        v-model:value="selectVal"
 | 
			
		||||
        @change="handleSelectChange"
 | 
			
		||||
      >
 | 
			
		||||
        <a-select-option v-for="item in options" :key="item.value">{{ item.label }}</a-select-option>
 | 
			
		||||
      </a-select>
 | 
			
		||||
    </a-input-group>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup name="JInputSelect" lang="ts">
 | 
			
		||||
  import { ref, watchEffect } from 'vue';
 | 
			
		||||
  import { propTypes } from '/@/utils/propTypes';
 | 
			
		||||
  const props = defineProps({
 | 
			
		||||
    value: propTypes.string.def(''),
 | 
			
		||||
    options: propTypes.array.def([]),
 | 
			
		||||
    selectLocation: propTypes.oneOf(['left', 'right']).def('right'),
 | 
			
		||||
    selectPlaceholder: propTypes.string.def(''),
 | 
			
		||||
    inputPlaceholder: propTypes.string.def(''),
 | 
			
		||||
  });
 | 
			
		||||
  const emit = defineEmits(['update:value', 'change']);
 | 
			
		||||
  const selectVal = ref<string>();
 | 
			
		||||
  const inputVal = ref<string>();
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
  const handleInputChange = (e) => {
 | 
			
		||||
    const val = e.target.value;
 | 
			
		||||
    setSelectValByInputVal(val);
 | 
			
		||||
    emits(val);
 | 
			
		||||
  };
 | 
			
		||||
  const handleSelectChange = (val) => {
 | 
			
		||||
    inputVal.value = val;
 | 
			
		||||
    emits(val);
 | 
			
		||||
  };
 | 
			
		||||
  const setSelectValByInputVal = (val) => {
 | 
			
		||||
    const findItem = props.options.find((item) => item.value === val);
 | 
			
		||||
    if (findItem) {
 | 
			
		||||
      selectVal.value = val;
 | 
			
		||||
    } else {
 | 
			
		||||
      selectVal.value = undefined;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  watchEffect(() => {
 | 
			
		||||
    inputVal.value = props.value;
 | 
			
		||||
    setSelectValByInputVal(props.value);
 | 
			
		||||
  });
 | 
			
		||||
  const emits = (val) => {
 | 
			
		||||
    emit('update:value', val);
 | 
			
		||||
    emit('change', val);
 | 
			
		||||
  };
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="less" scoped>
 | 
			
		||||
  .JInputSelect {
 | 
			
		||||
    .ant-input-group {
 | 
			
		||||
      display: flex;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			@ -3,10 +3,10 @@
 | 
			
		|||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
  import { computed, defineComponent, watch } from 'vue';
 | 
			
		||||
  import { computed, defineComponent, watch, nextTick } from 'vue';
 | 
			
		||||
  import { MarkDown } from '/@/components/Markdown';
 | 
			
		||||
  import { propTypes } from '/@/utils/propTypes';
 | 
			
		||||
 | 
			
		||||
  import { Form } from 'ant-design-vue';
 | 
			
		||||
  export default defineComponent({
 | 
			
		||||
    name: 'JMarkdownEditor',
 | 
			
		||||
    // 不将 attrs 的属性绑定到 html 标签上
 | 
			
		||||
| 
						 | 
				
			
			@ -24,7 +24,7 @@
 | 
			
		|||
      let vditorRef: any = null;
 | 
			
		||||
      // 合并 props 和 attrs
 | 
			
		||||
      const bindProps = computed(() => Object.assign({}, props, attrs));
 | 
			
		||||
 | 
			
		||||
      const formItemContext = Form.useInjectFormItemContext();
 | 
			
		||||
      // 相当于 onMounted
 | 
			
		||||
      function onGetVditor(instance) {
 | 
			
		||||
        mdRef = instance;
 | 
			
		||||
| 
						 | 
				
			
			@ -42,6 +42,11 @@
 | 
			
		|||
      function onChange(value) {
 | 
			
		||||
        emit('change', value);
 | 
			
		||||
        emit('update:value', value);
 | 
			
		||||
        // update-begin--author:liaozhiyang---date:20240429---for:【QQYUN-9110】组件有值校验没消失
 | 
			
		||||
        nextTick(() => {
 | 
			
		||||
          formItemContext?.onFieldChange();
 | 
			
		||||
        });
 | 
			
		||||
        // update-end--author:liaozhiyang---date:20240429---for:【QQYUN-9110】组件有值校验没消失
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
<!--popup组件-->
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="components-input-demo-presuffix" v-if="avalid">
 | 
			
		||||
  <div class="JPopup components-input-demo-presuffix" v-if="avalid">
 | 
			
		||||
    <!--输入框-->
 | 
			
		||||
    <a-input @click="handleOpen" v-model:value="showText" :placeholder="placeholder" readOnly v-bind="attrs">
 | 
			
		||||
      <template #prefix>
 | 
			
		||||
| 
						 | 
				
			
			@ -12,17 +12,22 @@
 | 
			
		|||
            </template>-->
 | 
			
		||||
      <!-- update-begin-author:taoyan date:2022-5-31 for: VUEN-1157 popup 选中后,有两个清除图标;后边这个清除,只是把输入框中数据清除,实际值并没有清除 -->
 | 
			
		||||
    </a-input>
 | 
			
		||||
    <!--popup弹窗-->
 | 
			
		||||
    <JPopupOnlReportModal
 | 
			
		||||
      @register="regModal"
 | 
			
		||||
      :code="code"
 | 
			
		||||
      :multi="multi"
 | 
			
		||||
      :sorter="sorter"
 | 
			
		||||
      :groupId="uniqGroupId"
 | 
			
		||||
      :param="param"
 | 
			
		||||
      @ok="callBack"
 | 
			
		||||
      :getContainer="getContainer"
 | 
			
		||||
    ></JPopupOnlReportModal>
 | 
			
		||||
    <!-- update-begin--author:liaozhiyang---date:20240515---for:【QQYUN-9260】必填模式下会影响到弹窗内antd组件的样式 -->
 | 
			
		||||
    <a-form-item>
 | 
			
		||||
      <!--popup弹窗-->
 | 
			
		||||
      <JPopupOnlReportModal
 | 
			
		||||
        @register="regModal"
 | 
			
		||||
        :code="code"
 | 
			
		||||
        :multi="multi"
 | 
			
		||||
        :sorter="sorter"
 | 
			
		||||
        :groupId="uniqGroupId"
 | 
			
		||||
        :param="param"
 | 
			
		||||
        :showAdvancedButton="showAdvancedButton"
 | 
			
		||||
        @ok="callBack"
 | 
			
		||||
        :getContainer="getContainer"
 | 
			
		||||
      ></JPopupOnlReportModal>
 | 
			
		||||
    </a-form-item>
 | 
			
		||||
    <!-- update-end--author:liaozhiyang---date:20240515---for:【QQYUN-9260】必填模式下会影响到弹窗内antd组件的样式 -->
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
| 
						 | 
				
			
			@ -56,6 +61,7 @@
 | 
			
		|||
        type: Array,
 | 
			
		||||
        default: () => [],
 | 
			
		||||
      },
 | 
			
		||||
      showAdvancedButton: propTypes.bool.def(true),
 | 
			
		||||
    },
 | 
			
		||||
    emits: ['update:value', 'register', 'popUpChange', 'focus'],
 | 
			
		||||
    setup(props, { emit, refs }) {
 | 
			
		||||
| 
						 | 
				
			
			@ -97,7 +103,9 @@
 | 
			
		|||
       */
 | 
			
		||||
      function handleOpen() {
 | 
			
		||||
        emit('focus');
 | 
			
		||||
        !props.disabled && openModal(true);
 | 
			
		||||
        // update-begin--author:liaozhiyang---date:20240528---for:【TV360X-317】禁用后JPopup和JPopupdic还可以点击出弹窗
 | 
			
		||||
        !attrs.value.disabled && openModal(true);
 | 
			
		||||
        // update-end--author:liaozhiyang---date:20240528---for:【TV360X-317】禁用后JPopup和JPopupdic还可以点击出弹窗
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
| 
						 | 
				
			
			@ -148,6 +156,13 @@
 | 
			
		|||
  });
 | 
			
		||||
</script>
 | 
			
		||||
<style lang="less" scoped>
 | 
			
		||||
  // update-begin--author:liaozhiyang---date:20240515---for:【QQYUN-9260】必填模式下会影响到弹窗内antd组件的样式
 | 
			
		||||
  .JPopup {
 | 
			
		||||
    > .ant-form-item {
 | 
			
		||||
      display: none;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  // update-end--author:liaozhiyang---date:20240515---for:【QQYUN-9260】必填模式下会影响到弹窗内antd组件的样式
 | 
			
		||||
  .components-input-demo-presuffix .anticon-close-circle {
 | 
			
		||||
    cursor: pointer;
 | 
			
		||||
    color: #ccc;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,21 +1,26 @@
 | 
			
		|||
<!--popup组件-->
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="components-input-demo-presuffix">
 | 
			
		||||
  <div class="JPopupDict components-input-demo-presuffix">
 | 
			
		||||
    <!--输入框-->
 | 
			
		||||
    <a-select v-model:value="showText" v-bind="attrs" :mode="multi ? 'multiple' : ''" @click="handleOpen" readOnly :loading="loading">
 | 
			
		||||
      <a-select-option v-for="item in options" :value="item.value">{{ item.text }}</a-select-option>
 | 
			
		||||
    </a-select>
 | 
			
		||||
    <!--popup弹窗-->
 | 
			
		||||
    <JPopupOnlReportModal
 | 
			
		||||
      @register="regModal"
 | 
			
		||||
      :code="code"
 | 
			
		||||
      :multi="multi"
 | 
			
		||||
      :sorter="sorter"
 | 
			
		||||
      :groupId="''"
 | 
			
		||||
      :param="param"
 | 
			
		||||
      @ok="callBack"
 | 
			
		||||
      :getContainer="getContainer"
 | 
			
		||||
    />
 | 
			
		||||
    <!-- update-begin--author:liaozhiyang---date:20240515---for:【QQYUN-9260】必填模式下会影响到弹窗内antd组件的样式 -->
 | 
			
		||||
    <a-form-item>
 | 
			
		||||
      <!--popup弹窗-->
 | 
			
		||||
      <JPopupOnlReportModal
 | 
			
		||||
        @register="regModal"
 | 
			
		||||
        :code="code"
 | 
			
		||||
        :multi="multi"
 | 
			
		||||
        :sorter="sorter"
 | 
			
		||||
        :groupId="''"
 | 
			
		||||
        :param="param"
 | 
			
		||||
        @ok="callBack"
 | 
			
		||||
        :getContainer="getContainer"
 | 
			
		||||
        :showAdvancedButton="showAdvancedButton"
 | 
			
		||||
      />
 | 
			
		||||
    </a-form-item>
 | 
			
		||||
    <!-- update-end--author:liaozhiyang---date:20240515---for:【QQYUN-9260】必填模式下会影响到弹窗内antd组件的样式 -->
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
| 
						 | 
				
			
			@ -52,6 +57,7 @@
 | 
			
		|||
      param: propTypes.object.def({}),
 | 
			
		||||
      spliter: propTypes.string.def(','),
 | 
			
		||||
      getContainer: propTypes.func,
 | 
			
		||||
      showAdvancedButton: propTypes.bool.def(true),
 | 
			
		||||
    },
 | 
			
		||||
    emits: ['update:value', 'register', 'change'],
 | 
			
		||||
    setup(props, { emit }) {
 | 
			
		||||
| 
						 | 
				
			
			@ -74,7 +80,9 @@
 | 
			
		|||
       * 打开pop弹出框
 | 
			
		||||
       */
 | 
			
		||||
      function handleOpen() {
 | 
			
		||||
        !props.disabled && openModal(true);
 | 
			
		||||
        // update-begin--author:liaozhiyang---date:20240528---for:【TV360X-317】禁用后JPopup和JPopupdic还可以点击出弹窗
 | 
			
		||||
        !attrs.value.disabled && openModal(true);
 | 
			
		||||
        // update-end--author:liaozhiyang---date:20240528---for:【TV360X-317】禁用后JPopup和JPopupdic还可以点击出弹窗
 | 
			
		||||
      }
 | 
			
		||||
      /**
 | 
			
		||||
       * 监听value数值
 | 
			
		||||
| 
						 | 
				
			
			@ -195,6 +203,13 @@
 | 
			
		|||
  });
 | 
			
		||||
</script>
 | 
			
		||||
<style lang="less" scoped>
 | 
			
		||||
  // update-begin--author:liaozhiyang---date:20240515---for:【QQYUN-9260】必填模式下会影响到弹窗内antd组件的样式
 | 
			
		||||
  .JPopupDict {
 | 
			
		||||
    > .ant-form-item {
 | 
			
		||||
      display: none;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  // update-end--author:liaozhiyang---date:20240515---for:【QQYUN-9260】必填模式下会影响到弹窗内antd组件的样式
 | 
			
		||||
  .components-input-demo-presuffix {
 | 
			
		||||
    :deep(.ant-select-dropdown) {
 | 
			
		||||
      display: none !important;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,8 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <a-input-group>
 | 
			
		||||
    <a-input :value="beginValue" style="width: calc(50% - 15px)" placeholder="最小值" @change="handleChangeBegin" />
 | 
			
		||||
    <a-input-number v-bind="attrs" :value="beginValue" style="width: calc(50% - 15px)" placeholder="最小值" @change="handleChangeBegin" />
 | 
			
		||||
    <a-input style="width: 30px; border-left: 0; pointer-events: none; background-color: #fff" placeholder="~" disabled />
 | 
			
		||||
    <a-input :value="endValue" style="width: calc(50% - 15px); border-left: 0" placeholder="最大值" @change="handleChangeEnd" />
 | 
			
		||||
    <a-input-number v-bind="attrs" :value="endValue" style="width: calc(50% - 15px); border-left: 0" placeholder="最大值" @change="handleChangeEnd" />
 | 
			
		||||
  </a-input-group>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -13,25 +13,27 @@
 | 
			
		|||
  import { ref, watch } from 'vue';
 | 
			
		||||
  import { Form } from 'ant-design-vue';
 | 
			
		||||
  import { propTypes } from '/@/utils/propTypes';
 | 
			
		||||
  import { useAttrs } from '/@/hooks/core/useAttrs';
 | 
			
		||||
  
 | 
			
		||||
  export default {
 | 
			
		||||
    name: 'JRangeNumber',
 | 
			
		||||
    props: {
 | 
			
		||||
      value: propTypes.oneOfType([propTypes.string, propTypes.array]),
 | 
			
		||||
    },
 | 
			
		||||
    emits: ['change', 'update:value'],
 | 
			
		||||
    emits: ['change', 'update:value', 'blur'],
 | 
			
		||||
    setup(props, { emit }) {
 | 
			
		||||
      const beginValue = ref('');
 | 
			
		||||
      const endValue = ref('');
 | 
			
		||||
      const attrs = useAttrs();
 | 
			
		||||
      const formItemContext = Form.useInjectFormItemContext();
 | 
			
		||||
      
 | 
			
		||||
      function handleChangeBegin(e) {
 | 
			
		||||
        beginValue.value = e.target.value;
 | 
			
		||||
        beginValue.value = e;
 | 
			
		||||
        emitArray();
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      function handleChangeEnd(e) {
 | 
			
		||||
        endValue.value = e.target.value;
 | 
			
		||||
        endValue.value = e;
 | 
			
		||||
        emitArray();
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -58,15 +60,32 @@
 | 
			
		|||
          }
 | 
			
		||||
        }, {immediate: true}
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
      
 | 
			
		||||
      return {
 | 
			
		||||
        beginValue,
 | 
			
		||||
        endValue,
 | 
			
		||||
        handleChangeBegin,
 | 
			
		||||
        handleChangeEnd,
 | 
			
		||||
        attrs,
 | 
			
		||||
      };
 | 
			
		||||
    },
 | 
			
		||||
  };
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped></style>
 | 
			
		||||
<style lang="less" scoped>
 | 
			
		||||
  // update-begin--author:liaozhiyang---date:20240607---for:【TV360X-214】范围查询控件没有根据配置格式化
 | 
			
		||||
  .ant-input-group {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    .ant-input-number {
 | 
			
		||||
      &:first-child {
 | 
			
		||||
        border-top-right-radius: 0;
 | 
			
		||||
        border-bottom-right-radius: 0;
 | 
			
		||||
      }
 | 
			
		||||
      &:last-child {
 | 
			
		||||
        border-top-left-radius: 0;
 | 
			
		||||
        border-bottom-left-radius: 0;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  // update-end--author:liaozhiyang---date:20240607---for:【TV360X-214】范围查询控件没有根据配置格式化
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,6 +11,7 @@
 | 
			
		|||
    :placeholder="placeholder"
 | 
			
		||||
    :filterOption="isDictTable ? false : filterOption"
 | 
			
		||||
    :notFoundContent="loading ? undefined : null"
 | 
			
		||||
    @focus="handleAsyncFocus"
 | 
			
		||||
    @search="loadData"
 | 
			
		||||
    @change="handleAsyncChange"
 | 
			
		||||
  >
 | 
			
		||||
| 
						 | 
				
			
			@ -46,6 +47,8 @@
 | 
			
		|||
  import { useAttrs } from '/@/hooks/core/useAttrs';
 | 
			
		||||
  import { initDictOptions } from '/@/utils/dict/index';
 | 
			
		||||
  import { defHttp } from '/@/utils/http/axios';
 | 
			
		||||
  import { debounce } from 'lodash-es';
 | 
			
		||||
  import { setPopContainer } from '/@/utils';
 | 
			
		||||
 | 
			
		||||
  export default defineComponent({
 | 
			
		||||
    name: 'JSearchSelect',
 | 
			
		||||
| 
						 | 
				
			
			@ -144,7 +147,7 @@
 | 
			
		|||
      /**
 | 
			
		||||
       * 异步查询数据
 | 
			
		||||
       */
 | 
			
		||||
      async function loadData(value) {
 | 
			
		||||
      const loadData = debounce(async function loadData(value) {
 | 
			
		||||
        if (!isDictTable.value) {
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -153,6 +156,9 @@
 | 
			
		|||
        options.value = [];
 | 
			
		||||
        loading.value = true;
 | 
			
		||||
        let keywordInfo = getKeywordParam(value);
 | 
			
		||||
        //update-begin---author:chenrui ---date:2024/4/7  for:[QQYUN-8800]JSearchSelect的search事件在中文输入还没拼字成功时会触发,导致后端SQL注入 #6049------------
 | 
			
		||||
        keywordInfo = keywordInfo.replaceAll("'", '');
 | 
			
		||||
        //update-end---author:chenrui ---date:2024/4/7  for:[QQYUN-8800]JSearchSelect的search事件在中文输入还没拼字成功时会触发,导致后端SQL注入 #6049------------
 | 
			
		||||
        // 字典code格式:table,text,code
 | 
			
		||||
        defHttp
 | 
			
		||||
          .get({
 | 
			
		||||
| 
						 | 
				
			
			@ -168,7 +174,7 @@
 | 
			
		|||
              options.value = res;
 | 
			
		||||
            }
 | 
			
		||||
          });
 | 
			
		||||
      }
 | 
			
		||||
      }, 300);
 | 
			
		||||
      /**
 | 
			
		||||
       * 初始化value
 | 
			
		||||
       */
 | 
			
		||||
| 
						 | 
				
			
			@ -282,6 +288,10 @@
 | 
			
		|||
          loadData('');
 | 
			
		||||
        }
 | 
			
		||||
        callback();
 | 
			
		||||
        // update-begin--author:liaozhiyang---date:20240524---for:【TV360X-426】下拉搜索设置了默认值,把查询条件删掉,再点击重置,没附上值
 | 
			
		||||
        // 点x清空时需要把loadSelectText设置true
 | 
			
		||||
        selectedObj ?? (loadSelectText.value = true);
 | 
			
		||||
        // update-end--author:liaozhiyang---date:20240524---for:【TV360X-426】下拉搜索设置了默认值,把查询条件删掉,再点击重置,没附上值
 | 
			
		||||
      }
 | 
			
		||||
      /**
 | 
			
		||||
       *回调方法
 | 
			
		||||
| 
						 | 
				
			
			@ -311,7 +321,9 @@
 | 
			
		|||
      function getParentContainer(node) {
 | 
			
		||||
        // update-begin-author:taoyan date:20220407 for: getPopupContainer一直有值 导致popContainer的逻辑永远走不进去,把它挪到前面判断
 | 
			
		||||
        if (props.popContainer) {
 | 
			
		||||
          return document.querySelector(props.popContainer);
 | 
			
		||||
          // update-begin--author:liaozhiyang---date:20240517---for:【QQYUN-9339】有多个modal弹窗内都有下拉字典多选和下拉搜索组件时,打开另一个modal时组件的options不展示
 | 
			
		||||
          return setPopContainer(node, props.popContainer);
 | 
			
		||||
          // update-end--author:liaozhiyang---date:20240517---for:【QQYUN-9339】有多个modal弹窗内都有下拉字典多选和下拉搜索组件时,打开另一个modal时组件的options不展示
 | 
			
		||||
        } else {
 | 
			
		||||
          if (typeof props.getPopupContainer === 'function') {
 | 
			
		||||
            return props.getPopupContainer(node);
 | 
			
		||||
| 
						 | 
				
			
			@ -339,7 +351,12 @@
 | 
			
		|||
        }
 | 
			
		||||
      }
 | 
			
		||||
      //update-end-author:taoyan date:2022-8-15 for: VUEN-1971 【online 专项测试】关联记录和他表字段 1
 | 
			
		||||
      
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20240523---for:【TV360X-26】下拉搜索控件选中选项后再次点击下拉应该显示初始的下拉选项,而不是只展示选中结果
 | 
			
		||||
      const handleAsyncFocus = () => {
 | 
			
		||||
        options.value.length && initDictCodeData();
 | 
			
		||||
        attrs.onFocus?.();
 | 
			
		||||
      };
 | 
			
		||||
      // update-end--author:liaozhiyang---date:20240523---for:【TV360X-26】下拉搜索控件选中选项后再次点击下拉应该显示初始的下拉选项,而不是只展示选中结果
 | 
			
		||||
      return {
 | 
			
		||||
        attrs,
 | 
			
		||||
        options,
 | 
			
		||||
| 
						 | 
				
			
			@ -352,6 +369,7 @@
 | 
			
		|||
        filterOption,
 | 
			
		||||
        handleChange,
 | 
			
		||||
        handleAsyncChange,
 | 
			
		||||
        handleAsyncFocus,
 | 
			
		||||
      };
 | 
			
		||||
    },
 | 
			
		||||
  });
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,12 @@
 | 
			
		|||
<!--部门选择组件-->
 | 
			
		||||
<template>
 | 
			
		||||
  <div>
 | 
			
		||||
    <JSelectBiz @handleOpen="handleOpen" :loading="loadingEcho" v-bind="attrs" @change="handleChange"/>
 | 
			
		||||
    <DeptSelectModal @register="regModal" @getSelectResult="setValue" v-bind="getBindValue" :multiple="multiple" />
 | 
			
		||||
  <div class="JSelectDept">
 | 
			
		||||
    <JSelectBiz  @change="handleSelectChange" @handleOpen="handleOpen" :loading="loadingEcho" v-bind="attrs"/>
 | 
			
		||||
    <!-- update-begin--author:liaozhiyang---date:20240515---for:【QQYUN-9260】必填模式下会影响到弹窗内antd组件的样式 -->
 | 
			
		||||
    <a-form-item>
 | 
			
		||||
      <DeptSelectModal @register="regModal" @getSelectResult="setValue" v-bind="getBindValue" :multiple="multiple" @close="handleClose"/>
 | 
			
		||||
    </a-form-item>
 | 
			
		||||
    <!-- update-end--author:liaozhiyang---date:20240515---for:【QQYUN-9260】必填模式下会影响到弹窗内antd组件的样式 -->
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
| 
						 | 
				
			
			@ -14,6 +18,7 @@
 | 
			
		|||
  import { useRuleFormItem } from '/@/hooks/component/useFormItem';
 | 
			
		||||
  import { useAttrs } from '/@/hooks/core/useAttrs';
 | 
			
		||||
  import { SelectValue } from 'ant-design-vue/es/select';
 | 
			
		||||
  import { cloneDeep } from 'lodash-es';
 | 
			
		||||
 | 
			
		||||
  export default defineComponent({
 | 
			
		||||
    name: 'JSelectDept',
 | 
			
		||||
| 
						 | 
				
			
			@ -33,13 +38,15 @@
 | 
			
		|||
      //注册model
 | 
			
		||||
      const [regModal, { openModal }] = useModal();
 | 
			
		||||
      //表单值
 | 
			
		||||
      const [state] = useRuleFormItem(props, 'value', 'change', emitData);
 | 
			
		||||
      // const [state] = useRuleFormItem(props, 'value', 'change', emitData);
 | 
			
		||||
      //下拉框选项值
 | 
			
		||||
      const selectOptions = ref<SelectValue>([]);
 | 
			
		||||
      //下拉框选中值
 | 
			
		||||
      let selectValues = reactive<Recordable>({
 | 
			
		||||
        value: [],
 | 
			
		||||
      });
 | 
			
		||||
      let tempSave: any = [];
 | 
			
		||||
 | 
			
		||||
      // 是否正在加载回显数据
 | 
			
		||||
      const loadingEcho = ref<boolean>(false);
 | 
			
		||||
      //下发 selectOptions,xxxBiz组件接收
 | 
			
		||||
| 
						 | 
				
			
			@ -70,11 +77,13 @@
 | 
			
		|||
      /**
 | 
			
		||||
       * 监听selectValues变化
 | 
			
		||||
       */
 | 
			
		||||
      watch(selectValues, () => {
 | 
			
		||||
        if (selectValues) {
 | 
			
		||||
          state.value = selectValues.value;
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20240527---for:【TV360X-414】部门设置了默认值,查询重置变成空了(同步JSelectUser组件改法)
 | 
			
		||||
      // watch(selectValues, () => {
 | 
			
		||||
      //   if (selectValues) {
 | 
			
		||||
      //     state.value = selectValues.value;
 | 
			
		||||
      //   }
 | 
			
		||||
      // });
 | 
			
		||||
      // update-end--author:liaozhiyang---date:20240527---for:【TV360X-414】部门设置了默认值,查询重置变成空了(同步JSelectUser组件改法)
 | 
			
		||||
      /**
 | 
			
		||||
       * 监听selectOptions变化
 | 
			
		||||
       */
 | 
			
		||||
| 
						 | 
				
			
			@ -100,11 +109,13 @@
 | 
			
		|||
      function initValue() {
 | 
			
		||||
        let value = props.value ? props.value : [];
 | 
			
		||||
        if (value && typeof value === 'string') {
 | 
			
		||||
          state.value = value.split(',');
 | 
			
		||||
          // state.value = value.split(',');
 | 
			
		||||
          selectValues.value = value.split(',');
 | 
			
		||||
          tempSave = value.split(',');
 | 
			
		||||
        } else {
 | 
			
		||||
          // 【VUEN-857】兼容数组(行编辑的用法问题)
 | 
			
		||||
          selectValues.value = value;
 | 
			
		||||
          tempSave = cloneDeep(value);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -114,24 +125,33 @@
 | 
			
		|||
      function setValue(options, values) {
 | 
			
		||||
        selectOptions.value = options;
 | 
			
		||||
        //emitData.value = values.join(",");
 | 
			
		||||
        state.value = values;
 | 
			
		||||
        // state.value = values;
 | 
			
		||||
        selectValues.value = values;
 | 
			
		||||
        emit('update:value', values.join(','));
 | 
			
		||||
        send(values);
 | 
			
		||||
      }
 | 
			
		||||
      const getBindValue = Object.assign({}, unref(props), unref(attrs));
 | 
			
		||||
 | 
			
		||||
      //update-begin---author:wangshuai ---date:20230406  for:【issues/397】在表单中使用v-model:value绑定JSelectDept组件时无法清除已选择的数据------------
 | 
			
		||||
      /**
 | 
			
		||||
       * 值改变事件更新value值
 | 
			
		||||
       * @param values
 | 
			
		||||
       */
 | 
			
		||||
      function handleChange(values) {
 | 
			
		||||
        emit('update:value', values);
 | 
			
		||||
      }
 | 
			
		||||
      //update-end---author:wangshuai ---date:20230406  for:【issues/397】在表单中使用v-model:value绑定JSelectDept组件时无法清除已选择的数据------------
 | 
			
		||||
       // update-begin--author:liaozhiyang---date:20240527---for:【TV360X-414】部门设置了默认值,查询重置变成空了(同步JSelectUser组件改法)
 | 
			
		||||
      const handleClose = () => {
 | 
			
		||||
        if (tempSave.length) {
 | 
			
		||||
          selectValues.value = cloneDeep(tempSave);
 | 
			
		||||
        } else {
 | 
			
		||||
          send(tempSave);
 | 
			
		||||
        }
 | 
			
		||||
      };
 | 
			
		||||
      const handleSelectChange = (values) => {
 | 
			
		||||
        tempSave = cloneDeep(values);
 | 
			
		||||
        send(tempSave);
 | 
			
		||||
      };
 | 
			
		||||
      const send = (values) => {
 | 
			
		||||
        let result = typeof props.value == 'string' ? values.join(',') : values;
 | 
			
		||||
        emit('update:value', result);
 | 
			
		||||
        emit('change', result);
 | 
			
		||||
      };
 | 
			
		||||
      // update-end--author:liaozhiyang---date:20240527---for:【TV360X-414】部门设置了默认值,查询重置变成空了(同步JSelectUser组件改法)
 | 
			
		||||
      
 | 
			
		||||
      return {
 | 
			
		||||
        state,
 | 
			
		||||
        // state,
 | 
			
		||||
        attrs,
 | 
			
		||||
        selectOptions,
 | 
			
		||||
        selectValues,
 | 
			
		||||
| 
						 | 
				
			
			@ -141,12 +161,20 @@
 | 
			
		|||
        regModal,
 | 
			
		||||
        setValue,
 | 
			
		||||
        handleOpen,
 | 
			
		||||
        handleChange
 | 
			
		||||
        handleClose,
 | 
			
		||||
        handleSelectChange,
 | 
			
		||||
      };
 | 
			
		||||
    },
 | 
			
		||||
  });
 | 
			
		||||
</script>
 | 
			
		||||
<style lang="less" scoped>
 | 
			
		||||
  // update-begin--author:liaozhiyang---date:20240515---for:【QQYUN-9260】必填模式下会影响到弹窗内antd组件的样式
 | 
			
		||||
  .JSelectDept {
 | 
			
		||||
    > .ant-form-item {
 | 
			
		||||
      display: none;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  // update-end--author:liaozhiyang---date:20240515---for:【QQYUN-9260】必填模式下会影响到弹窗内antd组件的样式
 | 
			
		||||
  .j-select-row {
 | 
			
		||||
    @width: 82px;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,6 +22,7 @@
 | 
			
		|||
  import { useAttrs } from '/@/hooks/core/useAttrs';
 | 
			
		||||
  import { getDictItems } from '/@/api/common/api';
 | 
			
		||||
  import { useMessage } from '/@/hooks/web/useMessage';
 | 
			
		||||
  import { setPopContainer } from '/@/utils';
 | 
			
		||||
 | 
			
		||||
  const { createMessage, createErrorModal } = useMessage();
 | 
			
		||||
  export default defineComponent({
 | 
			
		||||
| 
						 | 
				
			
			@ -80,7 +81,7 @@
 | 
			
		|||
      const arrayValue = ref<any[]>(!props.value ? [] : props.value.split(props.spliter));
 | 
			
		||||
      const dictOptions = ref<any[]>([]);
 | 
			
		||||
      const attrs = useAttrs();
 | 
			
		||||
      const [state] = useRuleFormItem(props, 'value', 'change', emitData);
 | 
			
		||||
      const [state, , , formItemContext] = useRuleFormItem(props, 'value', 'change', emitData);
 | 
			
		||||
 | 
			
		||||
      onMounted(() => {
 | 
			
		||||
        if (props.dictCode) {
 | 
			
		||||
| 
						 | 
				
			
			@ -118,13 +119,20 @@
 | 
			
		|||
          emit('input', selectedValue.join(props.spliter));
 | 
			
		||||
          emit('update:value', selectedValue.join(props.spliter));
 | 
			
		||||
        }
 | 
			
		||||
        // update-begin--author:liaozhiyang---date:20240429---for:【QQYUN-9110】组件有值校验没消失
 | 
			
		||||
        nextTick(() => {
 | 
			
		||||
          formItemContext?.onFieldChange();
 | 
			
		||||
        });
 | 
			
		||||
        // update-end--author:liaozhiyang---date:20240429---for:【QQYUN-9110】组件有值校验没消失
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      function getParentContainer(node) {
 | 
			
		||||
        if (!props.popContainer) {
 | 
			
		||||
          return node?.parentNode;
 | 
			
		||||
        } else {
 | 
			
		||||
          return document.querySelector(props.popContainer);
 | 
			
		||||
          // update-begin--author:liaozhiyang---date:20240517---for:【QQYUN-9339】有多个modal弹窗内都有下拉字典多选和下拉搜索组件时,打开另一个modal时组件的options不展示
 | 
			
		||||
          return setPopContainer(node, props.popContainer);
 | 
			
		||||
          // update-end--author:liaozhiyang---date:20240517---for:【QQYUN-9339】有多个modal弹窗内都有下拉字典多选和下拉搜索组件时,打开另一个modal时组件的options不展示
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -177,4 +185,4 @@
 | 
			
		|||
    color: #fff;
 | 
			
		||||
    font-size: 12px;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,12 @@
 | 
			
		|||
<!--职务选择组件-->
 | 
			
		||||
<template>
 | 
			
		||||
  <div>
 | 
			
		||||
  <div class="JSelectPosition">
 | 
			
		||||
    <JSelectBiz @handleOpen="handleOpen" :loading="loadingEcho" v-bind="attrs"></JSelectBiz>
 | 
			
		||||
    <PositionSelectModal @register="regModal" @getSelectResult="setValue" v-bind="getBindValue"></PositionSelectModal>
 | 
			
		||||
    <!-- update-begin--author:liaozhiyang---date:20240515---for:【QQYUN-9260】必填模式下会影响到弹窗内antd组件的样式 -->
 | 
			
		||||
    <a-form-item>
 | 
			
		||||
      <PositionSelectModal @register="regModal" @getSelectResult="setValue" v-bind="getBindValue"></PositionSelectModal>
 | 
			
		||||
    </a-form-item>
 | 
			
		||||
    <!-- update-end--author:liaozhiyang---date:20240515---for:【QQYUN-9260】必填模式下会影响到弹窗内antd组件的样式 -->
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
| 
						 | 
				
			
			@ -131,6 +135,13 @@
 | 
			
		|||
  });
 | 
			
		||||
</script>
 | 
			
		||||
<style lang="less" scoped>
 | 
			
		||||
  // update-begin--author:liaozhiyang---date:20240515---for:【QQYUN-9260】必填模式下会影响到弹窗内antd组件的样式
 | 
			
		||||
  .JSelectPosition {
 | 
			
		||||
    > .ant-form-item {
 | 
			
		||||
      display: none;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  // update-end--author:liaozhiyang---date:20240515---for:【QQYUN-9260】必填模式下会影响到弹窗内antd组件的样式
 | 
			
		||||
  .j-select-row {
 | 
			
		||||
    @width: 82px;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,12 @@
 | 
			
		|||
<!--角色选择组件-->
 | 
			
		||||
<template>
 | 
			
		||||
  <div>
 | 
			
		||||
  <div class="JSelectRole">
 | 
			
		||||
    <JSelectBiz @handleOpen="handleOpen" :loading="loadingEcho" v-bind="attrs"></JSelectBiz>
 | 
			
		||||
    <RoleSelectModal @register="regModal" @getSelectResult="setValue" v-bind="getBindValue"></RoleSelectModal>
 | 
			
		||||
    <!-- update-begin--author:liaozhiyang---date:20240515---for:【QQYUN-9260】必填模式下会影响到弹窗内antd组件的样式 -->
 | 
			
		||||
    <a-form-item>
 | 
			
		||||
      <RoleSelectModal @register="regModal" @getSelectResult="setValue" v-bind="getBindValue"></RoleSelectModal>
 | 
			
		||||
    </a-form-item>
 | 
			
		||||
    <!-- update-end--author:liaozhiyang---date:20240515---for:【QQYUN-9260】必填模式下会影响到弹窗内antd组件的样式 -->
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
| 
						 | 
				
			
			@ -132,6 +136,13 @@
 | 
			
		|||
  });
 | 
			
		||||
</script>
 | 
			
		||||
<style lang="less" scoped>
 | 
			
		||||
  // update-begin--author:liaozhiyang---date:20240515---for:【QQYUN-9260】必填模式下会影响到弹窗内antd组件的样式
 | 
			
		||||
  .JSelectRole {
 | 
			
		||||
    > .ant-form-item {
 | 
			
		||||
      display: none;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  // update-end--author:liaozhiyang---date:20240515---for:【QQYUN-9260】必填模式下会影响到弹窗内antd组件的样式
 | 
			
		||||
  .j-select-row {
 | 
			
		||||
    @width: 82px;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
<!--用户选择组件-->
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="JselectUser">
 | 
			
		||||
    <JSelectBiz @change="handleChange" @handleOpen="handleOpen" :loading="loadingEcho" v-bind="attrs"></JSelectBiz>
 | 
			
		||||
    <JSelectBiz @change="handleSelectChange" @handleOpen="handleOpen" :loading="loadingEcho" v-bind="attrs"></JSelectBiz>
 | 
			
		||||
    <!-- update-begin--author:liaozhiyang---date:20240515---for:【QQYUN-9260】必填模式下会影响到弹窗内antd组件的样式 -->
 | 
			
		||||
    <a-form-item>
 | 
			
		||||
      <UserSelectModal
 | 
			
		||||
| 
						 | 
				
			
			@ -10,6 +10,7 @@
 | 
			
		|||
        @getSelectResult="setValue"
 | 
			
		||||
        v-bind="getBindValue"
 | 
			
		||||
        :excludeUserIdList="excludeUserIdList"
 | 
			
		||||
        @close="handleClose"
 | 
			
		||||
      />
 | 
			
		||||
    </a-form-item>
 | 
			
		||||
    <!-- update-end--author:liaozhiyang---date:20240515---for:【QQYUN-9260】必填模式下会影响到弹窗内antd组件的样式 -->
 | 
			
		||||
| 
						 | 
				
			
			@ -25,7 +26,7 @@
 | 
			
		|||
  import { useRuleFormItem } from '/@/hooks/component/useFormItem';
 | 
			
		||||
  import { useAttrs } from '/@/hooks/core/useAttrs';
 | 
			
		||||
  import { SelectValue } from 'ant-design-vue/es/select';
 | 
			
		||||
 | 
			
		||||
  import { cloneDeep } from 'lodash-es';
 | 
			
		||||
  export default defineComponent({
 | 
			
		||||
    name: 'JSelectUser',
 | 
			
		||||
    components: {
 | 
			
		||||
| 
						 | 
				
			
			@ -61,7 +62,7 @@
 | 
			
		|||
      //注册model
 | 
			
		||||
      const [regModal, { openModal }] = useModal();
 | 
			
		||||
      //表单值
 | 
			
		||||
      const [state] = useRuleFormItem(props, 'value', 'change', emitData);
 | 
			
		||||
      // const [state] = useRuleFormItem(props, 'value', 'change', emitData);
 | 
			
		||||
      //下拉框选项值
 | 
			
		||||
      const selectOptions = ref<SelectValue>([]);
 | 
			
		||||
      //下拉框选中值
 | 
			
		||||
| 
						 | 
				
			
			@ -69,6 +70,7 @@
 | 
			
		|||
        value: [],
 | 
			
		||||
        change: false,
 | 
			
		||||
      });
 | 
			
		||||
      let tempSave: any = [];
 | 
			
		||||
      // 是否正在加载回显数据
 | 
			
		||||
      const loadingEcho = ref<boolean>(false);
 | 
			
		||||
      //下发 selectOptions,xxxBiz组件接收
 | 
			
		||||
| 
						 | 
				
			
			@ -95,11 +97,11 @@
 | 
			
		|||
      /**
 | 
			
		||||
       * 监听selectValues变化
 | 
			
		||||
       */
 | 
			
		||||
      watch(selectValues, () => {
 | 
			
		||||
        if (selectValues) {
 | 
			
		||||
          state.value = selectValues.value;
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
      // watch(selectValues, () => {
 | 
			
		||||
      //   if (selectValues) {
 | 
			
		||||
      //     state.value = selectValues.value;
 | 
			
		||||
      //   }
 | 
			
		||||
      // });
 | 
			
		||||
 | 
			
		||||
      //update-begin---author:wangshuai ---date:20230703  for:【QQYUN-5685】5、离职人员可以选自己------------
 | 
			
		||||
      const excludeUserIdList = ref<any>([]);
 | 
			
		||||
| 
						 | 
				
			
			@ -117,6 +119,9 @@
 | 
			
		|||
       */
 | 
			
		||||
      function handleOpen() {
 | 
			
		||||
        tag.value = true;
 | 
			
		||||
        //update-begin-author:liusq---date:2024-06-03--for: [TV360X-840]用户授权,没有选择,点取消,也会回显一个选过的用户
 | 
			
		||||
        tempSave = [];
 | 
			
		||||
        //update-end-author:liusq---date:2024-06-03--for:[TV360X-840]用户授权,没有选择,点取消,也会回显一个选过的用户
 | 
			
		||||
        openModal(true, {
 | 
			
		||||
          isUpdate: false,
 | 
			
		||||
        });
 | 
			
		||||
| 
						 | 
				
			
			@ -128,11 +133,13 @@
 | 
			
		|||
      function initValue() {
 | 
			
		||||
        let value = props.value ? props.value : [];
 | 
			
		||||
        if (value && typeof value === 'string' && value != 'null' && value != 'undefined') {
 | 
			
		||||
          state.value = value.split(',');
 | 
			
		||||
          // state.value = value.split(',');
 | 
			
		||||
          selectValues.value = value.split(',');
 | 
			
		||||
          tempSave = value.split(',');
 | 
			
		||||
        } else {
 | 
			
		||||
          // 【VUEN-857】兼容数组(行编辑的用法问题)
 | 
			
		||||
          selectValues.value = value;
 | 
			
		||||
          tempSave = cloneDeep(value);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -142,27 +149,31 @@
 | 
			
		|||
      function setValue(options, values) {
 | 
			
		||||
        selectOptions.value = options;
 | 
			
		||||
        //emitData.value = values.join(",");
 | 
			
		||||
        state.value = values;
 | 
			
		||||
        // state.value = values;
 | 
			
		||||
        selectValues.value = values;
 | 
			
		||||
        emit('update:value', values.join(','));
 | 
			
		||||
        send(values);
 | 
			
		||||
      }
 | 
			
		||||
      const getBindValue = Object.assign({}, unref(props), unref(attrs));
 | 
			
		||||
 | 
			
		||||
      //update-begin---author:wangshuai ---date:20230711  for:换成异步组件加载,否则会影响到其他页面描述------------
 | 
			
		||||
      /**
 | 
			
		||||
       * 下拉框值改变回调事件
 | 
			
		||||
       * @param values
 | 
			
		||||
       */
 | 
			
		||||
      function handleChange(values) {
 | 
			
		||||
        emit('update:value', values);
 | 
			
		||||
        // update-begin--author:liaozhiyang---date:20240417---for:【QQYUN-8933】选择用户组件触发必填校验之后再填入值校验没触发
 | 
			
		||||
        emit('change', values);
 | 
			
		||||
        // update-end--author:liaozhiyang---date:20240417---for:【QQYUN-8933】选择用户组件触发必填校验之后再填入值校验没触发
 | 
			
		||||
      }
 | 
			
		||||
      //update-end---author:wangshuai ---date:20230711  for:换成异步组件加载,否则会影响到其他页面描述------------
 | 
			
		||||
      
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20240517---for:【QQYUN-9366】用户选择组件取消和关闭会把选择数据带入
 | 
			
		||||
      const handleClose = () => {
 | 
			
		||||
        if (tempSave.length) {
 | 
			
		||||
          selectValues.value = cloneDeep(tempSave);
 | 
			
		||||
        } else {
 | 
			
		||||
          send(tempSave);
 | 
			
		||||
        }
 | 
			
		||||
      };
 | 
			
		||||
      const handleSelectChange = (values) => {
 | 
			
		||||
        tempSave = cloneDeep(values);
 | 
			
		||||
        send(tempSave);
 | 
			
		||||
      };
 | 
			
		||||
      const send = (values) => {
 | 
			
		||||
        let result = typeof props.value == "string" ? values.join(',') : values;
 | 
			
		||||
        emit('update:value', result);
 | 
			
		||||
        emit('change', result);
 | 
			
		||||
      };
 | 
			
		||||
      // update-end--author:liaozhiyang---date:20240517---for:【QQYUN-9366】用户选择组件取消和关闭会把选择数据带入
 | 
			
		||||
      return {
 | 
			
		||||
        state,
 | 
			
		||||
        // state,
 | 
			
		||||
        attrs,
 | 
			
		||||
        selectOptions,
 | 
			
		||||
        getBindValue,
 | 
			
		||||
| 
						 | 
				
			
			@ -173,7 +184,8 @@
 | 
			
		|||
        setValue,
 | 
			
		||||
        handleOpen,
 | 
			
		||||
        excludeUserIdList,
 | 
			
		||||
        handleChange,
 | 
			
		||||
        handleClose,
 | 
			
		||||
        handleSelectChange,
 | 
			
		||||
      };
 | 
			
		||||
    },
 | 
			
		||||
  });
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,6 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <a-tree-select
 | 
			
		||||
    v-if="show"
 | 
			
		||||
    allowClear
 | 
			
		||||
    labelInValue
 | 
			
		||||
    style="width: 100%"
 | 
			
		||||
| 
						 | 
				
			
			@ -22,7 +23,7 @@
 | 
			
		|||
   * 异步树加载组件 通过传入表名 显示字段 存储字段 加载一个树控件
 | 
			
		||||
   * <j-tree-select dict="aa_tree_test,aad,id" pid-field="pid" ></j-tree-select>
 | 
			
		||||
   * */
 | 
			
		||||
  import { ref, watch, unref } from 'vue';
 | 
			
		||||
  import { ref, watch, unref, nextTick } from 'vue';
 | 
			
		||||
  import { defHttp } from '/@/utils/http/axios';
 | 
			
		||||
  import { propTypes } from '/@/utils/propTypes';
 | 
			
		||||
  import { useAttrs } from '/@/hooks/core/useAttrs';
 | 
			
		||||
| 
						 | 
				
			
			@ -57,6 +58,7 @@
 | 
			
		|||
    //默认没有选择框
 | 
			
		||||
    treeCheckAble: propTypes.bool.def(false),
 | 
			
		||||
    //update-end---author:wangshuai date: 20230202 for: 新增是否有复选框
 | 
			
		||||
    hiddenNodeKey: propTypes.string.def(''),
 | 
			
		||||
  });
 | 
			
		||||
  const attrs = useAttrs();
 | 
			
		||||
  const emit = defineEmits(['change', 'update:value']);
 | 
			
		||||
| 
						 | 
				
			
			@ -68,6 +70,7 @@
 | 
			
		|||
  const tableName = ref<any>('');
 | 
			
		||||
  const text = ref<any>('');
 | 
			
		||||
  const code = ref<any>('');
 | 
			
		||||
  const show = ref<boolean>(true);
 | 
			
		||||
  /**
 | 
			
		||||
   * 监听value数据并初始化
 | 
			
		||||
   */
 | 
			
		||||
| 
						 | 
				
			
			@ -87,12 +90,29 @@
 | 
			
		|||
    },
 | 
			
		||||
    { deep: true, immediate: true }
 | 
			
		||||
  );
 | 
			
		||||
  // update-begin--author:liaozhiyang---date:20240529---for:【TV360X-87】树表编辑时不可选自己及子孙节点当父节点
 | 
			
		||||
  watch(
 | 
			
		||||
    () => props.hiddenNodeKey,
 | 
			
		||||
    () => {
 | 
			
		||||
      if (treeData.value?.length && props.hiddenNodeKey) {
 | 
			
		||||
        handleHiddenNode(treeData.value);
 | 
			
		||||
        treeData.value = [...treeData.value];
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  );
 | 
			
		||||
  // update-end--author:liaozhiyang---date:20240529---for:【TV360X-87】树表编辑时不可选自己及子孙节点当父节点
 | 
			
		||||
 | 
			
		||||
  //update-begin-author:taoyan date:2022-5-25 for: VUEN-1056 15、严重——online树表单,添加的时候,父亲节点是空的
 | 
			
		||||
  watch(
 | 
			
		||||
    () => props.reload,
 | 
			
		||||
    async () => {
 | 
			
		||||
      treeData.value = [];
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20240524---for:【TV360X-88】online树表重复新增时父节点数据加载不全且已开的子节点不重新加载
 | 
			
		||||
      show.value = false;
 | 
			
		||||
      nextTick(() => {
 | 
			
		||||
        show.value = true;
 | 
			
		||||
      });
 | 
			
		||||
      // update-end--author:liaozhiyang---date:20240524---for:【TV360X-88】online树表重复新增时父节点数据加载不全且已开的子节点不重新加载
 | 
			
		||||
      await loadRoot();
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -175,6 +195,9 @@
 | 
			
		|||
        i.value = i.key;
 | 
			
		||||
        i.isLeaf = !!i.leaf;
 | 
			
		||||
      }
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20240523---for:【TV360X-87】树表编辑时不可选自己及子孙节点当父节点
 | 
			
		||||
      handleHiddenNode(res.result);
 | 
			
		||||
      // update-end--author:liaozhiyang---date:20240523---for:【TV360X-87】树表编辑时不可选自己及子孙节点当父节点
 | 
			
		||||
      treeData.value = [...res.result];
 | 
			
		||||
    } else {
 | 
			
		||||
      console.log('数根节点查询结果异常', res);
 | 
			
		||||
| 
						 | 
				
			
			@ -208,6 +231,9 @@
 | 
			
		|||
        i.value = i.key;
 | 
			
		||||
        i.isLeaf = !!i.leaf;
 | 
			
		||||
      }
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20240523---for:【TV360X-87】树表编辑时不可选自己及子孙节点当父节点
 | 
			
		||||
      handleHiddenNode(res.result);
 | 
			
		||||
      // update-end--author:liaozhiyang---date:20240523---for:【TV360X-87】树表编辑时不可选自己及子孙节点当父节点
 | 
			
		||||
      //添加子节点
 | 
			
		||||
      addChildren(pid, res.result, treeData.value);
 | 
			
		||||
      treeData.value = [...treeData.value];
 | 
			
		||||
| 
						 | 
				
			
			@ -305,6 +331,9 @@
 | 
			
		|||
        i.key = i.value;
 | 
			
		||||
        i.isLeaf = !!i.leaf;
 | 
			
		||||
      }
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20240523---for:【TV360X-87】树表编辑时不可选自己及子孙节点当父节点
 | 
			
		||||
      handleHiddenNode(res.result);
 | 
			
		||||
      // update-end--author:liaozhiyang---date:20240523---for:【TV360X-87】树表编辑时不可选自己及子孙节点当父节点
 | 
			
		||||
      treeData.value = [...res.result];
 | 
			
		||||
    } else {
 | 
			
		||||
      console.log('数根节点查询结果异常', res);
 | 
			
		||||
| 
						 | 
				
			
			@ -347,6 +376,24 @@
 | 
			
		|||
  }
 | 
			
		||||
  //update-end-author:taoyan date:2022-11-8 for: issues/4173 Online JTreeSelect控件changeOptions方法未生效
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 2024-05-23
 | 
			
		||||
   * liaozhiyang
 | 
			
		||||
   * 过滤掉指定节点(包含其子孙节点)
 | 
			
		||||
   */
 | 
			
		||||
  function handleHiddenNode(data) {
 | 
			
		||||
    if (props.hiddenNodeKey && data?.length) {
 | 
			
		||||
      for (let i = 0, len = data.length; i < len; i++) {
 | 
			
		||||
        const item = data[i];
 | 
			
		||||
        if (item.key == props.hiddenNodeKey) {
 | 
			
		||||
          data.splice(i, 1);
 | 
			
		||||
          i--;
 | 
			
		||||
          len--;
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  // onCreated
 | 
			
		||||
  validateProp().then(() => {
 | 
			
		||||
    initDictInfo();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -408,7 +408,9 @@
 | 
			
		|||
        }
 | 
			
		||||
        /* update-end-author:taoyan date:2022-5-24 for:VUEN-1093详情界面 图片下载按钮显示不全*/
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .ant-upload-text-icon {
 | 
			
		||||
        color: @primary-color;
 | 
			
		||||
      }
 | 
			
		||||
      .ant-upload-list-item {
 | 
			
		||||
        .upload-actions-container {
 | 
			
		||||
          position: absolute;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -63,7 +63,7 @@
 | 
			
		|||
      // update-end--author:liaozhiyang---date:20231220---for:【QQYUN-7678】部门组件内容过多没有滚动条(给一个默认最大高)
 | 
			
		||||
      value: propTypes.oneOfType([propTypes.string, propTypes.array])
 | 
			
		||||
    },
 | 
			
		||||
    emits: ['register', 'getSelectResult'],
 | 
			
		||||
    emits: ['register', 'getSelectResult', 'close'],
 | 
			
		||||
    setup(props, { emit, refs }) {
 | 
			
		||||
      //注册弹框
 | 
			
		||||
      const [register, { closeModal }] = useModalInner();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,7 +28,7 @@
 | 
			
		|||
              </template>
 | 
			
		||||
            </template>
 | 
			
		||||
 | 
			
		||||
            <a-col :md="8" :sm="8">
 | 
			
		||||
            <a-col :md="8" :sm="8" v-if="showAdvancedButton">
 | 
			
		||||
              <span style="float: left; overflow: hidden" class="table-page-search-submitButtons">
 | 
			
		||||
                <a-col :lg="6">
 | 
			
		||||
                  <a-button type="primary" preIcon="ant-design:reload-outlined" @click="searchReset">重置</a-button>
 | 
			
		||||
| 
						 | 
				
			
			@ -82,7 +82,7 @@
 | 
			
		|||
        loading: true,
 | 
			
		||||
      }),
 | 
			
		||||
    },
 | 
			
		||||
    props: ['multi', 'code', 'sorter', 'groupId', 'param'],
 | 
			
		||||
    props: ['multi', 'code', 'sorter', 'groupId', 'param','showAdvancedButton'],
 | 
			
		||||
    emits: ['ok', 'register'],
 | 
			
		||||
    setup(props, { emit, refs }) {
 | 
			
		||||
      const { createMessage } = useMessage();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,8 +8,12 @@
 | 
			
		|||
      :width="showSelected ? '1200px' : '900px'"
 | 
			
		||||
      wrapClassName="j-user-select-modal"
 | 
			
		||||
      @ok="handleOk"
 | 
			
		||||
      @cancel="handleCancel"
 | 
			
		||||
      :maxHeight="maxHeight"
 | 
			
		||||
      :centered="true"
 | 
			
		||||
      destroyOnClose
 | 
			
		||||
      @visible-change="visibleChange"
 | 
			
		||||
      
 | 
			
		||||
    >
 | 
			
		||||
      <a-row>
 | 
			
		||||
        <a-col :span="showSelected ? 18 : 24">
 | 
			
		||||
| 
						 | 
				
			
			@ -81,11 +85,13 @@
 | 
			
		|||
      },
 | 
			
		||||
      //update-end---author:wangshuai ---date:20230703  for:【QQYUN-5685】5、离职人员可以选自己------------
 | 
			
		||||
    },
 | 
			
		||||
    emits: ['register', 'getSelectResult'],
 | 
			
		||||
    emits: ['register', 'getSelectResult', 'close'],
 | 
			
		||||
    setup(props, { emit, refs }) {
 | 
			
		||||
      // update-begin-author:taoyan date:2022-5-24 for: VUEN-1086 【移动端】用户选择 查询按钮 效果不好 列表展示没有滚动条
 | 
			
		||||
      const tableScroll = ref<any>({ x: false });
 | 
			
		||||
      const tableRef = ref();
 | 
			
		||||
      const maxHeight = ref(600);
 | 
			
		||||
 | 
			
		||||
      //注册弹框
 | 
			
		||||
      const [register, { closeModal }] = useModalInner(() => {
 | 
			
		||||
        if (window.innerWidth < 900) {
 | 
			
		||||
| 
						 | 
				
			
			@ -112,7 +118,8 @@
 | 
			
		|||
      const getBindValue = Object.assign({}, unref(props), unref(attrs), config);
 | 
			
		||||
      const [{ rowSelection, visibleChange, selectValues, indexColumnProps, getSelectResult, handleDeleteSelected, selectRows }] = useSelectBiz(
 | 
			
		||||
        getUserList,
 | 
			
		||||
        getBindValue
 | 
			
		||||
        getBindValue,
 | 
			
		||||
        emit
 | 
			
		||||
      );
 | 
			
		||||
      const searchInfo = ref(props.params);
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20230811---for:【issues/657】右侧选中列表删除无效
 | 
			
		||||
| 
						 | 
				
			
			@ -248,8 +255,18 @@
 | 
			
		|||
        }
 | 
			
		||||
        return record;
 | 
			
		||||
      }
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20240517---for:【QQYUN-9366】用户选择组件取消和关闭会把选择数据带入
 | 
			
		||||
      const handleCancel = () => {
 | 
			
		||||
        emit('close');
 | 
			
		||||
      };
 | 
			
		||||
      // update-end--author:liaozhiyang---date:20240517---for:【QQYUN-9366】用户选择组件取消和关闭会把选择数据带入
 | 
			
		||||
      //update-end---author:wangshuai ---date:20230703  for:【QQYUN-5685】5、离职人员可以选自己------------
 | 
			
		||||
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20240607---for:【TV360X-305】小屏幕展示10条
 | 
			
		||||
      const clientHeight = document.documentElement.clientHeight * 200;
 | 
			
		||||
      maxHeight.value = clientHeight > 600 ? 600 : clientHeight;
 | 
			
		||||
      // update-end--author:liaozhiyang---date:20240607---for:【TV360X-305】小屏幕展示10条
 | 
			
		||||
 | 
			
		||||
      return {
 | 
			
		||||
        //config,
 | 
			
		||||
        handleOk,
 | 
			
		||||
| 
						 | 
				
			
			@ -268,6 +285,8 @@
 | 
			
		|||
        tableScroll,
 | 
			
		||||
        tableRef,
 | 
			
		||||
        afterFetch,
 | 
			
		||||
        handleCancel,
 | 
			
		||||
        maxHeight,
 | 
			
		||||
      };
 | 
			
		||||
    },
 | 
			
		||||
  });
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -190,12 +190,17 @@
 | 
			
		|||
        e && prevent(e);
 | 
			
		||||
        searchInputStatus.value = true;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // 回车事件,触发查询
 | 
			
		||||
      function onSearchUser() {
 | 
			
		||||
        console.log('onSearchUser');
 | 
			
		||||
        pageNo.value = 1;
 | 
			
		||||
        loadUserList();
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // 清除按名称筛选
 | 
			
		||||
      function clearSearch(e) {
 | 
			
		||||
        e && prevent(e);
 | 
			
		||||
        pageNo.value = 1;
 | 
			
		||||
        searchText.value = '';
 | 
			
		||||
        searchInputStatus.value = false;
 | 
			
		||||
        loadUserList();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,7 +13,16 @@ export const useCodeHinting = (CodeMirror, keywords, language) => {
 | 
			
		|||
      }, 1e3);
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const codeHintingRegistry = () => {
 | 
			
		||||
    // 自定义关键词(.的上一级)
 | 
			
		||||
    const customKeywords: string[] = [];
 | 
			
		||||
 | 
			
		||||
    currentKeywords.forEach((item) => {
 | 
			
		||||
      if (item.superiors) {
 | 
			
		||||
        customKeywords.push(item.superiors);
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
    const funcsHint = (cm, callback) => {
 | 
			
		||||
      // 获取光标位置
 | 
			
		||||
      const cur = cm.getCursor();
 | 
			
		||||
| 
						 | 
				
			
			@ -22,38 +31,93 @@ export const useCodeHinting = (CodeMirror, keywords, language) => {
 | 
			
		|||
      const start = token.start;
 | 
			
		||||
      const end = cur.ch;
 | 
			
		||||
      const str = token.string;
 | 
			
		||||
      let recordKeyword = null;
 | 
			
		||||
      console.log('光标位置:', cur, '单词信息:', token, `start:${start},end:${end},str:${str}`);
 | 
			
		||||
 | 
			
		||||
      if (str.length) {
 | 
			
		||||
        const findIdx = (a, b) => a.toLowerCase().indexOf(b.toLowerCase());
 | 
			
		||||
        let list = currentKeywords
 | 
			
		||||
          .filter((item) => {
 | 
			
		||||
            const index = findIdx(item, str);
 | 
			
		||||
            return (index === 0 || index === 1) && (item.length != str.length || item.length - 1 != str.length);
 | 
			
		||||
          })
 | 
			
		||||
          .sort((a, b) => {
 | 
			
		||||
            if (findIdx(a, str) < findIdx(b, str)) {
 | 
			
		||||
              return -1;
 | 
			
		||||
            } else {
 | 
			
		||||
              return 1;
 | 
			
		||||
        if (str === '.') {
 | 
			
		||||
          // 查找.前面是否有定义的关键词
 | 
			
		||||
          const curLineCode = cm.getLine(cur.line);
 | 
			
		||||
          for (let i = 0, len = customKeywords.length; i < len; i++) {
 | 
			
		||||
            const k = curLineCode.substring(-1, customKeywords[i].length);
 | 
			
		||||
            if (customKeywords.includes(k)) {
 | 
			
		||||
              recordKeyword = k;
 | 
			
		||||
              break;
 | 
			
		||||
            }
 | 
			
		||||
          });
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        const findIdx = (a, b) => a.toLowerCase().indexOf(b.toLowerCase());
 | 
			
		||||
        let list = currentKeywords.filter((item) => {
 | 
			
		||||
          if (recordKeyword) {
 | 
			
		||||
            // 查特定对象下的属性or方法
 | 
			
		||||
            return item.superiors === recordKeyword;
 | 
			
		||||
          } else {
 | 
			
		||||
            // 查全局属性或者方法
 | 
			
		||||
            return item.superiors == undefined;
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
        if (str === '.') {
 | 
			
		||||
          if (recordKeyword == null) {
 | 
			
		||||
            list = [];
 | 
			
		||||
          }
 | 
			
		||||
        } else {
 | 
			
		||||
          list = list
 | 
			
		||||
            .filter((item) => {
 | 
			
		||||
              const { text } = item;
 | 
			
		||||
              const index = findIdx(text, str);
 | 
			
		||||
              let result = text.startsWith('.') ? index === 1 : index === 0;
 | 
			
		||||
              return result;
 | 
			
		||||
            })
 | 
			
		||||
            .sort((a, b) => {
 | 
			
		||||
              if (findIdx(a.text, str) < findIdx(b.text, str)) {
 | 
			
		||||
                return -1;
 | 
			
		||||
              } else {
 | 
			
		||||
                return 1;
 | 
			
		||||
              }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 有点去掉点
 | 
			
		||||
        // list = list.map(item => {
 | 
			
		||||
        //   if(item.indexOf(".") === 0){
 | 
			
		||||
        //     return item.substring(1);
 | 
			
		||||
        //   }
 | 
			
		||||
        //   return item;
 | 
			
		||||
        // });
 | 
			
		||||
        if (list.length === 1 && (list[0] === str || list[0].substring(1) === str)) {
 | 
			
		||||
          list = [];
 | 
			
		||||
        if (list.length === 1) {
 | 
			
		||||
          // 只有一个时可能是自己输入,输到最后需要去掉提示。
 | 
			
		||||
          const item = list[0];
 | 
			
		||||
          if (item.text === str || item.text.substring(1) === str) {
 | 
			
		||||
            list = [];
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        if (list.length) {
 | 
			
		||||
          // 当str不是点时去掉点
 | 
			
		||||
          if (str != '.') {
 | 
			
		||||
            list = list.map((item) => {
 | 
			
		||||
              if (item.text.indexOf('.') === 0) {
 | 
			
		||||
                return { ...item, text: item.text.substring(1) };
 | 
			
		||||
              }
 | 
			
		||||
              return item;
 | 
			
		||||
            });
 | 
			
		||||
          }
 | 
			
		||||
          callback({
 | 
			
		||||
            list: list,
 | 
			
		||||
            from: CodeMirror.Pos(cur.line, start),
 | 
			
		||||
            to: CodeMirror.Pos(cur.line, end),
 | 
			
		||||
          });
 | 
			
		||||
          // update-begin--author:liaozhiyang---date:20240429---for:【QQYUN-8865】js增强加上鼠标移入提示
 | 
			
		||||
          const item = currentKeywords[0];
 | 
			
		||||
          if (item?.desc) {
 | 
			
		||||
            setTimeout(() => {
 | 
			
		||||
              const elem: HTMLUListElement = document.querySelector('.CodeMirror-hints')!;
 | 
			
		||||
              if (elem) {
 | 
			
		||||
                const childElems = elem.children;
 | 
			
		||||
                Array.from(childElems).forEach((item) => {
 | 
			
		||||
                  const displayText = item.textContent;
 | 
			
		||||
                  const findItem = currentKeywords.find((item) => item.displayText === displayText);
 | 
			
		||||
                  if (findItem) {
 | 
			
		||||
                    item.setAttribute('title', findItem.desc);
 | 
			
		||||
                  }
 | 
			
		||||
                });
 | 
			
		||||
              }
 | 
			
		||||
            }, 0);
 | 
			
		||||
          }
 | 
			
		||||
          // update-end--author:liaozhiyang---date:20240429---for:【QQYUN-8865】js增强加上鼠标移入提示
 | 
			
		||||
        } else {
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    };
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,7 @@ import { inject, reactive, ref, watch, unref, Ref } from 'vue';
 | 
			
		|||
import { useMessage } from '/@/hooks/web/useMessage';
 | 
			
		||||
import { isEmpty } from '@/utils/is';
 | 
			
		||||
 | 
			
		||||
export function useSelectBiz(getList, props) {
 | 
			
		||||
export function useSelectBiz(getList, props, emit) {
 | 
			
		||||
  //接收下拉框选项
 | 
			
		||||
  const selectOptions = inject('selectOptions', ref<Array<object>>([]));
 | 
			
		||||
  //接收已选择的值
 | 
			
		||||
| 
						 | 
				
			
			@ -118,6 +118,10 @@ export function useSelectBiz(getList, props) {
 | 
			
		|||
    if (visible) {
 | 
			
		||||
      //设置列表默认选中
 | 
			
		||||
      props.showSelected && initSelectRows();
 | 
			
		||||
    } else {
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20240517---for:【QQYUN-9366】用户选择组件取消和关闭会把选择数据带入
 | 
			
		||||
      emit('close');
 | 
			
		||||
      // update-end--author:liaozhiyang---date:20240517---for:【QQYUN-9366】用户选择组件取消和关闭会把选择数据带入
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,7 @@ import { inject, reactive, ref, computed, unref, watch, nextTick } from 'vue';
 | 
			
		|||
import { TreeActionType } from '/@/components/Tree';
 | 
			
		||||
import { listToTree } from '/@/utils/common/compUtils';
 | 
			
		||||
 | 
			
		||||
export function useTreeBiz(treeRef, getList, props, realProps) {
 | 
			
		||||
export function useTreeBiz(treeRef, getList, props, realProps, emit) {
 | 
			
		||||
  //接收下拉框选项
 | 
			
		||||
  const selectOptions = inject('selectOptions', ref<Array<object>>([]));
 | 
			
		||||
  //接收已选择的值
 | 
			
		||||
| 
						 | 
				
			
			@ -252,6 +252,9 @@ export function useTreeBiz(treeRef, getList, props, realProps) {
 | 
			
		|||
      await onLoadData(null, null);
 | 
			
		||||
    } else {
 | 
			
		||||
      openModal.value = false;
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20240527---for:【TV360X-414】部门设置了默认值,查询重置变成空了(同步JSelectUser组件改法)
 | 
			
		||||
      emit?.('close');
 | 
			
		||||
      // update-end--author:liaozhiyang---date:20240527---for:【TV360X-414】部门设置了默认值,查询重置变成空了(同步JSelectUser组件改法)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -202,7 +202,10 @@ export interface FormSchema {
 | 
			
		|||
  buss?: any;
 | 
			
		||||
  
 | 
			
		||||
  //label字数控制(label宽度)
 | 
			
		||||
  labelLength?: number
 | 
			
		||||
  labelLength?: number;
 | 
			
		||||
  // update-begin--author:liaozhiyang---date:20240529---for【TV360X-460】basicForm支持v-auth指令(权限控制显隐)
 | 
			
		||||
  auth?: string;
 | 
			
		||||
  // update-end--author:liaozhiyang---date:20240529---for【TV360X-460】basicForm支持v-auth指令(权限控制显隐)
 | 
			
		||||
}
 | 
			
		||||
export interface HelpComponentProps {
 | 
			
		||||
  maxWidth: string;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -105,6 +105,7 @@ export type ComponentType =
 | 
			
		|||
  | 'RangePicker'
 | 
			
		||||
  | 'WeekPicker'
 | 
			
		||||
  | 'TimePicker'
 | 
			
		||||
  | 'DatePickerInFilter'
 | 
			
		||||
  | 'Switch'
 | 
			
		||||
  | 'StrengthMeter'
 | 
			
		||||
  | 'Upload'
 | 
			
		||||
| 
						 | 
				
			
			@ -147,10 +148,13 @@ export type ComponentType =
 | 
			
		|||
  | 'LinkTableSelect'
 | 
			
		||||
  | 'LinkTableForQuery'
 | 
			
		||||
  | 'CascaderPcaForQuery'
 | 
			
		||||
  | 'CascaderPcaInFilter'
 | 
			
		||||
  | 'UserSelect'
 | 
			
		||||
  | 'RoleSelect'
 | 
			
		||||
  | 'RangeDate'
 | 
			
		||||
  | 'RangeNumber'
 | 
			
		||||
  | 'linkRecordSelect'
 | 
			
		||||
  | 'RangeTime'
 | 
			
		||||
  | 'JRangeNumber';
 | 
			
		||||
  | 'JRangeNumber'
 | 
			
		||||
  | 'JInputSelect';
 | 
			
		||||
  
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,198 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <div class="flex justify-between ml-4 mr-5 mb-1" v-if="isSearch">
 | 
			
		||||
    <a-input :placeholder="t('component.icon.search')" v-model:value="searchIconValue" @change="debounceHandleSearchChange" allowClear />
 | 
			
		||||
  </div>
 | 
			
		||||
  <div v-if="getPaginationList.length > 0">
 | 
			
		||||
    <ScrollContainer>
 | 
			
		||||
      <ul class="px-2 icon-list" style="padding-right: 0">
 | 
			
		||||
        <li
 | 
			
		||||
          v-for="icon in getPaginationList"
 | 
			
		||||
          :key="icon"
 | 
			
		||||
          :class="currentSelect === icon ? 'icon-border' : ''"
 | 
			
		||||
          class="p-2 w-1/8 cursor-pointer mr-1 mt-1 flex justify-center items-center border border-solid hover:border-primary"
 | 
			
		||||
          @click="handleClick(icon)"
 | 
			
		||||
          :title="icon"
 | 
			
		||||
        >
 | 
			
		||||
          <SvgIcon v-if="isSvgMode" :name="icon" />
 | 
			
		||||
          <Icon :icon="icon" v-else />
 | 
			
		||||
        </li>
 | 
			
		||||
      </ul>
 | 
			
		||||
    </ScrollContainer>
 | 
			
		||||
    <div class="flex py-2 items-center justify-content-right mr-10 mt-5" v-if="getTotal >= pageSize && isPage">
 | 
			
		||||
      <Pagination
 | 
			
		||||
        showLessItems
 | 
			
		||||
        v-model:current="current"
 | 
			
		||||
        :page-size-options="pageSizeOptions"
 | 
			
		||||
        size="small"
 | 
			
		||||
        v-model:pageSize="pageSize"
 | 
			
		||||
        v-model:total="getTotal"
 | 
			
		||||
        @change="handlePageChange"
 | 
			
		||||
      />
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
  <template v-else
 | 
			
		||||
    ><div class="p-5"><empty /></div>
 | 
			
		||||
  </template>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts" name="icon-list">
 | 
			
		||||
  import { ScrollContainer } from '@/components/Container';
 | 
			
		||||
  import SvgIcon from '@/components/Icon/src/SvgIcon.vue';
 | 
			
		||||
  import Icon from '@/components/Icon/src/Icon.vue';
 | 
			
		||||
  import { defineComponent, ref, unref, watchEffect} from 'vue';
 | 
			
		||||
  import { useDebounceFn } from '@vueuse/core';
 | 
			
		||||
  import { usePagination } from '@/hooks/web/usePagination';
 | 
			
		||||
  import { propTypes } from '@/utils/propTypes';
 | 
			
		||||
  import { useCopyToClipboard } from '@/hooks/web/useCopyToClipboard';
 | 
			
		||||
  import { useI18n } from '@/hooks/web/useI18n';
 | 
			
		||||
  import { useMessage } from '@/hooks/web/useMessage';
 | 
			
		||||
  import { Empty, Pagination } from 'ant-design-vue';
 | 
			
		||||
  export default defineComponent({
 | 
			
		||||
    components: {
 | 
			
		||||
      ScrollContainer,
 | 
			
		||||
      SvgIcon,
 | 
			
		||||
      Icon,
 | 
			
		||||
      Empty,
 | 
			
		||||
      Pagination,
 | 
			
		||||
    },
 | 
			
		||||
    props: {
 | 
			
		||||
      currentList: propTypes.any.def([]),
 | 
			
		||||
      clearSelect: propTypes.bool.def(false),
 | 
			
		||||
      copy: propTypes.bool.def(false),
 | 
			
		||||
      isSvgMode: propTypes.bool.def(false),
 | 
			
		||||
      isPage: propTypes.bool.def(false),
 | 
			
		||||
      isSearch: propTypes.bool.def(false),
 | 
			
		||||
      value: propTypes.string.def(''),
 | 
			
		||||
    },
 | 
			
		||||
    setup(props, { emit }) {
 | 
			
		||||
      //选中的值
 | 
			
		||||
      const currentSelect = ref('');
 | 
			
		||||
      //页数
 | 
			
		||||
      const current = ref<number>(1);
 | 
			
		||||
      //每页条数
 | 
			
		||||
      const pageSize = ref<number>(140);
 | 
			
		||||
      //下拉分页显示
 | 
			
		||||
      const pageSizeOptions = ref<any>(['10', '20', '50', '100', '140']);
 | 
			
		||||
      //下拉搜索值
 | 
			
		||||
      const searchIconValue = ref<string>('');
 | 
			
		||||
      const { clipboardRef, isSuccessRef } = useCopyToClipboard(props.value);
 | 
			
		||||
 | 
			
		||||
      const currentList = ref<any>(props.currentList);
 | 
			
		||||
      const { getPaginationList, getTotal, setCurrentPage, setPageSize } = usePagination(currentList, pageSize.value);
 | 
			
		||||
      const debounceHandleSearchChange = useDebounceFn(handleSearchChange, 100);
 | 
			
		||||
      const { t } = useI18n();
 | 
			
		||||
      const { createMessage } = useMessage();
 | 
			
		||||
      /**
 | 
			
		||||
       * 搜索
 | 
			
		||||
       * @param e
 | 
			
		||||
       */
 | 
			
		||||
      function handleSearchChange(e: ChangeEvent) {
 | 
			
		||||
        const value = e.target.value;
 | 
			
		||||
        console.log("value::::",value)
 | 
			
		||||
        //update-begin---author:wangshuai ---date:20230522  for:【issues/4947】菜单编辑页面菜单图标选择模板,每页显示数量切换无效------------
 | 
			
		||||
        setCurrentPage(1);
 | 
			
		||||
        current.value = 1;
 | 
			
		||||
        //update-end---author:wangshuai ---date:20230522  for:【issues/4947】菜单编辑页面菜单图标选择模板,每页显示数量切换无述------------
 | 
			
		||||
        if (!value) {
 | 
			
		||||
          currentList.value = props.currentList;
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
        currentList.value = props.currentList.filter((item) => item.includes(value));
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      //update-begin---author:wangshuai ---date:20230522  for:【issues/4947】菜单编辑页面菜单图标选择模板,每页显示数量切换无效,输入框后面的图标点击之后清空数据------------
 | 
			
		||||
      /**
 | 
			
		||||
       * 图标点击重置页数
 | 
			
		||||
       */
 | 
			
		||||
      function currentSelectClick() {
 | 
			
		||||
        setCurrentPage(1);
 | 
			
		||||
        setPageSize(140);
 | 
			
		||||
        current.value = 1;
 | 
			
		||||
        pageSize.value = 140;
 | 
			
		||||
        currentList.value = props.currentList;
 | 
			
		||||
        searchIconValue.value = '';
 | 
			
		||||
      }
 | 
			
		||||
      //update-end---author:wangshuai ---date:20230522  for:【issues/4947】菜单编辑页面菜单图标选择模板,每页显示数量切换无效,输入框后面的图标点击之后清空数据------------
 | 
			
		||||
 | 
			
		||||
      function handlePageChange(page: number, size: number) {
 | 
			
		||||
        //update-begin---author:wangshuai ---date:20230522  for:【issues/4947】菜单编辑页面菜单图标选择模板,每页显示数量切换无效------------
 | 
			
		||||
        current.value = page;
 | 
			
		||||
        pageSize.value = size;
 | 
			
		||||
        setPageSize(size);
 | 
			
		||||
        //update-end---author:wangshuai ---date:20230522  for:【issues/4947】菜单编辑页面菜单图标选择模板,每页显示数量切换无效------------
 | 
			
		||||
        setCurrentPage(page);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * 图标点击事件
 | 
			
		||||
       * @param icon
 | 
			
		||||
       */
 | 
			
		||||
      function handleClick(icon: string) {
 | 
			
		||||
        if (props.clearSelect === true) {
 | 
			
		||||
          if (currentSelect.value === icon) {
 | 
			
		||||
            currentSelect.value = '';
 | 
			
		||||
          } else {
 | 
			
		||||
            currentSelect.value = icon;
 | 
			
		||||
          }
 | 
			
		||||
        } else {
 | 
			
		||||
          currentSelect.value = icon;
 | 
			
		||||
          if (props.copy) {
 | 
			
		||||
            clipboardRef.value = icon;
 | 
			
		||||
            if (unref(isSuccessRef)) {
 | 
			
		||||
              createMessage.success(t('component.icon.copy'));
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * 获取图标
 | 
			
		||||
       */
 | 
			
		||||
      function getIcon() {
 | 
			
		||||
        return currentSelect.value;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      watchEffect(() => {
 | 
			
		||||
        currentSelect.value = props.value;
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      return {
 | 
			
		||||
        searchIconValue,
 | 
			
		||||
        debounceHandleSearchChange,
 | 
			
		||||
        getTotal,
 | 
			
		||||
        getPaginationList,
 | 
			
		||||
        handlePageChange,
 | 
			
		||||
        handleClick,
 | 
			
		||||
        currentSelect,
 | 
			
		||||
        t,
 | 
			
		||||
        pageSize,
 | 
			
		||||
        pageSizeOptions,
 | 
			
		||||
        current,
 | 
			
		||||
        getIcon,
 | 
			
		||||
        currentSelectClick,
 | 
			
		||||
      };
 | 
			
		||||
    },
 | 
			
		||||
  });
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped lang="less">
 | 
			
		||||
  ul li {
 | 
			
		||||
    width: 32px;
 | 
			
		||||
    height: 32px;
 | 
			
		||||
    float: left;
 | 
			
		||||
    display: flex;
 | 
			
		||||
    margin: 6px;
 | 
			
		||||
  }
 | 
			
		||||
  ul span {
 | 
			
		||||
    font-size: 1.5rem !important;
 | 
			
		||||
    border: 1px solid #f1f1f1;
 | 
			
		||||
    padding: 0.2rem;
 | 
			
		||||
    margin: 0.3rem;
 | 
			
		||||
  }
 | 
			
		||||
  .icon-border span {
 | 
			
		||||
    border: 1px solid rgba(24, 144, 255) !important;
 | 
			
		||||
  }
 | 
			
		||||
  .justify-content-right {
 | 
			
		||||
    justify-content: right;
 | 
			
		||||
  }
 | 
			
		||||
</style>
 | 
			
		||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| 
						 | 
				
			
			@ -0,0 +1,39 @@
 | 
			
		|||
<!-- 省市县选择组件,在筛选中的用法 -->
 | 
			
		||||
<template>
 | 
			
		||||
  <a-space :class="[prefixCls]" direction="vertical">
 | 
			
		||||
  </a-space>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import {defineComponent} from "vue";
 | 
			
		||||
 | 
			
		||||
export default defineComponent({
 | 
			
		||||
  name: 'CascaderPcaInFilter',
 | 
			
		||||
  inheritAttrs: false,
 | 
			
		||||
})
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<script lang="ts" setup>
 | 
			
		||||
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="less">
 | 
			
		||||
//noinspection LessUnresolvedVariable
 | 
			
		||||
@prefix-cls: ~'@{namespace}-j-cascader-pca-in-filter';
 | 
			
		||||
 | 
			
		||||
.@{prefix-cls} {
 | 
			
		||||
  width: 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.@{prefix-cls}-menu-item-icon {
 | 
			
		||||
  width: 16px;
 | 
			
		||||
  height: 16px;
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
  margin-right: 6px;
 | 
			
		||||
 | 
			
		||||
  &, & + span {
 | 
			
		||||
    vertical-align: middle;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,142 @@
 | 
			
		|||
<!-- 在筛选中使用的日期选择器(可选择今天、本周等范围) -->
 | 
			
		||||
<template>
 | 
			
		||||
  <a-space :id="formItemId" :class="[prefixCls]" direction="vertical">
 | 
			
		||||
    <a-space-compact block>
 | 
			
		||||
      <!-- 日期范围下拉 -->
 | 
			
		||||
      <a-select v-if="isRange" v-model:value="innerValue">
 | 
			
		||||
        <a-select-option v-for="opt of RANGE_OPTIONS" :key="opt.key" :value="opt.key">
 | 
			
		||||
          {{ opt.label }}
 | 
			
		||||
        </a-select-option>
 | 
			
		||||
        <a-select-option key="custom" value="custom">
 | 
			
		||||
          自定义日期
 | 
			
		||||
        </a-select-option>
 | 
			
		||||
      </a-select>
 | 
			
		||||
      <!-- 自定义日期选择器 -->
 | 
			
		||||
      <DatePicker v-else v-model:value="innerValue" v-model:open="datePickerIsOpen" v-bind="attrs"/>
 | 
			
		||||
      <!-- 右侧下拉菜单 -->
 | 
			
		||||
      <a-dropdown v-if="allowSelectRange" :trigger="['click']">
 | 
			
		||||
        <a-button preIcon="ant-design:menu-unfold"/>
 | 
			
		||||
        <template #overlay>
 | 
			
		||||
          <a-menu @click="onMenuClick">
 | 
			
		||||
            <a-menu-item v-for="opt of RANGE_OPTIONS" :key="opt.key">
 | 
			
		||||
              {{ opt.label }}
 | 
			
		||||
            </a-menu-item>
 | 
			
		||||
            <a-menu-item key="custom">
 | 
			
		||||
              自定义日期
 | 
			
		||||
            </a-menu-item>
 | 
			
		||||
          </a-menu>
 | 
			
		||||
        </template>
 | 
			
		||||
      </a-dropdown>
 | 
			
		||||
    </a-space-compact>
 | 
			
		||||
  </a-space>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import {defineComponent} from "vue";
 | 
			
		||||
 | 
			
		||||
export default defineComponent({
 | 
			
		||||
  name: 'DatePickerInFilter',
 | 
			
		||||
  inheritAttrs: false,
 | 
			
		||||
})
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<script lang="ts" setup>
 | 
			
		||||
import {ref, watch, computed, nextTick, useAttrs, defineProps} from 'vue'
 | 
			
		||||
import {DatePicker} from 'ant-design-vue'
 | 
			
		||||
import {useDesign} from '/@/hooks/web/useDesign';
 | 
			
		||||
import { Form } from 'ant-design-vue';
 | 
			
		||||
const formItemContext = Form.useInjectFormItemContext();
 | 
			
		||||
 | 
			
		||||
// 日期范围选项
 | 
			
		||||
const RANGE_OPTIONS = [
 | 
			
		||||
  {key: 'TODAY', label: '今天'},
 | 
			
		||||
  {key: 'YESTERDAY', label: '昨天'},
 | 
			
		||||
  {key: 'TOMORROW', label: '明天'},
 | 
			
		||||
  {key: 'THIS_WEEK', label: '本周'},
 | 
			
		||||
  {key: 'LAST_WEEK', label: '上周'},
 | 
			
		||||
  {key: 'NEXT_WEEK', label: '下周'},
 | 
			
		||||
  {key: 'LAST_7_DAYS', label: '过去七天'},
 | 
			
		||||
  {key: 'THIS_MONTH', label: '本月'},
 | 
			
		||||
  {key: 'LAST_MONTH', label: '上月'},
 | 
			
		||||
  {key: 'NEXT_MONTH', label: '下月'},
 | 
			
		||||
];
 | 
			
		||||
const RANGE_OPTION_KEYS = RANGE_OPTIONS.map(item => item.key)
 | 
			
		||||
 | 
			
		||||
const {prefixCls} = useDesign('j-data-picker-in-filter');
 | 
			
		||||
const props = defineProps({
 | 
			
		||||
  value: {
 | 
			
		||||
    type: [String],
 | 
			
		||||
    default: ''
 | 
			
		||||
  },
 | 
			
		||||
  // 是否允许选择预设范围
 | 
			
		||||
  allowSelectRange: {
 | 
			
		||||
    type: Boolean,
 | 
			
		||||
    default: true,
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
const emit = defineEmits(['change', 'update:value'])
 | 
			
		||||
const attrs = useAttrs()
 | 
			
		||||
 | 
			
		||||
// 组件id
 | 
			
		||||
const formItemId  = computed(() => formItemContext.id.value)
 | 
			
		||||
 | 
			
		||||
const innerValue = ref(props.value)
 | 
			
		||||
// 是否打开日期选择器
 | 
			
		||||
const datePickerIsOpen = ref(false)
 | 
			
		||||
 | 
			
		||||
// 判断是否为范围选项
 | 
			
		||||
const isRange = computed(() => RANGE_OPTION_KEYS.includes(innerValue.value));
 | 
			
		||||
 | 
			
		||||
// 同步value
 | 
			
		||||
watch(() => props.value, (val) => {
 | 
			
		||||
  innerValue.value = val
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
// emit 更改
 | 
			
		||||
watch(innerValue, (val) => {
 | 
			
		||||
  if (val === 'custom') {
 | 
			
		||||
    val = ''
 | 
			
		||||
    openDatePicker()
 | 
			
		||||
  }
 | 
			
		||||
  emit('change', val)
 | 
			
		||||
  emit('update:value', val)
 | 
			
		||||
  // update-begin--author:liaozhiyang---date:20240509---for:【QQYUN-9227】日期校验没清空
 | 
			
		||||
  formItemContext?.onFieldChange();
 | 
			
		||||
  // update-end--author:liaozhiyang---date:20240509---for:【QQYUN-9227】日期校验没清空
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
watch(() => props.allowSelectRange, (allow) => {
 | 
			
		||||
  // 如果不允许选择范围,且当前值为范围选项,则清空值
 | 
			
		||||
  if (!allow && isRange.value) {
 | 
			
		||||
    innerValue.value = ''
 | 
			
		||||
  }
 | 
			
		||||
}, {immediate: true});
 | 
			
		||||
 | 
			
		||||
// 点击右侧下拉菜单
 | 
			
		||||
function onMenuClick(event: Recordable) {
 | 
			
		||||
  if (event.key === 'custom') {
 | 
			
		||||
    if (isRange.value) {
 | 
			
		||||
      innerValue.value = '';
 | 
			
		||||
    }
 | 
			
		||||
    openDatePicker()
 | 
			
		||||
  } else {
 | 
			
		||||
    innerValue.value = event.key
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 打开日期选择器下拉
 | 
			
		||||
async function openDatePicker() {
 | 
			
		||||
  await nextTick()
 | 
			
		||||
  datePickerIsOpen.value = true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="less">
 | 
			
		||||
//noinspection LessUnresolvedVariable
 | 
			
		||||
@prefix-cls: ~'@{namespace}-j-data-picker-in-filter';
 | 
			
		||||
 | 
			
		||||
.@{prefix-cls} {
 | 
			
		||||
  width: 100%;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,2 @@
 | 
			
		|||
export {default as DatePickerInFilter} from './DatePickerInFilter.vue';
 | 
			
		||||
export {default as CascaderPcaInFilter} from './CascaderPcaInFilter.vue';
 | 
			
		||||
| 
						 | 
				
			
			@ -2,7 +2,6 @@ import { registerComponent, registerAsyncComponent, registerASyncComponentReal }
 | 
			
		|||
import { JVxeTypes } from '/@/components/jeecg/JVxeTable/types';
 | 
			
		||||
import { DictSearchSpanCell, DictSearchInputCell } from './src/components/JVxeSelectDictSearchCell';
 | 
			
		||||
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
 | 
			
		||||
 | 
			
		||||
export async function registerJVxeCustom() {
 | 
			
		||||
  // ----------------- ⚠ 注意事项 ⚠ -----------------
 | 
			
		||||
  //  当组件内包含 BasicModal 时,必须使用异步引入!
 | 
			
		||||
| 
						 | 
				
			
			@ -24,8 +23,11 @@ export async function registerJVxeCustom() {
 | 
			
		|||
  // 注册【部门选择】组件
 | 
			
		||||
  await registerAsyncComponent(JVxeTypes.departSelect, import('./src/components/JVxeDepartSelectCell.vue'));
 | 
			
		||||
  // 注册【省市区选择】组件
 | 
			
		||||
  // await registerAsyncComponent(JVxeTypes.pca, import('./src/components/JVxePcaCell.vue'));
 | 
			
		||||
  // update-begin--author:liaozhiyang---date:20240308---for:【QQYUN-8241】为避免首次加载china-area-data,JVxePcaCell组件需异步加载
 | 
			
		||||
  registerASyncComponentReal(
 | 
			
		||||
    JVxeTypes.pca,
 | 
			
		||||
    createAsyncComponent(() => import('./src/components/JVxePcaCell.vue'))
 | 
			
		||||
  );
 | 
			
		||||
  // update-end--author:liaozhiyang---date:20240308---for:【QQYUN-8241】为避免首次加载china-area-data,JVxePcaCell组件需异步加载
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,7 +17,7 @@
 | 
			
		|||
          <span style="margin-left: 5px">{{ ellipsisFileName }}</span>
 | 
			
		||||
        </a-tooltip>
 | 
			
		||||
 | 
			
		||||
        <Dropdown :trigger="['click']" placement="bottomRight" style="margin-left: 10px" :disabled="cellProps.disabled">
 | 
			
		||||
        <Dropdown :trigger="['click']" placement="bottomRight" style="margin-left: 10px">
 | 
			
		||||
          <a-tooltip title="操作">
 | 
			
		||||
            <Icon v-if="file.status !== 'uploading'" icon="ant-design:setting" style="cursor: pointer" />
 | 
			
		||||
          </a-tooltip>
 | 
			
		||||
| 
						 | 
				
			
			@ -26,10 +26,10 @@
 | 
			
		|||
              <a-menu-item v-if="originColumn.allowDownload !== false" @click="handleClickDownloadFile">
 | 
			
		||||
                <span><Icon icon="ant-design:download" /> 下载</span>
 | 
			
		||||
              </a-menu-item>
 | 
			
		||||
              <a-menu-item v-if="originColumn.allowRemove !== false" @click="handleClickDeleteFile">
 | 
			
		||||
              <a-menu-item :disabled="cellProps.disabled" v-if="originColumn.allowRemove !== false" @click="handleClickDeleteFile">
 | 
			
		||||
                <span><Icon icon="ant-design:delete" /> 删除</span>
 | 
			
		||||
              </a-menu-item>
 | 
			
		||||
              <a-menu-item @click="handleMoreOperation">
 | 
			
		||||
              <a-menu-item :disabled="cellProps.disabled" @click="handleMoreOperation">
 | 
			
		||||
                <span><Icon icon="ant-design:bars" /> 更多</span>
 | 
			
		||||
              </a-menu-item>
 | 
			
		||||
            </a-menu>
 | 
			
		||||
| 
						 | 
				
			
			@ -39,6 +39,7 @@
 | 
			
		|||
    </template>
 | 
			
		||||
 | 
			
		||||
    <a-upload
 | 
			
		||||
      v-if="cellProps.allDisable"
 | 
			
		||||
      v-show="!hasFile"
 | 
			
		||||
      name="file"
 | 
			
		||||
      :data="{ isup: 1 }"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,7 +9,7 @@
 | 
			
		|||
        </template>
 | 
			
		||||
        <template v-else-if="file['path']">
 | 
			
		||||
          <template v-for="src of imgList">
 | 
			
		||||
            <img class="j-vxe-image" :src="src" alt="图片错误" @[clickEvent]="handleMoreOperation" />
 | 
			
		||||
            <img class="j-vxe-image" :src="src" alt="图片错误" @[clickEvent]="handleMoreOperation" @click="handlePreview" />
 | 
			
		||||
          </template>
 | 
			
		||||
        </template>
 | 
			
		||||
        <a-tooltip v-else :title="file.message || '上传失败'" @[clickEvent]="handleClickShowImageError">
 | 
			
		||||
| 
						 | 
				
			
			@ -17,8 +17,9 @@
 | 
			
		|||
        </a-tooltip>
 | 
			
		||||
      </div>
 | 
			
		||||
    </template>
 | 
			
		||||
    <div class="j-vxe-image-upload">
 | 
			
		||||
    <div class="j-vxe-image-upload" v-if="cellProps.allDisable">
 | 
			
		||||
      <a-upload
 | 
			
		||||
        :accept="acceptFileType"
 | 
			
		||||
        name="file"
 | 
			
		||||
        :data="{ isup: 1 }"
 | 
			
		||||
        :multiple="false"
 | 
			
		||||
| 
						 | 
				
			
			@ -45,6 +46,7 @@
 | 
			
		|||
  import { UploadTypeEnum } from '/@/components/Form/src/jeecg/components/JUpload';
 | 
			
		||||
  import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
 | 
			
		||||
  import { components, enhanced, useFileCell } from '../hooks/useFileCell';
 | 
			
		||||
  import { createImgPreview } from '/@/components/Preview/index';
 | 
			
		||||
 | 
			
		||||
  export default defineComponent({
 | 
			
		||||
    name: 'JVxeImageCell',
 | 
			
		||||
| 
						 | 
				
			
			@ -54,6 +56,9 @@
 | 
			
		|||
      
 | 
			
		||||
      const { createErrorModal } = useMessage();
 | 
			
		||||
      const setup = useFileCell(props, UploadTypeEnum.image, { multiple: true });
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20240604---for:【TV360X-470】jVxetable上传图片组件限制类型
 | 
			
		||||
      const acceptFileType = 'image/*';
 | 
			
		||||
      // update-end--author:liaozhiyang---date:20240604---for:【TV360X-470】jVxetable上传图片组件限制类型
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20240105---for:【issues/953】online子表vxe-table展现形式详情图片上传可点击
 | 
			
		||||
      const clickEvent = computed(() => {
 | 
			
		||||
        return unref(setup.cellProps).disabled ? null : 'click';
 | 
			
		||||
| 
						 | 
				
			
			@ -84,13 +89,21 @@
 | 
			
		|||
          });
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20240523---for:【TV360X-121】jvxetable文件组件禁用状态(详情)下可下载
 | 
			
		||||
      const handlePreview = () => {
 | 
			
		||||
        if (unref(setup.cellProps).disabled) {
 | 
			
		||||
          createImgPreview({ imageList: imgList.value });
 | 
			
		||||
        }
 | 
			
		||||
      };
 | 
			
		||||
      // update-end--author:liaozhiyang---date:20240523---for:【TV360X-121】jvxetable文件组件禁用状态(详情)下可下载
 | 
			
		||||
      return {
 | 
			
		||||
        ...setup,
 | 
			
		||||
        imgList,
 | 
			
		||||
        maxCount,
 | 
			
		||||
        handleClickShowImageError,
 | 
			
		||||
        clickEvent
 | 
			
		||||
        clickEvent,
 | 
			
		||||
        handlePreview,
 | 
			
		||||
        acceptFileType,
 | 
			
		||||
      };
 | 
			
		||||
    },
 | 
			
		||||
    // 【组件增强】注释详见:JVxeComponent.Enhanced
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -63,6 +63,11 @@ export function useFileCell(props, fileType: UploadTypeEnum, options?) {
 | 
			
		|||
  // 更多上传回调
 | 
			
		||||
  function onModalChange(path) {
 | 
			
		||||
    if (path) {
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20240524---for:【TV360X-235】富文本禁用状态下图片上传按钮文字看不清
 | 
			
		||||
      if (innerFile.value === null) {
 | 
			
		||||
        innerFile.value = {};
 | 
			
		||||
      }
 | 
			
		||||
      // update-end-author:liaozhiyang---date:20240524---for:【TV360X-235】富文本禁用状态下图片上传按钮文字看不清
 | 
			
		||||
      innerFile.value.path = path;
 | 
			
		||||
      handleChangeCommon(innerFile.value);
 | 
			
		||||
    } else {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -112,8 +112,46 @@
 | 
			
		|||
        const insEditor = new Vditor(wrapEl, {
 | 
			
		||||
          theme: getDarkMode.value === 'dark' ? 'dark' : 'classic',
 | 
			
		||||
          lang: unref(getCurrentLang),
 | 
			
		||||
          // update-begin--author:liaozhiyang---date:20240520---for:【TV360X-146】Markdown组件去掉录音选项
 | 
			
		||||
          toolbar: [
 | 
			
		||||
            'emoji',
 | 
			
		||||
            'headings',
 | 
			
		||||
            'bold',
 | 
			
		||||
            'italic',
 | 
			
		||||
            'strike',
 | 
			
		||||
            'link',
 | 
			
		||||
            '|',
 | 
			
		||||
            'list',
 | 
			
		||||
            'ordered-list',
 | 
			
		||||
            'check',
 | 
			
		||||
            'outdent',
 | 
			
		||||
            'indent',
 | 
			
		||||
            '|',
 | 
			
		||||
            'quote',
 | 
			
		||||
            'line',
 | 
			
		||||
            'code',
 | 
			
		||||
            'inline-code',
 | 
			
		||||
            'insert-before',
 | 
			
		||||
            'insert-after',
 | 
			
		||||
            '|',
 | 
			
		||||
            'upload',
 | 
			
		||||
            // 'record',
 | 
			
		||||
            'table',
 | 
			
		||||
            '|',
 | 
			
		||||
            'undo',
 | 
			
		||||
            'redo',
 | 
			
		||||
            '|',
 | 
			
		||||
            'fullscreen',
 | 
			
		||||
            'edit-mode',
 | 
			
		||||
            {
 | 
			
		||||
              name: 'more',
 | 
			
		||||
              toolbar: ['both', 'code-theme', 'content-theme', 'export', 'outline', 'preview', 'devtools', 'info', 'help'],
 | 
			
		||||
            },
 | 
			
		||||
          ],
 | 
			
		||||
          // update-end--author:liaozhiyang---date:20240520---for:【TV360X-146】Markdown组件去掉录音选项
 | 
			
		||||
          mode: 'sv',
 | 
			
		||||
          cdn: 'https://cdn.jsdelivr.net/npm/vditor@3.9.6',
 | 
			
		||||
          // cdn: 'https://cdn.jsdelivr.net/npm/vditor@3.9.6',
 | 
			
		||||
          cdn: 'https://unpkg.com/vditor@3.10.1',
 | 
			
		||||
          fullscreen: {
 | 
			
		||||
            index: 520,
 | 
			
		||||
          },
 | 
			
		||||
| 
						 | 
				
			
			@ -186,3 +224,10 @@
 | 
			
		|||
    },
 | 
			
		||||
  });
 | 
			
		||||
</script>
 | 
			
		||||
<style lang="less" scoped>
 | 
			
		||||
  // update-begin--author:liaozhiyang---date:20240527---for:【TV360X-318】解决markdown控件禁用状态放大按钮还可以点击
 | 
			
		||||
  :deep(.vditor-menu--disabled) {
 | 
			
		||||
    pointer-events: none;
 | 
			
		||||
  }
 | 
			
		||||
  // update-end--author:liaozhiyang---date:20240527---for:【TV360X-318】解决markdown控件禁用状态放大按钮还可以点击
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,7 +25,7 @@
 | 
			
		|||
  import { MenuModeEnum, MenuTypeEnum } from '/@/enums/menuEnum';
 | 
			
		||||
  import { useOpenKeys } from './useOpenKeys';
 | 
			
		||||
  import { RouteLocationNormalizedLoaded, useRouter } from 'vue-router';
 | 
			
		||||
  import { isFunction } from '/@/utils/is';
 | 
			
		||||
  import { isFunction, isUrl } from '/@/utils/is';
 | 
			
		||||
  import { basicProps } from './props';
 | 
			
		||||
  import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
 | 
			
		||||
  import { REDIRECT_NAME } from '/@/router/constant';
 | 
			
		||||
| 
						 | 
				
			
			@ -33,6 +33,9 @@
 | 
			
		|||
  import { getCurrentParentPath } from '/@/router/menus';
 | 
			
		||||
  import { listenerRouteChange } from '/@/logics/mitt/routeChange';
 | 
			
		||||
  import { getAllParentPath } from '/@/router/helper/menuHelper';
 | 
			
		||||
  import { createBasicRootMenuContext } from './useBasicMenuContext';
 | 
			
		||||
  import { URL_HASH_TAB } from '/@/utils';
 | 
			
		||||
  import { getMenus } from '/@/router/menus';
 | 
			
		||||
 | 
			
		||||
  export default defineComponent({
 | 
			
		||||
    name: 'BasicMenu',
 | 
			
		||||
| 
						 | 
				
			
			@ -52,7 +55,9 @@
 | 
			
		|||
        selectedKeys: [],
 | 
			
		||||
        collapsedOpenKeys: [],
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20230326---for:【QQYUN-8691】顶部菜单模式online不显示菜单名显示默认的auto在线表单
 | 
			
		||||
      createBasicRootMenuContext({ menuState: menuState });
 | 
			
		||||
      // update-end--author:liaozhiyang---date:20230326---for:【QQYUN-8691】顶部菜单模式online不显示菜单名显示默认的auto在线表单
 | 
			
		||||
      const { prefixCls } = useDesign('basic-menu');
 | 
			
		||||
      const { items, mode, accordion } = toRefs(props);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -112,11 +117,43 @@
 | 
			
		|||
      //update-begin-author:taoyan date:2022-6-1 for: VUEN-1144 online 配置成菜单后,打开菜单,显示名称未展示为菜单名称
 | 
			
		||||
      async function handleMenuClick({ item, key }: { item: any; key: string; keyPath: string[] }) {
 | 
			
		||||
        const { beforeClickFn } = props;
 | 
			
		||||
        // update-begin--author:liaozhiyang---date:20240402---for:【QQYUN-8773】配置外部网址在顶部菜单模式和搜索打不开
 | 
			
		||||
        if (isUrl(key)) {
 | 
			
		||||
          key = key.replace(URL_HASH_TAB, '#');
 | 
			
		||||
          window.open(key);
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
        // update-end--author:liaozhiyang---date:20240402---for:【QQYUN-8773】配置外部网址在顶部菜单模式和搜索打不开
 | 
			
		||||
        if (beforeClickFn && isFunction(beforeClickFn)) {
 | 
			
		||||
          const flag = await beforeClickFn(key);
 | 
			
		||||
          if (!flag) return;
 | 
			
		||||
        }
 | 
			
		||||
        emit('menuClick', key, item);
 | 
			
		||||
        // update-begin--author:liaozhiyang---date:20240418---for:【QQYUN-8773】顶部混合导航(顶部左侧组合菜单)一级菜单没有配置redirect默认跳子菜单的第一个
 | 
			
		||||
        if (props.type === MenuTypeEnum.MIX) {
 | 
			
		||||
          const menus = await getMenus();
 | 
			
		||||
          const menuItem = getMatchingPath(menus, key);
 | 
			
		||||
          if (menuItem && !menuItem.redirect && menuItem.children?.length) {
 | 
			
		||||
            const subMenuItem = getSubMenu(menuItem.children);
 | 
			
		||||
            if (subMenuItem?.path) {
 | 
			
		||||
              const path = subMenuItem.redirect ?? subMenuItem.path;
 | 
			
		||||
              let _key = path;
 | 
			
		||||
              if (isUrl(path)) {
 | 
			
		||||
                window.open(path);
 | 
			
		||||
                // 外部打开emit出去的key不能是url,否则左侧菜单出不来
 | 
			
		||||
                _key = key;
 | 
			
		||||
              }
 | 
			
		||||
              emit('menuClick', _key, { title: subMenuItem.title });
 | 
			
		||||
            } else {
 | 
			
		||||
              emit('menuClick', key, item);
 | 
			
		||||
            }
 | 
			
		||||
          } else {
 | 
			
		||||
            emit('menuClick', key, item);
 | 
			
		||||
          }
 | 
			
		||||
        } else {
 | 
			
		||||
          emit('menuClick', key, item);
 | 
			
		||||
        }
 | 
			
		||||
        // emit('menuClick', key, item);
 | 
			
		||||
        // update-begin--author:liaozhiyang---date:20240418---for:【QQYUN-8773】顶部混合导航(顶部左侧组合菜单)一级菜单没有配置redirect默认跳子菜单的第一个
 | 
			
		||||
        //update-end-author:taoyan date:2022-6-1 for: VUEN-1144 online 配置成菜单后,打开菜单,显示名称未展示为菜单名称
 | 
			
		||||
 | 
			
		||||
        isClickGo.value = true;
 | 
			
		||||
| 
						 | 
				
			
			@ -142,6 +179,45 @@
 | 
			
		|||
          menuState.selectedKeys = parentPaths;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      /**
 | 
			
		||||
       * liaozhiyang
 | 
			
		||||
       * 2024-05-18
 | 
			
		||||
       * 获取指定菜单下的第一个菜单
 | 
			
		||||
       */
 | 
			
		||||
      function getSubMenu(menus) {
 | 
			
		||||
        for (let i = 0, len = menus.length; i < len; i++) {
 | 
			
		||||
          const item = menus[i];
 | 
			
		||||
          if (item.path && !item.children?.length) {
 | 
			
		||||
            return item;
 | 
			
		||||
          } else if (item.children?.length) {
 | 
			
		||||
            const result = getSubMenu(item.children);
 | 
			
		||||
            if (result) {
 | 
			
		||||
              return result;
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * liaozhiyang
 | 
			
		||||
       * 2024-05-18
 | 
			
		||||
       * 获取匹配path的菜单
 | 
			
		||||
       */
 | 
			
		||||
      function getMatchingPath(menus, path) {
 | 
			
		||||
        for (let i = 0, len = menus.length; i < len; i++) {
 | 
			
		||||
          const item = menus[i];
 | 
			
		||||
          if (item.path === path) {
 | 
			
		||||
            return item;
 | 
			
		||||
          } else if (item.children?.length) {
 | 
			
		||||
            const result = getMatchingPath(item.children, path);
 | 
			
		||||
            if (result) {
 | 
			
		||||
              return result;
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return {
 | 
			
		||||
        handleMenuClick,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <BasicMenuItem v-if="!menuHasChildren(item) && getShowMenu" v-bind="$props" />
 | 
			
		||||
  <SubMenu v-if="menuHasChildren(item) && getShowMenu" :class="[theme]" :key="`submenu-${item.path}`" popupClassName="app-top-menu-popup">
 | 
			
		||||
  <SubMenu v-if="menuHasChildren(item) && getShowMenu" :class="[theme]" :key="`submenu-${item.path}`" :popupClassName="prefixCls">
 | 
			
		||||
    <template #title>
 | 
			
		||||
      <MenuItemContent v-bind="$props" :item="item" />
 | 
			
		||||
    </template>
 | 
			
		||||
| 
						 | 
				
			
			@ -12,14 +12,17 @@
 | 
			
		|||
</template>
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
  import type { Menu as MenuType } from '/@/router/types';
 | 
			
		||||
  import { defineComponent, computed } from 'vue';
 | 
			
		||||
  import { defineComponent, computed, watch } from 'vue';
 | 
			
		||||
  import { Menu } from 'ant-design-vue';
 | 
			
		||||
  import { useDesign } from '/@/hooks/web/useDesign';
 | 
			
		||||
  import { checkChildrenHidden } from '/@/utils/common/compUtils';
 | 
			
		||||
  import { itemProps } from '../props';
 | 
			
		||||
  import BasicMenuItem from './BasicMenuItem.vue';
 | 
			
		||||
  import MenuItemContent from './MenuItemContent.vue';
 | 
			
		||||
 | 
			
		||||
  import { useBasicRootMenuContext } from '../useBasicMenuContext';
 | 
			
		||||
  import { useLocaleStore } from '/@/store/modules/locale';
 | 
			
		||||
  import { getMenus } from '/@/router/menus';
 | 
			
		||||
  
 | 
			
		||||
  export default defineComponent({
 | 
			
		||||
    name: 'BasicSubMenuItem',
 | 
			
		||||
    isSubMenu: true,
 | 
			
		||||
| 
						 | 
				
			
			@ -30,8 +33,10 @@
 | 
			
		|||
    },
 | 
			
		||||
    props: itemProps,
 | 
			
		||||
    setup(props) {
 | 
			
		||||
      const { prefixCls } = useDesign('basic-menu-item');
 | 
			
		||||
 | 
			
		||||
      const { prefixCls } = useDesign('basic-subMenu');
 | 
			
		||||
      const { menuState } = useBasicRootMenuContext();
 | 
			
		||||
      const localeStore = useLocaleStore();
 | 
			
		||||
      
 | 
			
		||||
      const getShowMenu = computed(() => !props.item.meta?.hideMenu);
 | 
			
		||||
      function menuHasChildren(menuTreeItem: MenuType): boolean {
 | 
			
		||||
        return (
 | 
			
		||||
| 
						 | 
				
			
			@ -42,6 +47,34 @@
 | 
			
		|||
          &&checkChildrenHidden(menuTreeItem)
 | 
			
		||||
        );
 | 
			
		||||
      }
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20230326---for:【QQYUN-8691】顶部菜单模式online不显示菜单名显示默认的auto在线表单
 | 
			
		||||
      const getMatchingRouterName = (menus, path) => {
 | 
			
		||||
        for (let i = 0, len = menus.length; i < len; i++) {
 | 
			
		||||
          const item = menus[i];
 | 
			
		||||
          if (item.path === path && !item.redirect && !item.paramPath) {
 | 
			
		||||
            return item.meta?.title;
 | 
			
		||||
          } else if (item.children?.length) {
 | 
			
		||||
            const result = getMatchingRouterName(item.children, path);
 | 
			
		||||
            if (result) {
 | 
			
		||||
              return result;
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        return '';
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      watch(
 | 
			
		||||
        () => menuState.selectedKeys,
 | 
			
		||||
        async (value) => {
 | 
			
		||||
          if (value.length && value.includes(props.item.path)) {
 | 
			
		||||
            const menus = await getMenus();
 | 
			
		||||
            const getTitle = getMatchingRouterName(menus, props.item.path);
 | 
			
		||||
            localeStore.setPathTitle(props.item.path, getTitle ? getTitle : props.item.name);
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        { immediate: true }
 | 
			
		||||
      );
 | 
			
		||||
      // update-end--author:liaozhiyang---date:20230326---for:【QQYUN-8691】顶部菜单模式online不显示菜单名显示默认的auto在线表单
 | 
			
		||||
      return {
 | 
			
		||||
        prefixCls,
 | 
			
		||||
        menuHasChildren,
 | 
			
		||||
| 
						 | 
				
			
			@ -51,3 +84,51 @@
 | 
			
		|||
    },
 | 
			
		||||
  });
 | 
			
		||||
</script>
 | 
			
		||||
<style lang="less">
 | 
			
		||||
  // update-begin--author:liaozhiyang---date:20240407---for:【QQYUN-8762】顶部模式下拉菜单颜色统一
 | 
			
		||||
  @prefix-cls: ~'@{namespace}-basic-subMenu';
 | 
			
		||||
  html[data-theme='light'] {
 | 
			
		||||
    .@{prefix-cls}.ant-menu-dark {
 | 
			
		||||
      background-color: var(--header-bg-color);
 | 
			
		||||
      color: rgba(255, 255, 255, 0.9);
 | 
			
		||||
      &.ant-menu-submenu {
 | 
			
		||||
        > .ant-menu {
 | 
			
		||||
          background-color: var(--header-bg-color);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      .ant-menu-item-selected {
 | 
			
		||||
        background-color: var(--header-active-menu-bg-color);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    //【QQYUN-8922】顶部导航三个点菜单样式调整
 | 
			
		||||
    .ant-menu-submenu-placement-bottomLeft.ant-menu-dark.ant-menu-submenu-popup {
 | 
			
		||||
      background-color: var(--header-bg-color);
 | 
			
		||||
      &.ant-menu-dark.ant-menu-submenu > .ant-menu {
 | 
			
		||||
        background-color: var(--header-bg-color);
 | 
			
		||||
        color: rgba(255, 255, 255, 0.9);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  // update-end--author:liaozhiyang---date:20240407---for:【QQYUN-8762】顶部模式下拉菜单颜色统一
 | 
			
		||||
  // update-begin--author:liaozhiyang---date:20240429---for:【QQYUN-9128】暗黑主题顶部模式下拉菜单颜色统一
 | 
			
		||||
  html[data-theme='dark'] {
 | 
			
		||||
    @bgcolor:#212121;
 | 
			
		||||
    .@{prefix-cls}.ant-menu-dark {
 | 
			
		||||
      background-color: @bgcolor;
 | 
			
		||||
      &.ant-menu-submenu {
 | 
			
		||||
        > .ant-menu {
 | 
			
		||||
          background-color: @bgcolor;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    //【QQYUN-8922】顶部导航三个点菜单样式调整
 | 
			
		||||
    .ant-menu-submenu-placement-bottomLeft.ant-menu-dark.ant-menu-submenu-popup {
 | 
			
		||||
      background-color: @bgcolor;
 | 
			
		||||
      &.ant-menu-dark.ant-menu-submenu > .ant-menu {
 | 
			
		||||
        background-color: @bgcolor;
 | 
			
		||||
        color: rgba(255, 255, 255, 0.9);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  // update-end--author:liaozhiyang---date:20240429---for:【QQYUN-9128】暗黑主题顶部模式下拉菜单颜色统一
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,7 +18,9 @@
 | 
			
		|||
 | 
			
		||||
      &.ant-menu-dark {
 | 
			
		||||
        background-color: transparent;
 | 
			
		||||
 | 
			
		||||
        // update-begin--author:liaozhiyang---date:20240407---for:【QQYUN-8762】顶部菜单模式文字调整
 | 
			
		||||
        color: rgba(255 ,255 ,255, 1);
 | 
			
		||||
        // update-end--author:liaozhiyang---date:20240407---for:【QQYUN-8762】顶部菜单模式文字调整
 | 
			
		||||
        .ant-menu-submenu:hover,
 | 
			
		||||
        .ant-menu-item-open,
 | 
			
		||||
        .ant-menu-submenu-open,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,16 @@
 | 
			
		|||
import type { InjectionKey, Ref } from 'vue';
 | 
			
		||||
import { createContext, useContext } from '/@/hooks/core/useContext';
 | 
			
		||||
 | 
			
		||||
export interface BasicRootMenuContextProps {
 | 
			
		||||
  menuState: any;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const key: InjectionKey<BasicRootMenuContextProps> = Symbol();
 | 
			
		||||
 | 
			
		||||
export function createBasicRootMenuContext(context: BasicRootMenuContextProps) {
 | 
			
		||||
  return createContext<BasicRootMenuContextProps>(context, key, { readonly: false, native: true });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function useBasicRootMenuContext() {
 | 
			
		||||
  return useContext<BasicRootMenuContextProps>(key);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -73,7 +73,7 @@
 | 
			
		|||
    components: { Modal, ModalWrapper, ModalClose, ModalFooter, ModalHeader },
 | 
			
		||||
    inheritAttrs: false,
 | 
			
		||||
    props: basicProps,
 | 
			
		||||
    emits: ['visible-change', 'open-change', 'height-change', 'cancel', 'ok', 'register', 'update:visible', 'update:open', 'fullScreen'],
 | 
			
		||||
    emits: ['visible-change', 'open-change', 'height-change', 'cancel', 'ok', 'register', 'update:visible', 'update:open', 'fullScreen','comment-open'],
 | 
			
		||||
    setup(props, { emit, attrs , slots}) {
 | 
			
		||||
      const visibleRef = ref(false);
 | 
			
		||||
      const propsRef = ref<Partial<ModalProps> | null>(null);
 | 
			
		||||
| 
						 | 
				
			
			@ -183,6 +183,7 @@
 | 
			
		|||
        () => unref(visibleRef),
 | 
			
		||||
        (v) => {
 | 
			
		||||
          emit('visible-change', v);
 | 
			
		||||
          emit('open-change', v);
 | 
			
		||||
          emit('update:visible', v);
 | 
			
		||||
          emit('update:open', v);
 | 
			
		||||
          instance && modalMethods.emitVisible?.(v, instance.uid);
 | 
			
		||||
| 
						 | 
				
			
			@ -263,6 +264,9 @@
 | 
			
		|||
        }else{
 | 
			
		||||
          commentSpan.value = 0
 | 
			
		||||
        }
 | 
			
		||||
        // update-begin--author:liaozhiyang---date:20240528---for:【TV360X-485】开启评论之后弹窗按钮居右隔一个评论的距离
 | 
			
		||||
        emit('comment-open', commentSpan.value === 0, commentSpan.value);
 | 
			
		||||
        // update-end--author:liaozhiyang---date:20240528---for:【TV360X-485】开启评论之后弹窗按钮居右隔一个评论的距离
 | 
			
		||||
      }
 | 
			
		||||
      //update-end-author:taoyan date:2022-7-18 for: modal支持评论 slot
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,327 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <a-modal v-bind="getBindValue" @cancel="handleCancel" :body-style="!fullScreenRef ? bodyStyle : {}">
 | 
			
		||||
    <slot></slot>
 | 
			
		||||
    <template #closeIcon v-if="!$slots.closeIcon">
 | 
			
		||||
      <div class="jeecg-basic-modal-close" v-if="canFullscreen">
 | 
			
		||||
        <Tooltip :title="t('component.modal.restore')" placement="bottom" v-if="fullScreenRef">
 | 
			
		||||
          <FullscreenExitOutlined role="full" @click="handleFullScreen" />
 | 
			
		||||
        </Tooltip>
 | 
			
		||||
        <Tooltip :title="t('component.modal.maximize')" placement="bottom" v-else>
 | 
			
		||||
          <FullscreenOutlined role="close" @click="handleFullScreen" />
 | 
			
		||||
        </Tooltip>
 | 
			
		||||
        <Tooltip :title="t('component.modal.close')" placement="bottom">
 | 
			
		||||
          <CloseOutlined @click="handleCancel" />
 | 
			
		||||
        </Tooltip>
 | 
			
		||||
      </div>
 | 
			
		||||
    </template>
 | 
			
		||||
 | 
			
		||||
    <template #title v-if="!isNoTitle">
 | 
			
		||||
      <ModalHeader :helpMessage="getProps.helpMessage" :title="getMergeProps.title" @dblclick="handleTitleDbClick" />
 | 
			
		||||
    </template>
 | 
			
		||||
 | 
			
		||||
    <template #footer v-if="!$slots.footer">
 | 
			
		||||
      <ModalFooter v-bind="getBindValue" @ok="handleOk" @cancel="handleCancel">
 | 
			
		||||
        <template #[item]="data" v-for="item in Object.keys($slots)">
 | 
			
		||||
          <slot :name="item" v-bind="data || {}"></slot>
 | 
			
		||||
        </template>
 | 
			
		||||
      </ModalFooter>
 | 
			
		||||
    </template>
 | 
			
		||||
 | 
			
		||||
    <template #[item]="data" v-for="item in Object.keys(omit($slots, 'default'))">
 | 
			
		||||
      <slot :name="item" v-bind="data || {}"></slot>
 | 
			
		||||
    </template>
 | 
			
		||||
  </a-modal>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts" name="j-modal">
 | 
			
		||||
  import { computed, defineComponent, getCurrentInstance, ref, toRef, unref, watch, watchEffect } from 'vue';
 | 
			
		||||
  import ModalFooter from '@/components/Modal/src/components/ModalFooter.vue';
 | 
			
		||||
  import ModalClose from '@/components/Modal/src/components/ModalClose.vue';
 | 
			
		||||
  import ModalHeader from '@/components/Modal/src/components/ModalHeader.vue';
 | 
			
		||||
  import { omit } from 'lodash-es';
 | 
			
		||||
  import { useAppInject } from '@/hooks/web/useAppInject';
 | 
			
		||||
  import type { ModalMethods, ModalProps } from '@/components/Modal';
 | 
			
		||||
  import { CloseOutlined, FullscreenExitOutlined, FullscreenOutlined } from '@ant-design/icons-vue';
 | 
			
		||||
  import { Tooltip } from 'ant-design-vue';
 | 
			
		||||
  import { useI18n } from '@/hooks/web/useI18n';
 | 
			
		||||
  import { deepMerge } from '@/utils';
 | 
			
		||||
  import { basicProps } from '@/components/Modal/src/props';
 | 
			
		||||
  import Modal from '/@/components/Modal/src/components/Modal';
 | 
			
		||||
  import { isFunction } from '@/utils/is';
 | 
			
		||||
  export default defineComponent({
 | 
			
		||||
    name: 'JModal',
 | 
			
		||||
    methods: { omit },
 | 
			
		||||
    components: {
 | 
			
		||||
      CloseOutlined,
 | 
			
		||||
      Tooltip,
 | 
			
		||||
      FullscreenExitOutlined,
 | 
			
		||||
      FullscreenOutlined,
 | 
			
		||||
      ModalHeader,
 | 
			
		||||
      ModalClose,
 | 
			
		||||
      ModalFooter,
 | 
			
		||||
      Modal,
 | 
			
		||||
    },
 | 
			
		||||
    props: {
 | 
			
		||||
      //是否全屏
 | 
			
		||||
      fullscreen: {
 | 
			
		||||
        type: Boolean,
 | 
			
		||||
        default: false,
 | 
			
		||||
      },
 | 
			
		||||
      ...basicProps,
 | 
			
		||||
    },
 | 
			
		||||
    emits: ['visible-change', 'open-change', 'height-change', 'cancel', 'ok', 'register', 'update:visible', 'update:open', 'fullScreen'],
 | 
			
		||||
    setup(props, { emit, attrs, slots }) {
 | 
			
		||||
      const { getIsMobile } = useAppInject();
 | 
			
		||||
      const visibleRef = ref(false);
 | 
			
		||||
      const propsRef = ref<Partial<ModalProps> | null>(null);
 | 
			
		||||
      const fullScreenRef = ref<any>(props.fullscreen);
 | 
			
		||||
      const fullScreen = ref<boolean>(false);
 | 
			
		||||
      const { t } = useI18n();
 | 
			
		||||
      const bodyStyle = ref<any>({
 | 
			
		||||
        height: props.maxHeight ? props.maxHeight : '600px',
 | 
			
		||||
        'overflow-y': 'auto',
 | 
			
		||||
      });
 | 
			
		||||
      const modalMethods: ModalMethods = {
 | 
			
		||||
        setModalProps,
 | 
			
		||||
        emitVisible: undefined,
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      const getMergeProps = computed((): Recordable => {
 | 
			
		||||
        const result = {
 | 
			
		||||
          ...props,
 | 
			
		||||
          ...(unref(propsRef) as any),
 | 
			
		||||
        };
 | 
			
		||||
        if (getIsMobile.value) {
 | 
			
		||||
          result.fullscreen = false;
 | 
			
		||||
        }
 | 
			
		||||
        return result;
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      const getBindValue = computed((): Recordable => {
 | 
			
		||||
        const attr = {
 | 
			
		||||
          ...attrs,
 | 
			
		||||
          ...unref(getMergeProps),
 | 
			
		||||
          open: unref(visibleRef),
 | 
			
		||||
          wrapClassName: unref(getWrapClassName),
 | 
			
		||||
        };
 | 
			
		||||
        if (unref(fullScreenRef)) {
 | 
			
		||||
          return omit(attr, ['height', 'visible']);
 | 
			
		||||
        }
 | 
			
		||||
        return omit(attr, ['visible']);
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      //整合warpClassName
 | 
			
		||||
      const getWrapClassName = computed(() => {
 | 
			
		||||
        const clsName = toRef(getMergeProps.value, 'wrapClassName').value || '';
 | 
			
		||||
        return unref(fullScreenRef) ? `jeecg-full-screen-modal-code-generate ${clsName} ` : unref(clsName);
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      //获取props
 | 
			
		||||
      const getProps = computed((): Recordable => {
 | 
			
		||||
        const opt = {
 | 
			
		||||
          ...unref(getMergeProps),
 | 
			
		||||
          visible: unref(visibleRef),
 | 
			
		||||
          okButtonProps: undefined,
 | 
			
		||||
          cancelButtonProps: undefined,
 | 
			
		||||
          title: undefined,
 | 
			
		||||
        };
 | 
			
		||||
        return {
 | 
			
		||||
          ...opt,
 | 
			
		||||
          wrapClassName: unref(getWrapClassName),
 | 
			
		||||
        };
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      //注册model,instance.uid 避免多个model冲突
 | 
			
		||||
      const instance = getCurrentInstance();
 | 
			
		||||
      if (instance) {
 | 
			
		||||
        emit('register', modalMethods, instance.uid);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * 是否含有标题
 | 
			
		||||
       */
 | 
			
		||||
      function isNoTitle() {
 | 
			
		||||
        //标题为空并且不含有标题插槽
 | 
			
		||||
        return !unref(getMergeProps).title && !slots.title;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * 放大缩小事件
 | 
			
		||||
       * @param e
 | 
			
		||||
       */
 | 
			
		||||
      function handleFullScreen(e: Event) {
 | 
			
		||||
        e?.stopPropagation();
 | 
			
		||||
        e?.preventDefault();
 | 
			
		||||
        fullScreenRef.value = !unref(fullScreenRef);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // 取消事件
 | 
			
		||||
      async function handleCancel(e: Event) {
 | 
			
		||||
        e?.stopPropagation();
 | 
			
		||||
        // 过滤自定义关闭按钮的空白区域
 | 
			
		||||
        if (props.closeFunc && isFunction(props.closeFunc)) {
 | 
			
		||||
          const isClose: boolean = await props.closeFunc();
 | 
			
		||||
          visibleRef.value = !isClose;
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
        visibleRef.value = false;
 | 
			
		||||
        emit('cancel', e);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * 确定事件
 | 
			
		||||
       * @param e
 | 
			
		||||
       */
 | 
			
		||||
      function handleOk(e: Event) {
 | 
			
		||||
        emit('ok', e);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      function handleTitleDbClick(e) {
 | 
			
		||||
        if (!props.fullscreen) return;
 | 
			
		||||
        e.stopPropagation();
 | 
			
		||||
        handleFullScreen(e);
 | 
			
		||||
      }
 | 
			
		||||
      /**
 | 
			
		||||
       * 设置modal参数
 | 
			
		||||
       */
 | 
			
		||||
      function setModalProps(props: Partial<ModalProps>): void {
 | 
			
		||||
        // Keep the last setModalProps
 | 
			
		||||
        propsRef.value = deepMerge(unref(propsRef) || ({} as any), props);
 | 
			
		||||
        if (Reflect.has(props, 'visible')) {
 | 
			
		||||
          visibleRef.value = !!props.visible;
 | 
			
		||||
        }
 | 
			
		||||
        if (Reflect.has(props, 'open')) {
 | 
			
		||||
          visibleRef.value = !!props.open;
 | 
			
		||||
        }
 | 
			
		||||
        if (Reflect.has(props, 'defaultFullscreen')) {
 | 
			
		||||
          fullScreenRef.value = !!props.defaultFullscreen;
 | 
			
		||||
          if (getIsMobile.value) {
 | 
			
		||||
            fullScreenRef.value = true;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * 监听放大缩小
 | 
			
		||||
       */
 | 
			
		||||
      watchEffect(() => {
 | 
			
		||||
        fullScreenRef.value = props.fullscreen;
 | 
			
		||||
        if (getIsMobile.value) {
 | 
			
		||||
          fullScreenRef.value = true;
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * 监听model的显示隐藏
 | 
			
		||||
       */
 | 
			
		||||
      watchEffect(() => {
 | 
			
		||||
        visibleRef.value = !!props.visible;
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * 监听model的显示隐藏
 | 
			
		||||
       */
 | 
			
		||||
      watchEffect(() => {
 | 
			
		||||
        visibleRef.value = !!props.open;
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      watch(
 | 
			
		||||
        () => unref(visibleRef),
 | 
			
		||||
        (v) => {
 | 
			
		||||
          emit('visible-change', v);
 | 
			
		||||
          emit('open-change', v);
 | 
			
		||||
          emit('update:visible', v);
 | 
			
		||||
          emit('update:open', v);
 | 
			
		||||
          instance && modalMethods.emitVisible?.(v, instance.uid);
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          immediate: false,
 | 
			
		||||
        }
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
      return {
 | 
			
		||||
        isNoTitle,
 | 
			
		||||
        getBindValue,
 | 
			
		||||
        fullScreenRef,
 | 
			
		||||
        handleFullScreen,
 | 
			
		||||
        fullScreen,
 | 
			
		||||
        t,
 | 
			
		||||
        handleCancel,
 | 
			
		||||
        handleOk,
 | 
			
		||||
        getProps,
 | 
			
		||||
        getMergeProps,
 | 
			
		||||
        handleTitleDbClick,
 | 
			
		||||
        bodyStyle,
 | 
			
		||||
      };
 | 
			
		||||
    },
 | 
			
		||||
  });
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="less" scoped>
 | 
			
		||||
  /*begin 放大关闭按钮样式*/
 | 
			
		||||
  .jeecg-basic-modal-close {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    height: 95%;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
 | 
			
		||||
    > span {
 | 
			
		||||
      margin-left: 10px;
 | 
			
		||||
      font-size: 16px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    &--can-full {
 | 
			
		||||
      > span {
 | 
			
		||||
        margin-left: 12px;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    &:not(&--can-full) {
 | 
			
		||||
      > span:nth-child(1) {
 | 
			
		||||
        &:hover {
 | 
			
		||||
          font-weight: 700;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    & span:nth-child(1) {
 | 
			
		||||
      display: inline-block;
 | 
			
		||||
      padding: 10px;
 | 
			
		||||
 | 
			
		||||
      &:hover {
 | 
			
		||||
        color: @primary-color;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    & span:last-child {
 | 
			
		||||
      padding: 10px 10px 10px 0;
 | 
			
		||||
      &:hover {
 | 
			
		||||
        color: @error-color;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  /*end 放大关闭按钮样式*/
 | 
			
		||||
</style>
 | 
			
		||||
 | 
			
		||||
<style lang="less">
 | 
			
		||||
  /*begin 全屏弹窗modal样式*/
 | 
			
		||||
  .jeecg-full-screen-modal-code-generate {
 | 
			
		||||
    .ant-modal {
 | 
			
		||||
      max-width: 100%;
 | 
			
		||||
      top: 0 !important;
 | 
			
		||||
      padding-bottom: 0 !important;
 | 
			
		||||
      margin: 0 !important;
 | 
			
		||||
      width: 100% !important;
 | 
			
		||||
      overflow-y: auto;
 | 
			
		||||
    }
 | 
			
		||||
    .ant-modal-content {
 | 
			
		||||
      display: flex;
 | 
			
		||||
      flex-direction: column;
 | 
			
		||||
      height: calc(100vh);
 | 
			
		||||
    }
 | 
			
		||||
    .ant-modal-body {
 | 
			
		||||
      flex: 1;
 | 
			
		||||
      overflow-y: auto;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  /*end 全屏弹窗modal样式*/
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			@ -46,34 +46,50 @@
 | 
			
		|||
      useWindowSizeFn(setModalHeight.bind(null, false));
 | 
			
		||||
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:2024-04-18---for:【QQYUN-9035】basicModal不设置maxHeight或height会一直执行setModalHeight,需即使销毁MutationObserver
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:2024-05-30---for:【TV360X-145】将弹窗还原全屏后,关闭再打开窗口变小了
 | 
			
		||||
      let observer,
 | 
			
		||||
        recordCount: any = {};
 | 
			
		||||
      if (!(props.maxHeight || props.height)) {
 | 
			
		||||
        observer = useMutationObserver(
 | 
			
		||||
          spinRef,
 | 
			
		||||
          () => {
 | 
			
		||||
            setModalHeight({
 | 
			
		||||
              source: 'muob',
 | 
			
		||||
              callBack: (height) => {
 | 
			
		||||
                const count = recordCount[height];
 | 
			
		||||
                if (count) {
 | 
			
		||||
                  recordCount[height] = ++recordCount[height];
 | 
			
		||||
                  if (count > 5) {
 | 
			
		||||
                    observer.stop();
 | 
			
		||||
                    recordCount = null;
 | 
			
		||||
                  }
 | 
			
		||||
                } else {
 | 
			
		||||
                  recordCount[height] = 1;
 | 
			
		||||
                }
 | 
			
		||||
      watch(
 | 
			
		||||
        () => props.visible,
 | 
			
		||||
        () => {
 | 
			
		||||
          if (props.visible && !observer && !(props.maxHeight || props.height)) {
 | 
			
		||||
            recordCount = {};
 | 
			
		||||
            observer = useMutationObserver(
 | 
			
		||||
              spinRef,
 | 
			
		||||
              () => {
 | 
			
		||||
                setModalHeight({
 | 
			
		||||
                  source: 'muob',
 | 
			
		||||
                  callBack: (height) => {
 | 
			
		||||
                    const count = recordCount[height];
 | 
			
		||||
                    if (count) {
 | 
			
		||||
                      recordCount[height] = ++recordCount[height];
 | 
			
		||||
                      if (count > 10) {
 | 
			
		||||
                        observer.stop();
 | 
			
		||||
                        recordCount = {};
 | 
			
		||||
                        observer = null;
 | 
			
		||||
                      }
 | 
			
		||||
                    } else {
 | 
			
		||||
                      recordCount = {};
 | 
			
		||||
                      recordCount[height] = 1;
 | 
			
		||||
                    }
 | 
			
		||||
                  },
 | 
			
		||||
                });
 | 
			
		||||
              },
 | 
			
		||||
            });
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            attributes: true,
 | 
			
		||||
            subtree: true,
 | 
			
		||||
              {
 | 
			
		||||
                attributes: true,
 | 
			
		||||
                subtree: true,
 | 
			
		||||
              }
 | 
			
		||||
            );
 | 
			
		||||
          } else {
 | 
			
		||||
            if (observer) {
 | 
			
		||||
              observer.stop();
 | 
			
		||||
              observer = null;
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        );
 | 
			
		||||
      }
 | 
			
		||||
        },
 | 
			
		||||
        { immediate: true }
 | 
			
		||||
      );
 | 
			
		||||
      // update-end--author:liaozhiyang---date:2024-05-30---for:【TV360X-145】将弹窗还原全屏后,关闭再打开窗口变小了
 | 
			
		||||
      // update-end--author:liaozhiyang---date:2024-04-18---for:【QQYUN-9035】basicModal不设置maxHeight或height会一直执行setModalHeight,需即使销毁MutationObserver
 | 
			
		||||
 | 
			
		||||
      createModalContext({
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,12 +3,12 @@
 | 
			
		|||
    v-bind="getBindValues"
 | 
			
		||||
    :activeName="activeName"
 | 
			
		||||
    :openNames="getOpenKeys"
 | 
			
		||||
    :class="prefixCls"
 | 
			
		||||
    :class="`${prefixCls} ${isThemeBright ? 'bright' : ''}`"
 | 
			
		||||
    :activeSubMenuNames="activeSubMenuNames"
 | 
			
		||||
    @select="handleSelect"
 | 
			
		||||
  >
 | 
			
		||||
    <template v-for="item in items" :key="item.path">
 | 
			
		||||
      <SimpleSubMenu :item="item" :parent="true" :collapsedShowTitle="collapsedShowTitle" :collapse="collapse" />
 | 
			
		||||
      <SimpleSubMenu :isThemeBright="isThemeBright" :item="item" :parent="true" :collapsedShowTitle="collapsedShowTitle" :collapse="collapse" />
 | 
			
		||||
    </template>
 | 
			
		||||
  </Menu>
 | 
			
		||||
</template>
 | 
			
		||||
| 
						 | 
				
			
			@ -29,6 +29,7 @@
 | 
			
		|||
 | 
			
		||||
  import { useOpenKeys } from './useOpenKeys';
 | 
			
		||||
  import { URL_HASH_TAB } from '/@/utils';
 | 
			
		||||
  import { useAppStore } from '/@/store/modules/app';
 | 
			
		||||
 | 
			
		||||
  export default defineComponent({
 | 
			
		||||
    name: 'SimpleMenu',
 | 
			
		||||
| 
						 | 
				
			
			@ -56,6 +57,8 @@
 | 
			
		|||
    setup(props, { attrs, emit }) {
 | 
			
		||||
      const currentActiveMenu = ref('');
 | 
			
		||||
      const isClickGo = ref(false);
 | 
			
		||||
      const appStore = useAppStore();
 | 
			
		||||
      const isThemeBright = ref(false);
 | 
			
		||||
 | 
			
		||||
      const menuState = reactive<MenuState>({
 | 
			
		||||
        activeName: '',
 | 
			
		||||
| 
						 | 
				
			
			@ -93,7 +96,15 @@
 | 
			
		|||
        },
 | 
			
		||||
        { flush: 'post' }
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20240408---for:【QQYUN-8922】左侧导航栏文字颜色调整区分彩色和暗黑
 | 
			
		||||
      watch(
 | 
			
		||||
        () => appStore.getProjectConfig.menuSetting,
 | 
			
		||||
        (menuSetting) => {
 | 
			
		||||
          isThemeBright.value = !!menuSetting?.isThemeBright;
 | 
			
		||||
        },
 | 
			
		||||
        { immediate: true, deep: true }
 | 
			
		||||
      );
 | 
			
		||||
      // update-end--author:liaozhiyang---date:20240408---for:【QQYUN-8922】左侧导航栏文字颜色调整区分彩色和暗黑
 | 
			
		||||
      listenerRouteChange((route) => {
 | 
			
		||||
        if (route.name === REDIRECT_NAME) return;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -174,6 +185,7 @@
 | 
			
		|||
        handleSelect,
 | 
			
		||||
        getOpenKeys,
 | 
			
		||||
        ...toRefs(menuState),
 | 
			
		||||
        isThemeBright,
 | 
			
		||||
      };
 | 
			
		||||
    },
 | 
			
		||||
  });
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,7 +11,13 @@
 | 
			
		|||
      <SimpleMenuTag :item="item" :collapseParent="getIsCollapseParent" />
 | 
			
		||||
    </template>
 | 
			
		||||
  </MenuItem>
 | 
			
		||||
  <SubMenu :name="item.path" v-if="menuHasChildren(item) && getShowMenu" :class="[getLevelClass, theme]" :collapsedShowTitle="collapsedShowTitle">
 | 
			
		||||
  <SubMenu
 | 
			
		||||
    :isThemeBright="isThemeBright"
 | 
			
		||||
    :name="item.path"
 | 
			
		||||
    v-if="menuHasChildren(item) && getShowMenu"
 | 
			
		||||
    :class="[getLevelClass, theme]"
 | 
			
		||||
    :collapsedShowTitle="collapsedShowTitle"
 | 
			
		||||
  >
 | 
			
		||||
    <template #title>
 | 
			
		||||
      <Icon v-if="getIcon" :icon="getIcon" :size="16" />
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -25,7 +31,7 @@
 | 
			
		|||
      <SimpleMenuTag :item="item" :collapseParent="!!collapse && !!parent" />
 | 
			
		||||
    </template>
 | 
			
		||||
    <template v-for="childrenItem in item.children || []" :key="childrenItem.path">
 | 
			
		||||
      <SimpleSubMenu v-bind="$props" :item="childrenItem" :parent="false" />
 | 
			
		||||
      <SimpleSubMenu v-bind="$props" :isThemeBright="isThemeBright" :item="childrenItem" :parent="false" />
 | 
			
		||||
    </template>
 | 
			
		||||
  </SubMenu>
 | 
			
		||||
</template>
 | 
			
		||||
| 
						 | 
				
			
			@ -60,6 +66,12 @@
 | 
			
		|||
      collapsedShowTitle: propTypes.bool,
 | 
			
		||||
      collapse: propTypes.bool,
 | 
			
		||||
      theme: propTypes.oneOf(['dark', 'light']),
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20240417---for:【QQYUN-8927】侧边栏导航二级菜单彩色模式文字颜色调整
 | 
			
		||||
      isThemeBright: {
 | 
			
		||||
        type: Boolean,
 | 
			
		||||
        default: false,
 | 
			
		||||
      },
 | 
			
		||||
      // update-end--author:liaozhiyang---date:20240417---for:【QQYUN-8927】侧边栏导航二级菜单彩色模式文字颜色调整
 | 
			
		||||
    },
 | 
			
		||||
    setup(props) {
 | 
			
		||||
      const { t } = useI18n();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -37,7 +37,7 @@
 | 
			
		|||
      <!-- eslint-disable-next-line -->
 | 
			
		||||
      <template #content v-show="opened">
 | 
			
		||||
        <div v-bind="getEvents(true)">
 | 
			
		||||
          <ul :class="[prefixCls, `${prefixCls}-${getTheme}`, `${prefixCls}-popup`]">
 | 
			
		||||
          <ul :class="[prefixCls, `${prefixCls}-${getTheme}`, `${prefixCls}-popup`, `${isThemeBright && 'bright'}`]">
 | 
			
		||||
            <slot></slot>
 | 
			
		||||
          </ul>
 | 
			
		||||
        </div>
 | 
			
		||||
| 
						 | 
				
			
			@ -75,6 +75,12 @@
 | 
			
		|||
      },
 | 
			
		||||
      disabled: propTypes.bool,
 | 
			
		||||
      collapsedShowTitle: propTypes.bool,
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20240417---for:【QQYUN-8927】侧边栏导航二级菜单彩色模式文字颜色调整
 | 
			
		||||
      isThemeBright: {
 | 
			
		||||
        type: Boolean,
 | 
			
		||||
        default: false,
 | 
			
		||||
      },
 | 
			
		||||
      // update-end--author:liaozhiyang---date:20240417---for:【QQYUN-8927】侧边栏导航二级菜单彩色模式文字颜色调整
 | 
			
		||||
    },
 | 
			
		||||
    setup(props) {
 | 
			
		||||
      const instance = getCurrentInstance();
 | 
			
		||||
| 
						 | 
				
			
			@ -128,9 +134,11 @@
 | 
			
		|||
      const getTheme = computed(() => rootProps.theme);
 | 
			
		||||
 | 
			
		||||
      const getOverlayStyle = computed((): CSSProperties => {
 | 
			
		||||
        // update-begin--author:liaozhiyang---date:20240407---for:【QQYUN-8774】侧边混合导航菜单宽度调整
 | 
			
		||||
        return {
 | 
			
		||||
          minWidth: '200px',
 | 
			
		||||
          minWidth: '150px',
 | 
			
		||||
        };
 | 
			
		||||
        // update-end--author:liaozhiyang---date:20240407---for:【QQYUN-8774】侧边混合导航菜单宽度调整
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      const getIsOpend = computed(() => {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,7 +36,7 @@
 | 
			
		|||
    &-submenu-title {
 | 
			
		||||
      position: relative;
 | 
			
		||||
      z-index: 1;
 | 
			
		||||
      padding: 12px 20px;
 | 
			
		||||
      padding: 10px 14px;
 | 
			
		||||
      color: @menu-dark-subsidiary-color;
 | 
			
		||||
      cursor: pointer;
 | 
			
		||||
      transition: all @transition-time @ease-in-out;
 | 
			
		||||
| 
						 | 
				
			
			@ -65,6 +65,16 @@
 | 
			
		|||
          background-color: @primary-color !important;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      // 彩色模式(绿色,橘红等)
 | 
			
		||||
      &.bright {
 | 
			
		||||
        .@{menu-prefix-cls}-item,
 | 
			
		||||
        .@{menu-prefix-cls}-submenu-title {
 | 
			
		||||
          color: #fff;
 | 
			
		||||
          &:hover {
 | 
			
		||||
            color: rgba(255, 255, 255, 0.8);
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    &-light {
 | 
			
		||||
| 
						 | 
				
			
			@ -108,7 +118,15 @@
 | 
			
		|||
 | 
			
		||||
    &-light {
 | 
			
		||||
      background-color: #fff;
 | 
			
		||||
 | 
			
		||||
      color: rgba(0, 0, 0, 0.65);
 | 
			
		||||
      .@{menu-prefix-cls} {
 | 
			
		||||
        color: rgba(0, 0, 0, 0.65);
 | 
			
		||||
      }
 | 
			
		||||
      .@{namespace}-menu-submenu:not(.@{namespace}-menu-item-active)  .@{namespace}-menu-submenu-title {
 | 
			
		||||
        .anticon {
 | 
			
		||||
           color: rgba(0, 0, 0, 0.9);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      .@{menu-prefix-cls}-submenu-active {
 | 
			
		||||
        color: @primary-color !important;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -129,7 +147,6 @@
 | 
			
		|||
      z-index: 1;
 | 
			
		||||
      display: flex;
 | 
			
		||||
      font-size: @font-size-base;
 | 
			
		||||
      color: inherit;
 | 
			
		||||
      list-style: none;
 | 
			
		||||
      cursor: pointer;
 | 
			
		||||
      outline: none;
 | 
			
		||||
| 
						 | 
				
			
			@ -262,6 +279,20 @@
 | 
			
		|||
        color: #fff;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    // update-begin--author:liaozhiyang---date:20240408---for:【QQYUN-8922】左侧导航栏文字颜色调整区分彩色和暗黑
 | 
			
		||||
    &-dark&-vertical&.bright &-item,
 | 
			
		||||
    &-dark&-vertical.bright &-submenu-title {
 | 
			
		||||
      color: rgba(255, 255, 255, 1);
 | 
			
		||||
      &-active:not(.@{menu-prefix-cls}-submenu) {
 | 
			
		||||
        color: #fff !important;
 | 
			
		||||
        background-color: @primary-color !important;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      &:hover {
 | 
			
		||||
        color: rgba(255, 255, 255, 0.8);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    // update-end--author:liaozhiyang---date:20240408---for:【QQYUN-8922】左侧导航栏文字颜色调整区分彩色和暗黑
 | 
			
		||||
 | 
			
		||||
    &-dark&-vertical&-collapse {
 | 
			
		||||
      > li.@{menu-prefix-cls}-item-active,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,7 @@
 | 
			
		|||
    <BasicForm
 | 
			
		||||
      submitOnReset
 | 
			
		||||
      v-bind="getFormProps"
 | 
			
		||||
      v-if="getBindValues.useSearchForm"
 | 
			
		||||
      v-if="getBindValues.useSearchForm && getBindValues.formConfig?.schemas?.length"
 | 
			
		||||
      :tableAction="tableAction"
 | 
			
		||||
      @register="registerForm"
 | 
			
		||||
      @submit="handleSearchInfoChange"
 | 
			
		||||
| 
						 | 
				
			
			@ -17,37 +17,47 @@
 | 
			
		|||
    <!-- antd v3 升级兼容,阻止数据的收集,防止控制台报错 -->
 | 
			
		||||
    <!-- https://antdv.com/docs/vue/migration-v3-cn -->
 | 
			
		||||
    <a-form-item-rest>
 | 
			
		||||
      <Table ref="tableElRef" v-bind="getBindValues" :rowClassName="getRowClassName" v-show="getEmptyDataIsShowTable" @resizeColumn="handleResizeColumn" @change="handleTableChange">
 | 
			
		||||
        <!-- antd的原生插槽直接传递 -->
 | 
			
		||||
        <template #[item]="data" v-for="item in slotNamesGroup.native" :key="item">
 | 
			
		||||
          <!-- update-begin--author:liaozhiyang---date:20240424---for:【issues/1146】BasicTable使用headerCell全选框出不来 -->
 | 
			
		||||
          <template v-if="item === 'headerCell'">
 | 
			
		||||
            <CustomSelectHeader v-if="isCustomSelection(data.column)" v-bind="selectHeaderProps" />
 | 
			
		||||
      <!-- 【TV360X-377】关联记录必填影响到了table的输入框和页码样式 -->
 | 
			
		||||
      <a-form-item>
 | 
			
		||||
        <Table ref="tableElRef" v-bind="getBindValues" :rowClassName="getRowClassName" v-show="getEmptyDataIsShowTable" @resizeColumn="handleResizeColumn" @change="handleTableChange">
 | 
			
		||||
          <!-- antd的原生插槽直接传递 -->
 | 
			
		||||
          <template #[item]="data" v-for="item in slotNamesGroup.native" :key="item">
 | 
			
		||||
            <!-- update-begin--author:liaozhiyang---date:20240424---for:【issues/1146】BasicTable使用headerCell全选框出不来 -->
 | 
			
		||||
            <template v-if="item === 'headerCell'">
 | 
			
		||||
              <CustomSelectHeader v-if="isCustomSelection(data.column)" v-bind="selectHeaderProps" />
 | 
			
		||||
              <slot v-else :name="item" v-bind="data || {}"></slot>
 | 
			
		||||
            </template>
 | 
			
		||||
            <slot v-else :name="item" v-bind="data || {}"></slot>
 | 
			
		||||
            <!-- update-begin--author:liaozhiyang---date:20240424---for:【issues/1146】BasicTable使用headerCell全选框出不来 -->
 | 
			
		||||
          </template>
 | 
			
		||||
          <slot v-else :name="item" v-bind="data || {}"></slot>
 | 
			
		||||
          <!-- update-begin--author:liaozhiyang---date:20240424---for:【issues/1146】BasicTable使用headerCell全选框出不来 -->
 | 
			
		||||
        </template>
 | 
			
		||||
        <template #headerCell="{ column }">
 | 
			
		||||
          <!-- update-begin--author:sunjianlei---date:220230630---for:【QQYUN-5571】自封装选择列,解决数据行选择卡顿问题 -->
 | 
			
		||||
          <CustomSelectHeader v-if="isCustomSelection(column)" v-bind="selectHeaderProps"/>
 | 
			
		||||
          <HeaderCell v-else :column="column" />
 | 
			
		||||
          <!-- update-end--author:sunjianlei---date:220230630---for:【QQYUN-5571】自封装选择列,解决数据行选择卡顿问题 -->
 | 
			
		||||
        </template>
 | 
			
		||||
        <!-- 增加对antdv3.x兼容 -->
 | 
			
		||||
        <template #bodyCell="data">
 | 
			
		||||
          <!-- update-begin--author:liaozhiyang---date:220230717---for:【issues-179】antd3 一些警告以及报错(针对表格) -->
 | 
			
		||||
          <!-- update-begin--author:liusq---date:20230921---for:【issues/770】slotsBak异常报错的问题,增加判断column是否存在 -->
 | 
			
		||||
          <template v-if="data.column?.slotsBak?.customRender">
 | 
			
		||||
          <!-- update-end--author:liusq---date:20230921---for:【issues/770】slotsBak异常报错的问题,增加判断column是否存在 -->
 | 
			
		||||
            <slot :name="data.column.slotsBak.customRender" v-bind="data || {}"></slot>
 | 
			
		||||
          <template #headerCell="{ column }">
 | 
			
		||||
            <!-- update-begin--author:sunjianlei---date:220230630---for:【QQYUN-5571】自封装选择列,解决数据行选择卡顿问题 -->
 | 
			
		||||
            <CustomSelectHeader v-if="isCustomSelection(column)" v-bind="selectHeaderProps"/>
 | 
			
		||||
            <HeaderCell v-else :column="column" />
 | 
			
		||||
            <!-- update-end--author:sunjianlei---date:220230630---for:【QQYUN-5571】自封装选择列,解决数据行选择卡顿问题 -->
 | 
			
		||||
          </template>
 | 
			
		||||
          <template v-else>
 | 
			
		||||
            <slot name="bodyCell" v-bind="data || {}"></slot>
 | 
			
		||||
          <!-- 增加对antdv3.x兼容 -->
 | 
			
		||||
          <template #bodyCell="data">
 | 
			
		||||
            <!-- update-begin--author:liaozhiyang---date:220230717---for:【issues-179】antd3 一些警告以及报错(针对表格) -->
 | 
			
		||||
            <!-- update-begin--author:liusq---date:20230921---for:【issues/770】slotsBak异常报错的问题,增加判断column是否存在 -->
 | 
			
		||||
            <template v-if="data.column?.slotsBak?.customRender">
 | 
			
		||||
            <!-- update-end--author:liusq---date:20230921---for:【issues/770】slotsBak异常报错的问题,增加判断column是否存在 -->
 | 
			
		||||
              <slot :name="data.column.slotsBak.customRender" v-bind="data || {}"></slot>
 | 
			
		||||
            </template>
 | 
			
		||||
            <template v-else>
 | 
			
		||||
              <slot name="bodyCell" v-bind="data || {}"></slot>
 | 
			
		||||
            </template>
 | 
			
		||||
            <!-- update-begin--author:liaozhiyang---date:22030717---for:【issues-179】antd3 一些警告以及报错(针对表格) -->
 | 
			
		||||
          </template>
 | 
			
		||||
          <!-- update-begin--author:liaozhiyang---date:22030717---for:【issues-179】antd3 一些警告以及报错(针对表格) -->
 | 
			
		||||
        </template>
 | 
			
		||||
      </Table>
 | 
			
		||||
          <!-- update-begin--author:liaozhiyang---date:20240425---for:【pull/1201】添加antd的TableSummary功能兼容老的summary(表尾合计) -->
 | 
			
		||||
          <template v-if="showSummaryRef && !getBindValues.showSummary" #summary="data">
 | 
			
		||||
            <slot name="summary" v-bind="data || {}">
 | 
			
		||||
              <TableSummary :data="data || {}" v-bind="getSummaryProps" />
 | 
			
		||||
            </slot>
 | 
			
		||||
          </template>
 | 
			
		||||
          <!-- update-end--author:liaozhiyang---date:20240425---for:【pull/1201】添加antd的TableSummary功能兼容老的summary(表尾合计) -->
 | 
			
		||||
        </Table>
 | 
			
		||||
      </a-form-item>
 | 
			
		||||
    </a-form-item-rest>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
| 
						 | 
				
			
			@ -61,6 +71,7 @@
 | 
			
		|||
  import CustomSelectHeader from './components/CustomSelectHeader.vue'
 | 
			
		||||
  import expandIcon from './components/ExpandIcon';
 | 
			
		||||
  import HeaderCell from './components/HeaderCell.vue';
 | 
			
		||||
  import TableSummary from './components/TableSummary';
 | 
			
		||||
  import { InnerHandlers } from './types/table';
 | 
			
		||||
  import { usePagination } from './hooks/usePagination';
 | 
			
		||||
  import { useColumns } from './hooks/useColumns';
 | 
			
		||||
| 
						 | 
				
			
			@ -78,7 +89,7 @@
 | 
			
		|||
  import { useDesign } from '/@/hooks/web/useDesign';
 | 
			
		||||
  import { useCustomSelection } from "./hooks/useCustomSelection";
 | 
			
		||||
 | 
			
		||||
  import { omit } from 'lodash-es';
 | 
			
		||||
  import { omit, pick } from 'lodash-es';
 | 
			
		||||
  import { basicProps } from './props';
 | 
			
		||||
  import { isFunction } from '/@/utils/is';
 | 
			
		||||
  import { warn } from '/@/utils/log';
 | 
			
		||||
| 
						 | 
				
			
			@ -88,6 +99,7 @@
 | 
			
		|||
      Table,
 | 
			
		||||
      BasicForm,
 | 
			
		||||
      HeaderCell,
 | 
			
		||||
      TableSummary,
 | 
			
		||||
      CustomSelectHeader,
 | 
			
		||||
    },
 | 
			
		||||
    props: basicProps,
 | 
			
		||||
| 
						 | 
				
			
			@ -232,6 +244,18 @@
 | 
			
		|||
      };
 | 
			
		||||
 | 
			
		||||
      const { getHeaderProps } = useTableHeader(getProps, slots, handlers);
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20240425---for:【pull/1201】添加antd的TableSummary功能兼容老的summary(表尾合计)
 | 
			
		||||
      const getSummaryProps = computed(() => {
 | 
			
		||||
        return pick(unref(getProps), ['summaryFunc', 'summaryData', 'hasExpandedRow', 'rowKey']);
 | 
			
		||||
      });
 | 
			
		||||
      const getIsEmptyData = computed(() => {
 | 
			
		||||
        return (unref(getDataSourceRef) || []).length === 0;
 | 
			
		||||
      });
 | 
			
		||||
      const showSummaryRef = computed(() => {
 | 
			
		||||
        const summaryProps = unref(getSummaryProps);
 | 
			
		||||
        return (summaryProps.summaryFunc || summaryProps.summaryData) && !unref(getIsEmptyData);
 | 
			
		||||
      });
 | 
			
		||||
      // update-end--author:liaozhiyang---date:20240425---for:【pull/1201】添加antd的TableSummary功能兼容老的summary(表尾合计)
 | 
			
		||||
 | 
			
		||||
      const { getFooterProps } = useTableFooter(getProps, slots, getScrollRef, tableElRef, getDataSourceRef);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -266,7 +290,7 @@
 | 
			
		|||
        /*if (slots.expandedRowRender) {
 | 
			
		||||
          propsData = omit(propsData, 'scroll');
 | 
			
		||||
        }*/
 | 
			
		||||
        //update-end---author:wangshuai ---date:20230214  for:[QQYUN-4237]代码生成 内嵌子表模式 没有滚动条------------
 | 
			
		||||
        //update-end---author:wangshuai ---date:20230214  for:[QQYUN-4237]代码生成 内嵌子表模式 没有滚动条------------ 
 | 
			
		||||
 | 
			
		||||
        // update-begin--author:sunjianlei---date:220230630---for:【QQYUN-5571】自封装选择列,解决数据行选择卡顿问题
 | 
			
		||||
        // 自定义选择列,需要去掉原生的
 | 
			
		||||
| 
						 | 
				
			
			@ -414,6 +438,10 @@
 | 
			
		|||
        isCustomSelection,
 | 
			
		||||
        // update-end--author:sunjianlei---date:220230630---for:【QQYUN-5571】自封装选择列,解决数据行选择卡顿问题
 | 
			
		||||
        slotNamesGroup,
 | 
			
		||||
        // update-begin--author:liaozhiyang---date:20240425---for:【pull/1201】添加antd的TableSummary功能兼容老的summary(表尾合计)
 | 
			
		||||
        getSummaryProps,
 | 
			
		||||
        showSummaryRef,
 | 
			
		||||
        // update-end--author:liaozhiyang---date:20240425---for:【pull/1201】添加antd的TableSummary功能兼容老的summary(表尾合计)
 | 
			
		||||
      };
 | 
			
		||||
    },
 | 
			
		||||
  });
 | 
			
		||||
| 
						 | 
				
			
			@ -563,5 +591,10 @@
 | 
			
		|||
      }
 | 
			
		||||
    }
 | 
			
		||||
    // update-end--author:sunjianlei---date:220230718---for:【issues/622】修复表尾合计错位的问题
 | 
			
		||||
    // update-begin--author:liaozhiyang---date:20240604---for:【TV360X-377】关联记录必填影响到了table的输入框和页码样式
 | 
			
		||||
    > .ant-form-item {
 | 
			
		||||
      margin-bottom: 0;
 | 
			
		||||
    }
 | 
			
		||||
    // update-end--author:liaozhiyang---date:20240604---for:【TV360X-377】关联记录必填影响到了table的输入框和页码样式
 | 
			
		||||
  }
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,7 +19,13 @@
 | 
			
		|||
 | 
			
		||||
      <Divider type="vertical" class="action-divider" v-if="divider && index < getActions.length - 1" />
 | 
			
		||||
    </template>
 | 
			
		||||
    <Dropdown :trigger="['hover']" :dropMenuList="getDropdownList" popconfirm v-if="dropDownActions && getDropdownList.length > 0">
 | 
			
		||||
    <Dropdown
 | 
			
		||||
      :overlayClassName="dropdownCls"
 | 
			
		||||
      :trigger="['hover']"
 | 
			
		||||
      :dropMenuList="getDropdownList"
 | 
			
		||||
      popconfirm
 | 
			
		||||
      v-if="dropDownActions && getDropdownList.length > 0"
 | 
			
		||||
    >
 | 
			
		||||
      <slot name="more"></slot>
 | 
			
		||||
      <!--  设置插槽   -->
 | 
			
		||||
      <template v-slot:[item.slot] v-for="(item, index) in getDropdownSlotList" :key="`${index}-${item.label}`">
 | 
			
		||||
| 
						 | 
				
			
			@ -63,6 +69,7 @@
 | 
			
		|||
    },
 | 
			
		||||
    setup(props) {
 | 
			
		||||
      const { prefixCls } = useDesign('basic-table-action');
 | 
			
		||||
      const dropdownCls = `${prefixCls}-dropdown`;
 | 
			
		||||
      let table: Partial<TableActionType> = {};
 | 
			
		||||
      if (!props.outside) {
 | 
			
		||||
        table = useTableContext();
 | 
			
		||||
| 
						 | 
				
			
			@ -189,8 +196,8 @@
 | 
			
		|||
        });
 | 
			
		||||
        isInButton && e.stopPropagation();
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return { prefixCls, getActions, getDropdownList, getDropdownSlotList, getAlign, onCellClick, getTooltip };
 | 
			
		||||
     
 | 
			
		||||
      return { prefixCls, getActions, getDropdownList, getDropdownSlotList, getAlign, onCellClick, getTooltip, dropdownCls };
 | 
			
		||||
    },
 | 
			
		||||
  });
 | 
			
		||||
</script>
 | 
			
		||||
| 
						 | 
				
			
			@ -258,5 +265,19 @@
 | 
			
		|||
        // update-end--author:liaozhiyang---date:20240124---for:【issues/1019】popConfirm确认框待端后端返回过程中(处理中)样式错乱
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    // update-begin--author:liaozhiyang---date:20240407---for:【QQYUN-8762】调整table操作栏ant-dropdown样式
 | 
			
		||||
    &-dropdown {
 | 
			
		||||
      .ant-dropdown-menu .ant-dropdown-menu-item-divider {
 | 
			
		||||
        margin: 2px 0;
 | 
			
		||||
      }
 | 
			
		||||
      .ant-dropdown-menu .ant-dropdown-menu-item {
 | 
			
		||||
        padding: 3px 8px;
 | 
			
		||||
        font-size: 13.6px;
 | 
			
		||||
      }
 | 
			
		||||
      .dropdown-event-area {
 | 
			
		||||
        padding: 0 !important;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    // update-end--author:liaozhiyang---date:20240407---for:【QQYUN-8762】调整table操作栏ant-dropdown样式
 | 
			
		||||
  }
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,163 @@
 | 
			
		|||
import type { PropType, VNode } from 'vue';
 | 
			
		||||
import { defineComponent, unref, computed, isVNode } from 'vue';
 | 
			
		||||
import { cloneDeep, pick } from 'lodash-es';
 | 
			
		||||
import { isFunction } from '/@/utils/is';
 | 
			
		||||
import type { BasicColumn } from '../types/table';
 | 
			
		||||
import { INDEX_COLUMN_FLAG } from '../const';
 | 
			
		||||
import { propTypes } from '/@/utils/propTypes';
 | 
			
		||||
import { useTableContext } from '../hooks/useTableContext';
 | 
			
		||||
import { TableSummary, TableSummaryRow, TableSummaryCell } from 'ant-design-vue';
 | 
			
		||||
 | 
			
		||||
const SUMMARY_ROW_KEY = '_row';
 | 
			
		||||
const SUMMARY_INDEX_KEY = '_index';
 | 
			
		||||
export default defineComponent({
 | 
			
		||||
  name: 'BasicTableSummary',
 | 
			
		||||
  components: { TableSummary, TableSummaryRow, TableSummaryCell },
 | 
			
		||||
  props: {
 | 
			
		||||
    summaryFunc: {
 | 
			
		||||
      type: Function as PropType<Fn>,
 | 
			
		||||
    },
 | 
			
		||||
    summaryData: {
 | 
			
		||||
      type: Array as PropType<Recordable[]>,
 | 
			
		||||
    },
 | 
			
		||||
    rowKey: propTypes.string.def('key'),
 | 
			
		||||
    // 是否有展开列
 | 
			
		||||
    hasExpandedRow: propTypes.bool,
 | 
			
		||||
    data: {
 | 
			
		||||
      type: Object as PropType<Recordable>,
 | 
			
		||||
      default: () => {},
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
  setup(props) {
 | 
			
		||||
    const table = useTableContext();
 | 
			
		||||
 | 
			
		||||
    const getDataSource = computed((): Recordable[] => {
 | 
			
		||||
      const {
 | 
			
		||||
        summaryFunc,
 | 
			
		||||
        summaryData,
 | 
			
		||||
        data: { pageData },
 | 
			
		||||
      } = props;
 | 
			
		||||
      if (summaryData?.length) {
 | 
			
		||||
        summaryData.forEach((item, i) => (item[props.rowKey] = `${i}`));
 | 
			
		||||
        return summaryData;
 | 
			
		||||
      }
 | 
			
		||||
      if (!isFunction(summaryFunc)) {
 | 
			
		||||
        return [];
 | 
			
		||||
      }
 | 
			
		||||
      let dataSource = cloneDeep(unref(pageData));
 | 
			
		||||
      dataSource = summaryFunc(dataSource);
 | 
			
		||||
      dataSource.forEach((item, i) => {
 | 
			
		||||
        item[props.rowKey] = `${i}`;
 | 
			
		||||
      });
 | 
			
		||||
      return dataSource;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    const getColumns = computed(() => {
 | 
			
		||||
      const dataSource = unref(getDataSource);
 | 
			
		||||
      let columns: BasicColumn[] = cloneDeep(table.getColumns({ sort: true }));
 | 
			
		||||
      columns = columns.filter((item) => !item.defaultHidden);
 | 
			
		||||
      const index = columns.findIndex((item) => item.flag === INDEX_COLUMN_FLAG);
 | 
			
		||||
      const hasRowSummary = dataSource.some((item) => Reflect.has(item, SUMMARY_ROW_KEY));
 | 
			
		||||
      const hasIndexSummary = dataSource.some((item) => Reflect.has(item, SUMMARY_INDEX_KEY));
 | 
			
		||||
 | 
			
		||||
      // 是否有序号列
 | 
			
		||||
      let hasIndexCol = false;
 | 
			
		||||
      // 是否有选择列
 | 
			
		||||
      const hasSelection = table.getRowSelection() && hasRowSummary;
 | 
			
		||||
 | 
			
		||||
      if (index !== -1) {
 | 
			
		||||
        if (hasIndexSummary) {
 | 
			
		||||
          hasIndexCol = true;
 | 
			
		||||
          columns[index].customSummaryRender = ({ record }) => record[SUMMARY_INDEX_KEY];
 | 
			
		||||
          columns[index].ellipsis = false;
 | 
			
		||||
        } else {
 | 
			
		||||
          Reflect.deleteProperty(columns[index], 'customSummaryRender');
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (hasSelection) {
 | 
			
		||||
        const isFixed = columns.some((col) => col.fixed === 'left' || col.fixed === true);
 | 
			
		||||
        columns.unshift({
 | 
			
		||||
          width: 60,
 | 
			
		||||
          title: 'selection',
 | 
			
		||||
          key: 'selectionKey',
 | 
			
		||||
          align: 'center',
 | 
			
		||||
          ...(isFixed ? { fixed: 'left' } : {}),
 | 
			
		||||
          customSummaryRender: ({ record }) => (hasIndexCol ? '' : record[SUMMARY_ROW_KEY]),
 | 
			
		||||
        });
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (props.hasExpandedRow) {
 | 
			
		||||
        const isFixed = columns.some((col) => col.fixed === 'left');
 | 
			
		||||
        columns.unshift({
 | 
			
		||||
          width: 50,
 | 
			
		||||
          title: 'expandedRow',
 | 
			
		||||
          key: 'expandedRowKey',
 | 
			
		||||
          align: 'center',
 | 
			
		||||
          ...(isFixed ? { fixed: 'left' } : {}),
 | 
			
		||||
          customSummaryRender: () => '',
 | 
			
		||||
        });
 | 
			
		||||
      }
 | 
			
		||||
      return columns;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    function isRenderCell(data: any) {
 | 
			
		||||
      return data && typeof data === 'object' && !Array.isArray(data) && !isVNode(data);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const getValues = (row: Recordable, col: BasicColumn, index: number) => {
 | 
			
		||||
      const value = row[col.dataIndex as string];
 | 
			
		||||
      let childNode: VNode | JSX.Element | string | number | undefined | null;
 | 
			
		||||
      childNode = value;
 | 
			
		||||
      if (col.customSummaryRender) {
 | 
			
		||||
        const renderData = col.customSummaryRender({
 | 
			
		||||
          text: value,
 | 
			
		||||
          value,
 | 
			
		||||
          record: row,
 | 
			
		||||
          index,
 | 
			
		||||
          column: cloneDeep(col),
 | 
			
		||||
        });
 | 
			
		||||
        if (isRenderCell(renderData)) {
 | 
			
		||||
          childNode = renderData.children;
 | 
			
		||||
        } else {
 | 
			
		||||
          childNode = renderData;
 | 
			
		||||
        }
 | 
			
		||||
        if (typeof childNode === 'object' && !Array.isArray(childNode) && !isVNode(childNode)) {
 | 
			
		||||
          childNode = null;
 | 
			
		||||
        }
 | 
			
		||||
        if (Array.isArray(childNode) && childNode.length === 1) {
 | 
			
		||||
          childNode = childNode[0];
 | 
			
		||||
        }
 | 
			
		||||
        return childNode;
 | 
			
		||||
      }
 | 
			
		||||
      return childNode;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    const getCellProps = (col: BasicColumn) => {
 | 
			
		||||
      const cellProps = pick(col, ['colSpan', 'rowSpan', 'align']);
 | 
			
		||||
      return {
 | 
			
		||||
        ...cellProps,
 | 
			
		||||
      };
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return () => {
 | 
			
		||||
      return (
 | 
			
		||||
        <TableSummary fixed>
 | 
			
		||||
          {(unref(getDataSource) || []).map((row) => {
 | 
			
		||||
            return (
 | 
			
		||||
              <TableSummaryRow key={row[props.rowKey]}>
 | 
			
		||||
                {unref(getColumns).map((col, index) => {
 | 
			
		||||
                  return (
 | 
			
		||||
                    <TableSummaryCell {...getCellProps(col)} index={index} key={`${row[props.rowKey]}_${col.dataIndex}_${index}`}>
 | 
			
		||||
                      {getValues(row, col, index)}
 | 
			
		||||
                    </TableSummaryCell>
 | 
			
		||||
                  );
 | 
			
		||||
                })}
 | 
			
		||||
              </TableSummaryRow>
 | 
			
		||||
            );
 | 
			
		||||
          })}
 | 
			
		||||
        </TableSummary>
 | 
			
		||||
      );
 | 
			
		||||
    };
 | 
			
		||||
  },
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			@ -142,9 +142,9 @@
 | 
			
		|||
    setup(props, { emit, attrs }) {
 | 
			
		||||
      const { t } = useI18n();
 | 
			
		||||
      const table = useTableContext();
 | 
			
		||||
      const popoverVisible = ref(true);
 | 
			
		||||
      const popoverVisible = ref(false);
 | 
			
		||||
      // update-begin--author:sunjianlei---date:20221101---for: 修复第一次进入时列表配置不能拖拽
 | 
			
		||||
      nextTick(() => popoverVisible.value = false);
 | 
			
		||||
      // nextTick(() => popoverVisible.value = false);
 | 
			
		||||
      // update-end--author:sunjianlei---date:20221101---for: 修复第一次进入时列表配置不能拖拽
 | 
			
		||||
      const defaultRowSelection = omit(table.getRowSelection(), 'selectedRowKeys');
 | 
			
		||||
      let inited = false;
 | 
			
		||||
| 
						 | 
				
			
			@ -311,7 +311,9 @@
 | 
			
		|||
      // Open the pop-up window for drag and drop initialization
 | 
			
		||||
      function handleVisibleChange() {
 | 
			
		||||
        if (inited) return;
 | 
			
		||||
        nextTick(() => {
 | 
			
		||||
        // update-begin--author:liaozhiyang---date:20240529---for:【TV360X-254】列设置闪现及苹果浏览器弹窗过长
 | 
			
		||||
        setTimeout(() => {
 | 
			
		||||
          // update-begin--author:liaozhiyang---date:20240529---for:【TV360X-254】列设置闪现及苹果浏览器弹窗过长
 | 
			
		||||
          const columnListEl = unref(columnListRef);
 | 
			
		||||
          if (!columnListEl) return;
 | 
			
		||||
          const el = columnListEl.$el as any;
 | 
			
		||||
| 
						 | 
				
			
			@ -340,14 +342,14 @@
 | 
			
		|||
 | 
			
		||||
              plainSortOptions.value = columns;
 | 
			
		||||
              // update-begin--author:liaozhiyang---date:20230904---for:【QQYUN-6424】table字段列表设置不显示后,再拖拽字段顺序,原本不显示的,又显示了
 | 
			
		||||
              if(state.checkedList.length != columns.length){
 | 
			
		||||
                const cols = columns.map(item => item.value);
 | 
			
		||||
                const arr = cols.filter((cItem) => state.checkedList.find((lItem) => lItem === cItem));
 | 
			
		||||
                setColumns(arr);
 | 
			
		||||
              } else {
 | 
			
		||||
                setColumns(columns);
 | 
			
		||||
              }
 | 
			
		||||
              // update-begin--author:liaozhiyang---date:20230904---for:【QQYUN-6424】table字段列表设置不显示后,再拖拽字段顺序,原本不显示的,又显示了
 | 
			
		||||
              // update-begin--author:liaozhiyang---date:20240522---for:【TV360X-108】刷新后勾选之前未勾选的字段拖拽之后该字段对应的表格列消失了
 | 
			
		||||
              const cols = columns.map((item) => item.value);
 | 
			
		||||
              const arr = cols.filter((cItem) => state.checkedList.find((lItem) => lItem === cItem));
 | 
			
		||||
              setColumns(arr);
 | 
			
		||||
              // 最开始的代码
 | 
			
		||||
              // setColumns(columns);
 | 
			
		||||
              // update-end--author:liaozhiyang---date:20240522---for:【TV360X-108】刷新后勾选之前未勾选的字段拖拽之后该字段对应的表格列消失了
 | 
			
		||||
              // update-end--author:liaozhiyang---date:20230904---for:【QQYUN-6424】table字段列表设置不显示后,再拖拽字段顺序,原本不显示的,又显示了
 | 
			
		||||
            },
 | 
			
		||||
          });
 | 
			
		||||
          // 记录原始 order 序列
 | 
			
		||||
| 
						 | 
				
			
			@ -355,7 +357,7 @@
 | 
			
		|||
            sortableOrder.value = sortable.toArray();
 | 
			
		||||
          }
 | 
			
		||||
          inited = true;
 | 
			
		||||
        });
 | 
			
		||||
        }, 2000);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Control whether the serial number column is displayed
 | 
			
		||||
| 
						 | 
				
			
			@ -516,6 +518,16 @@
 | 
			
		|||
        // flex-wrap: wrap;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20240529---for:【TV360X-254】列设置闪现及苹果浏览器弹窗过长
 | 
			
		||||
      &.ant-popover,
 | 
			
		||||
      .ant-popover-content,
 | 
			
		||||
      .ant-popover-inner,
 | 
			
		||||
      .ant-popover-inner-content,
 | 
			
		||||
      .scroll-container,
 | 
			
		||||
      .scrollbar__wrap {
 | 
			
		||||
        max-width: min-content;
 | 
			
		||||
      }
 | 
			
		||||
      // update-end--author:liaozhiyang---date:20240529---for:【TV360X-254】列设置闪现及苹果浏览器弹窗过长
 | 
			
		||||
      .scrollbar {
 | 
			
		||||
        height: 220px;
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,8 +8,8 @@
 | 
			
		|||
      <ColumnHeightOutlined />
 | 
			
		||||
      <template #overlay>
 | 
			
		||||
        <Menu @click="handleTitleClick" selectable v-model:selectedKeys="selectedKeysRef">
 | 
			
		||||
          <MenuItem key="default">
 | 
			
		||||
            <span>{{ t('component.table.settingDensDefault') }}</span>
 | 
			
		||||
          <MenuItem key="large">
 | 
			
		||||
            <span>{{ t('component.table.settingDensLarge') }}</span>
 | 
			
		||||
          </MenuItem>
 | 
			
		||||
          <MenuItem key="middle">
 | 
			
		||||
            <span>{{ t('component.table.settingDensMiddle') }}</span>
 | 
			
		||||
| 
						 | 
				
			
			@ -30,6 +30,8 @@
 | 
			
		|||
  import { useI18n } from '/@/hooks/web/useI18n';
 | 
			
		||||
  import { useTableContext } from '../../hooks/useTableContext';
 | 
			
		||||
  import { getPopupContainer } from '/@/utils';
 | 
			
		||||
  import { useRoute } from 'vue-router';
 | 
			
		||||
  import { createLocalStorage } from '/@/utils/cache';
 | 
			
		||||
 | 
			
		||||
  export default defineComponent({
 | 
			
		||||
    name: 'SizeSetting',
 | 
			
		||||
| 
						 | 
				
			
			@ -46,6 +48,8 @@
 | 
			
		|||
    setup(props) {
 | 
			
		||||
      const table = useTableContext();
 | 
			
		||||
      const { t } = useI18n();
 | 
			
		||||
      const $ls = createLocalStorage();
 | 
			
		||||
      const route = useRoute();
 | 
			
		||||
 | 
			
		||||
      const selectedKeysRef = ref<SizeType[]>([table.getSize()]);
 | 
			
		||||
      const getBindProps = computed(() => {
 | 
			
		||||
| 
						 | 
				
			
			@ -60,7 +64,28 @@
 | 
			
		|||
        table.setProps({
 | 
			
		||||
          size: key,
 | 
			
		||||
        });
 | 
			
		||||
        // update-begin--author:liaozhiyang---date:20240604---for:【TV360X-100】缓存表格密度
 | 
			
		||||
        $ls.set(cacheKey.value, key);
 | 
			
		||||
        // update-end--author:liaozhiyang---date:20240604---for:【TV360X-100】缓存表格密度
 | 
			
		||||
      }
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20240604---for:【TV360X-100】缓存表格密度
 | 
			
		||||
      const cacheKey = computed(() => {
 | 
			
		||||
        const path = route.path;
 | 
			
		||||
        let key = path.replace(/[\/\\]/g, '_');
 | 
			
		||||
        let cacheKey = table.getBindValues.value.tableSetting?.cacheKey;
 | 
			
		||||
        if (cacheKey) {
 | 
			
		||||
          key += ':' + cacheKey;
 | 
			
		||||
        }
 | 
			
		||||
        return 'tableSizeCache:' + key;
 | 
			
		||||
      });
 | 
			
		||||
      const local: SizeType | null = $ls.get(cacheKey.value);
 | 
			
		||||
      if (local) {
 | 
			
		||||
        selectedKeysRef.value = [local];
 | 
			
		||||
        table.setProps({
 | 
			
		||||
          size: local,
 | 
			
		||||
        });
 | 
			
		||||
      }
 | 
			
		||||
      // update-end--author:liaozhiyang---date:20240604---for:【TV360X-100】缓存表格密度
 | 
			
		||||
 | 
			
		||||
      return {
 | 
			
		||||
        getBindProps,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -75,6 +75,11 @@ export function useCustomRow(
 | 
			
		|||
              }
 | 
			
		||||
              setSelectedRowKeys([key]);
 | 
			
		||||
              return;
 | 
			
		||||
            } else {
 | 
			
		||||
              // update-begin--author:liaozhiyang---date:20240527---for:【TV360X-359】erp主表点击已选中的选到了最后一个
 | 
			
		||||
              // 点击已经选中的,直接return不在做操作
 | 
			
		||||
              return;
 | 
			
		||||
              // update-end--author:liaozhiyang---date:20240527---for:【TV360X-359】erp主表点击已选中的选到了最后一个
 | 
			
		||||
            }
 | 
			
		||||
            clearSelectedRowKeys();
 | 
			
		||||
          }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -120,7 +120,10 @@ export function useCustomSelection(
 | 
			
		|||
      onSelectAll,
 | 
			
		||||
      isRadio: isRadio.value,
 | 
			
		||||
      selectedLength: flattedData.value.filter((data) => selectedKeys.value.includes(getRecordKey(data))).length,
 | 
			
		||||
      pageSize: currentPageSize.value,
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20240511---for:【QQYUN-9289】解决表格条数不足pageSize数量时行数全部勾选但是全选框不勾选
 | 
			
		||||
      // 【TV360X-53】为空时会报错,加强判断
 | 
			
		||||
      pageSize: tableData.value?.length ?? 0,
 | 
			
		||||
      // update-end--author:liaozhiyang---date:20240511---for:【QQYUN-9289】解决表格条数不足pageSize数量时行数全部勾选但是全选框不勾选
 | 
			
		||||
      // 【QQYUN-6774】解决checkbox禁用后全选仍能勾选问题
 | 
			
		||||
      disabled: flattedData.value.length == 0,
 | 
			
		||||
      hideSelectAll: unref(propsRef)?.rowSelection?.hideSelectAll,
 | 
			
		||||
| 
						 | 
				
			
			@ -225,9 +228,14 @@ export function useCustomSelection(
 | 
			
		|||
    // update-end--author:liaozhiyang---date:20231122---for:【issues/5577】BasicTable组件全选和取消全选时不触发onSelectAll事件
 | 
			
		||||
    // 取消全选
 | 
			
		||||
    if (!checked) {
 | 
			
		||||
      selectedKeys.value = [];
 | 
			
		||||
      selectedRows.value = [];
 | 
			
		||||
      emitChange('all');
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20240510---for:【issues/1173】取消全选只是当前页面取消
 | 
			
		||||
      // selectedKeys.value = [];
 | 
			
		||||
      // selectedRows.value = [];
 | 
			
		||||
      // emitChange('all');
 | 
			
		||||
      flattedData.value.forEach((item) => {
 | 
			
		||||
        updateSelected(item, false);
 | 
			
		||||
      });
 | 
			
		||||
      // update-end--author:liaozhiyang---date:20240510---for:【issues/1173】取消全选只是当前页面取消
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    let modal: Nullable<ReturnType<ModalFunc>> = null;
 | 
			
		||||
| 
						 | 
				
			
			@ -625,3 +633,4 @@ function flattenData<RecordType>(data: RecordType[] | undefined, childrenColumnN
 | 
			
		|||
 | 
			
		||||
  return list;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -133,6 +133,10 @@ export function useTableScroll(
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    let height = bottomIncludeBody - (resizeHeightOffset || 0) - paddingHeight - paginationHeight - footerHeight - headerHeight;
 | 
			
		||||
    // update-begin--author:liaozhiyang---date:20240603---for【TV360X-861】列表查询区域不可往上滚动
 | 
			
		||||
    // 10+6(外层边距padding:10 + 内层padding-bottom:6)
 | 
			
		||||
    height -= 16;
 | 
			
		||||
    // update-end--author:liaozhiyang---date:20240603---for:【TV360X-861】列表查询区域不可往上滚动
 | 
			
		||||
 | 
			
		||||
    height = (height < minHeight! ? (minHeight as number) : height) ?? height;
 | 
			
		||||
    height = (height > maxHeight! ? (maxHeight as number) : height) ?? height;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -173,6 +173,9 @@ export interface ColumnProps<T> {
 | 
			
		|||
   * @type object
 | 
			
		||||
   */
 | 
			
		||||
  customHeaderCell?: (column: ColumnProps<T>) => object;
 | 
			
		||||
  // update-begin--author:liaozhiyang---date:20240425---for:【pull/1201】添加antd的TableSummary功能兼容老的summary(表尾合计)
 | 
			
		||||
  customSummaryRender?: CustomRenderFunction<T> | VNodeChild | JSX.Element;
 | 
			
		||||
  // update-end--author:liaozhiyang---date:20240425---for:【pull/1201】添加antd的TableSummary功能兼容老的summary(表尾合计)
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Callback executed when the confirm filter button is clicked, Use as a filter event when using template or jsx
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -81,7 +81,7 @@ export interface GetColumnsParams {
 | 
			
		|||
  sort?: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export type SizeType = 'default' | 'middle' | 'small' | 'large';
 | 
			
		||||
export type SizeType = 'middle' | 'small' | 'large';
 | 
			
		||||
 | 
			
		||||
export interface TableActionType {
 | 
			
		||||
  reload: (opt?: FetchParams) => Promise<void>;
 | 
			
		||||
| 
						 | 
				
			
			@ -455,6 +455,16 @@ export interface BasicColumn extends ColumnProps<Recordable> {
 | 
			
		|||
  ifShow?: boolean | ((column: BasicColumn) => boolean);
 | 
			
		||||
  //compType-用于记录类型
 | 
			
		||||
  compType?: string;
 | 
			
		||||
  // update-begin--author:liaozhiyang---date:20240425---for:【pull/1201】添加antd的TableSummary功能兼容老的summary(表尾合计)
 | 
			
		||||
  customSummaryRender?: (opt: {
 | 
			
		||||
    value: any;
 | 
			
		||||
    text: any;
 | 
			
		||||
    record: Recordable;
 | 
			
		||||
    index: number;
 | 
			
		||||
    renderIndex?: number;
 | 
			
		||||
    column: BasicColumn;
 | 
			
		||||
  }) => any | VNodeChild | JSX.Element;
 | 
			
		||||
  // update-end--author:liaozhiyang---date:20240425---for:【pull/1201】添加antd的TableSummary功能兼容老的summary(表尾合计)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export type ColumnChangeParam = {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,13 +1,16 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <div :class="prefixCls" :style="{ width: containerWidth }">
 | 
			
		||||
    <ImgUpload
 | 
			
		||||
      :fullscreen="fullscreen"
 | 
			
		||||
      @uploading="handleImageUploading"
 | 
			
		||||
      @done="handleDone"
 | 
			
		||||
      v-if="showImageUpload"
 | 
			
		||||
      v-show="editorRef"
 | 
			
		||||
      :disabled="disabled"
 | 
			
		||||
    />
 | 
			
		||||
  <div ref="editorRootRef" :class="prefixCls" :style="{ width: containerWidth }">
 | 
			
		||||
    <!-- update-begin--author:liaozhiyang---date:20240517---for:【TV360X-35】富文本,图片上传遮挡其他按钮 -->
 | 
			
		||||
    <Teleport v-if="imgUploadShow" :to="targetElem">
 | 
			
		||||
      <ImgUpload
 | 
			
		||||
        :fullscreen="fullscreen"
 | 
			
		||||
        @uploading="handleImageUploading"
 | 
			
		||||
        @done="handleDone"
 | 
			
		||||
        v-show="editorRef"
 | 
			
		||||
        :disabled="disabled"
 | 
			
		||||
      />
 | 
			
		||||
    </Teleport>
 | 
			
		||||
    <!-- update-end--author:liaozhiyang---date:20240517---for:【TV360X-35】富文本,图片上传遮挡其他按钮 -->
 | 
			
		||||
    <Editor :id="tinymceId" ref="elRef" :disabled="disabled" :init="initOptions" :style="{ visibility: 'hidden' }" v-if="!initOptions.inline"></Editor>
 | 
			
		||||
    <slot v-else></slot>
 | 
			
		||||
  </div>
 | 
			
		||||
| 
						 | 
				
			
			@ -27,7 +30,7 @@
 | 
			
		|||
  import 'tinymce/plugins/lists';
 | 
			
		||||
  import 'tinymce/plugins/preview';
 | 
			
		||||
  import 'tinymce/plugins/image';
 | 
			
		||||
  import { defineComponent, computed, nextTick, ref, unref, watch, onDeactivated, onBeforeUnmount } from 'vue';
 | 
			
		||||
  import { defineComponent, computed, nextTick, ref, unref, watch, onDeactivated, onBeforeUnmount, onMounted } from 'vue';
 | 
			
		||||
  import ImgUpload from './ImgUpload.vue';
 | 
			
		||||
  import {simpleToolbar, menubar, simplePlugins} from './tinymce';
 | 
			
		||||
  import { buildShortUUID } from '/@/utils/uuid';
 | 
			
		||||
| 
						 | 
				
			
			@ -39,6 +42,7 @@
 | 
			
		|||
  import { useAppStore } from '/@/store/modules/app';
 | 
			
		||||
  import { uploadFile } from '/@/api/common/api';
 | 
			
		||||
  import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
 | 
			
		||||
  import { ThemeEnum } from '/@/enums/appEnum';
 | 
			
		||||
  const tinymceProps = {
 | 
			
		||||
    options: {
 | 
			
		||||
      type: Object as PropType<Partial<RawEditorSettings>>,
 | 
			
		||||
| 
						 | 
				
			
			@ -92,6 +96,9 @@
 | 
			
		|||
      const fullscreen = ref(false);
 | 
			
		||||
      const tinymceId = ref<string>(buildShortUUID('tiny-vue'));
 | 
			
		||||
      const elRef = ref<Nullable<HTMLElement>>(null);
 | 
			
		||||
      const editorRootRef = ref<Nullable<HTMLElement>>(null);
 | 
			
		||||
      const imgUploadShow = ref(false);
 | 
			
		||||
      const targetElem = ref<null | HTMLDivElement>(null);
 | 
			
		||||
 | 
			
		||||
      const { prefixCls } = useDesign('tinymce-container');
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -231,6 +238,7 @@
 | 
			
		|||
        tinymce
 | 
			
		||||
          .init(unref(initOptions))
 | 
			
		||||
          .then((editor) => {
 | 
			
		||||
            changeColor();
 | 
			
		||||
            emit('inited', editor);
 | 
			
		||||
          })
 | 
			
		||||
          .catch((err) => {
 | 
			
		||||
| 
						 | 
				
			
			@ -311,7 +319,60 @@
 | 
			
		|||
      function getUploadingImgName(name: string) {
 | 
			
		||||
        return `[uploading:${name}]`;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20240517---for:【TV360X-35】富文本,图片上传遮挡其他按钮
 | 
			
		||||
      let executeCount = 0;
 | 
			
		||||
      watch(
 | 
			
		||||
        () => props.showImageUpload,
 | 
			
		||||
        () => {
 | 
			
		||||
          mountElem();
 | 
			
		||||
        }
 | 
			
		||||
      );
 | 
			
		||||
      onMounted(() => {
 | 
			
		||||
        mountElem();
 | 
			
		||||
      });
 | 
			
		||||
      const mountElem = () => {
 | 
			
		||||
        if (executeCount > 20) return;
 | 
			
		||||
        setTimeout(() => {
 | 
			
		||||
          if (targetElem.value) {
 | 
			
		||||
            imgUploadShow.value = props.showImageUpload;
 | 
			
		||||
          } else {
 | 
			
		||||
            const toxToolbar = editorRootRef.value?.querySelector('.tox-toolbar__group');
 | 
			
		||||
            if (toxToolbar) {
 | 
			
		||||
              const divElem = document.createElement('div');
 | 
			
		||||
              divElem.setAttribute('style', `width:64px;height:39px;display:flex;align-items:center;`);
 | 
			
		||||
              toxToolbar!.appendChild(divElem);
 | 
			
		||||
              targetElem.value = divElem;
 | 
			
		||||
              imgUploadShow.value = props.showImageUpload;
 | 
			
		||||
              executeCount = 0;
 | 
			
		||||
            } else {
 | 
			
		||||
              mountElem();
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
          executeCount++;
 | 
			
		||||
        }, 100);
 | 
			
		||||
      };
 | 
			
		||||
      // update-end--author:liaozhiyang---date:20240517---for:【TV360X-35】富文本,图片上传遮挡其他按钮
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20240327---for:【QQYUN-8639】暗黑主题适配
 | 
			
		||||
      function changeColor() {
 | 
			
		||||
        setTimeout(() => {
 | 
			
		||||
          const iframe = editorRootRef.value?.querySelector('iframe');
 | 
			
		||||
          const body = iframe?.contentDocument?.querySelector('body');
 | 
			
		||||
          if (body) {
 | 
			
		||||
            if (appStore.getDarkMode == ThemeEnum.DARK) {
 | 
			
		||||
              body.style.color = '#fff';
 | 
			
		||||
            } else {
 | 
			
		||||
              body.style.color = '#000';
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }, 300);
 | 
			
		||||
      }
 | 
			
		||||
      watch(
 | 
			
		||||
        () => appStore.getDarkMode,
 | 
			
		||||
        () => {
 | 
			
		||||
          changeColor();
 | 
			
		||||
        }
 | 
			
		||||
      );
 | 
			
		||||
      // update-end--author:liaozhiyang---date:20240327---for:【QQYUN-8639】暗黑主题适配
 | 
			
		||||
      return {
 | 
			
		||||
        prefixCls,
 | 
			
		||||
        containerWidth,
 | 
			
		||||
| 
						 | 
				
			
			@ -324,6 +385,9 @@
 | 
			
		|||
        editorRef,
 | 
			
		||||
        fullscreen,
 | 
			
		||||
        disabled,
 | 
			
		||||
        editorRootRef,
 | 
			
		||||
        imgUploadShow,
 | 
			
		||||
        targetElem,
 | 
			
		||||
      };
 | 
			
		||||
    },
 | 
			
		||||
  });
 | 
			
		||||
| 
						 | 
				
			
			@ -342,5 +406,22 @@
 | 
			
		|||
      z-index: -1;
 | 
			
		||||
      visibility: hidden;
 | 
			
		||||
    }
 | 
			
		||||
    .tox:not(.tox-tinymce-inline) .tox-editor-header {
 | 
			
		||||
      padding:0;
 | 
			
		||||
    }
 | 
			
		||||
    // update-begin--author:liaozhiyang---date:20240527---for:【TV360X-329】富文本禁用状态下工具栏划过边框丢失
 | 
			
		||||
    .tox .tox-tbtn--disabled,
 | 
			
		||||
    .tox .tox-tbtn--disabled:hover,
 | 
			
		||||
    .tox .tox-tbtn:disabled,
 | 
			
		||||
    .tox .tox-tbtn:disabled:hover {
 | 
			
		||||
      background-image: url("data:image/svg+xml;charset=utf8,%3Csvg height='39px' viewBox='0 0 40 39px' width='40' xmlns='http://www.w3.org/2000/svg'%3E%3Crect x='0' y='38px' width='100' height='1' fill='%23d9d9d9'/%3E%3C/svg%3E");
 | 
			
		||||
      background-position: left 0;
 | 
			
		||||
    }
 | 
			
		||||
    // update-end--author:liaozhiyang---date:20240527---for:【TV360X-329】富文本禁用状态下工具栏划过边框丢失
 | 
			
		||||
  }
 | 
			
		||||
  html[data-theme='dark'] {
 | 
			
		||||
    .@{prefix-cls} {
 | 
			
		||||
      .tox .tox-edit-area__iframe {background-color: #141414;}
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -105,11 +105,8 @@
 | 
			
		|||
  @prefix-cls: ~'@{namespace}-tinymce-img-upload';
 | 
			
		||||
 | 
			
		||||
  .@{prefix-cls} {
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    top: 8px;
 | 
			
		||||
    right: 10px;
 | 
			
		||||
    z-index: 20;
 | 
			
		||||
 | 
			
		||||
    background-color: @primary-color;
 | 
			
		||||
    margin: 0 3px;
 | 
			
		||||
    &.fullscreen {
 | 
			
		||||
      position: fixed;
 | 
			
		||||
      z-index: 10000;
 | 
			
		||||
| 
						 | 
				
			
			@ -119,6 +116,11 @@
 | 
			
		|||
      padding: 2px 4px;
 | 
			
		||||
      font-size: 12px;
 | 
			
		||||
      height: 24px;
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20240524---for:【TV360X-235】富文本禁用状态下图片上传按钮文字看不清
 | 
			
		||||
      &.is-disabled {
 | 
			
		||||
        color: rgba(255, 255, 255, 0.5);
 | 
			
		||||
      }
 | 
			
		||||
      // update-end--author:liaozhiyang---date:20240524---for:【TV360X-235】富文本禁用状态下图片上传按钮文字看不清
 | 
			
		||||
    }
 | 
			
		||||
    // update-end--author:liaozhiyang---date:20230326---for:【QQYUN-8647】online tinymce组件上传图片按遮挡了控件栏的全屏按钮
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,7 +13,7 @@ export const toolbar =
 | 
			
		|||
export const simplePlugins = 'lists image link fullscreen';
 | 
			
		||||
 | 
			
		||||
export const simpleToolbar = [
 | 
			
		||||
  'undo redo  formatselect bold italic alignleft aligncenter alignright alignjustify bullist numlist outdent indent lists image link fullscreen',
 | 
			
		||||
  'undo redo styles  bold italic alignleft aligncenter alignright alignjustify bullist numlist outdent indent lists image link fullscreen',
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
export const menubar = 'file edit insert view format table';
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,6 +24,12 @@
 | 
			
		|||
        type: String as PropType<string>,
 | 
			
		||||
        default: 'calc(100vh - 78px)',
 | 
			
		||||
      },
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20240407---for:【QQYUN-8762】首页默认及echars颜色调整
 | 
			
		||||
      seriesColor: {
 | 
			
		||||
        type: String,
 | 
			
		||||
        default: '#1890ff',
 | 
			
		||||
      },
 | 
			
		||||
      // update-end--author:liaozhiyang---date:20240407---for:【QQYUN-8762】首页默认及echars颜色调整
 | 
			
		||||
    },
 | 
			
		||||
    setup(props) {
 | 
			
		||||
      const chartRef = ref<HTMLDivElement | null>(null);
 | 
			
		||||
| 
						 | 
				
			
			@ -51,6 +57,7 @@
 | 
			
		|||
            name: 'bar',
 | 
			
		||||
            type: 'bar',
 | 
			
		||||
            data: [],
 | 
			
		||||
            color: props.seriesColor,
 | 
			
		||||
          },
 | 
			
		||||
        ],
 | 
			
		||||
      });
 | 
			
		||||
| 
						 | 
				
			
			@ -70,6 +77,9 @@
 | 
			
		|||
          return item.name;
 | 
			
		||||
        });
 | 
			
		||||
        option.series[0].data = seriesData;
 | 
			
		||||
        // update-begin--author:liaozhiyang---date:20240407---for:【QQYUN-8762】首页默认及echars颜色调整
 | 
			
		||||
        option.series[0].color = props.seriesColor;
 | 
			
		||||
        // update-end--author:liaozhiyang---date:20240407---for:【QQYUN-8762】首页默认及echars颜色调整
 | 
			
		||||
        option.xAxis.data = xAxisData;
 | 
			
		||||
        setOptions(option);
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,6 +29,12 @@
 | 
			
		|||
        type: String as PropType<string>,
 | 
			
		||||
        default: 'calc(100vh - 78px)',
 | 
			
		||||
      },
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20240407---for:【QQYUN-8762】首页默认及echars颜色调整
 | 
			
		||||
      seriesColor: {
 | 
			
		||||
        type: Array,
 | 
			
		||||
        default: () => [],
 | 
			
		||||
      },
 | 
			
		||||
      // update-end--author:liaozhiyang---date:20240407---for:【QQYUN-8762】首页默认及echars颜色调整
 | 
			
		||||
    },
 | 
			
		||||
    emits: ['click'],
 | 
			
		||||
    setup(props, { emit }) {
 | 
			
		||||
| 
						 | 
				
			
			@ -89,6 +95,14 @@
 | 
			
		|||
          // update-end-author:liusq date:2023-7-12 for: [issues/613] LineMulti 在数据不对齐时,横坐标计算错误
 | 
			
		||||
          //data数据
 | 
			
		||||
          obj['data'] = data;
 | 
			
		||||
          // update-begin--author:liaozhiyang---date:20240407---for:【QQYUN-8762】首页默认及echars颜色调整
 | 
			
		||||
          if (props.seriesColor?.length) {
 | 
			
		||||
            const findItem = props.seriesColor.find((item: any) => item.type === type);
 | 
			
		||||
            if (findItem?.color) {
 | 
			
		||||
              obj['color'] = findItem.color;
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
          // update-end--author:liaozhiyang---date:20240407---for:【QQYUN-8762】首页默认及echars颜色调整
 | 
			
		||||
          seriesData.push(obj);
 | 
			
		||||
        });
 | 
			
		||||
        option.series = seriesData;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -100,7 +100,6 @@
 | 
			
		|||
    text-overflow: ellipsis;
 | 
			
		||||
    word-break: break-all;
 | 
			
		||||
    white-space: nowrap;
 | 
			
		||||
    color: #000;
 | 
			
		||||
    margin-top: 4px;
 | 
			
		||||
    margin-bottom: 0;
 | 
			
		||||
    font-size: 30px;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,6 +25,12 @@
 | 
			
		|||
        type: String as PropType<string>,
 | 
			
		||||
        default: 'calc(100vh - 78px)',
 | 
			
		||||
      },
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20240407---for:【QQYUN-8762】首页默认及echars颜色调整
 | 
			
		||||
      seriesColor: {
 | 
			
		||||
        type: String,
 | 
			
		||||
        default: '#1890ff',
 | 
			
		||||
      },
 | 
			
		||||
      // update-end--author:liaozhiyang---date:20240407---for:【QQYUN-8762】首页默认及echars颜色调整
 | 
			
		||||
    },
 | 
			
		||||
    setup(props) {
 | 
			
		||||
      const chartRef = ref<HTMLDivElement | null>(null);
 | 
			
		||||
| 
						 | 
				
			
			@ -93,6 +99,9 @@
 | 
			
		|||
        }
 | 
			
		||||
        option.series[0].data[0].name = props.chartData.name;
 | 
			
		||||
        option.series[0].data[0].value = props.chartData.value;
 | 
			
		||||
        // update-begin--author:liaozhiyang---date:20240407---for:【QQYUN-8762】首页默认及echars颜色调整
 | 
			
		||||
        option.series[0].color = props.seriesColor;
 | 
			
		||||
        // update-end--author:liaozhiyang---date:20240407---for:【QQYUN-8762】首页默认及echars颜色调整
 | 
			
		||||
        setOptions(option);
 | 
			
		||||
      }
 | 
			
		||||
      return { chartRef };
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <div class="head-info" :class="center && 'center'">
 | 
			
		||||
    <span>{{ title }}</span>
 | 
			
		||||
    <p>{{ content }} <a-icon :type="icon" style="font-size: 24px; color: #2b99ff" /></p>
 | 
			
		||||
    <p :style="{ color: `${$props.iconColor}` }">{{ content }} <a-icon :type="icon" :style="{ fontSize: `24px`, color: `${$props.iconColor}` }" /></p>
 | 
			
		||||
    <em v-if="bordered" />
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
| 
						 | 
				
			
			@ -32,6 +32,12 @@
 | 
			
		|||
        type: String,
 | 
			
		||||
        default: false,
 | 
			
		||||
      },
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20240407---for:【QQYUN-8762】首页默认及echars颜色调整
 | 
			
		||||
      iconColor: {
 | 
			
		||||
        type: String,
 | 
			
		||||
        default: '#2b99ff',
 | 
			
		||||
      },
 | 
			
		||||
      // update-end--author:liaozhiyang---date:20240407---for:【QQYUN-8762】首页默认及echars颜色调整
 | 
			
		||||
    },
 | 
			
		||||
  });
 | 
			
		||||
</script>
 | 
			
		||||
| 
						 | 
				
			
			@ -49,7 +55,6 @@
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    span {
 | 
			
		||||
      color: rgba(0, 0, 0, 0.45);
 | 
			
		||||
      display: inline-block;
 | 
			
		||||
      font-size: 14px;
 | 
			
		||||
      line-height: 22px;
 | 
			
		||||
| 
						 | 
				
			
			@ -57,7 +62,6 @@
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    p {
 | 
			
		||||
      color: rgba(0, 0, 0, 0.85);
 | 
			
		||||
      font-size: 24px;
 | 
			
		||||
      line-height: 32px;
 | 
			
		||||
      margin: 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -77,6 +77,12 @@
 | 
			
		|||
        let seriesData = [];
 | 
			
		||||
        typeArr.forEach((type) => {
 | 
			
		||||
          let obj: any = { name: type, type: props.type };
 | 
			
		||||
          // update-begin--author:liaozhiyang---date:20240407---for:【QQYUN-8762】首页默认及echars颜色调整
 | 
			
		||||
          const findItem: any = props.chartData.find((item: any) => item.type == type);
 | 
			
		||||
          if (findItem && findItem.color) {
 | 
			
		||||
            obj.color = findItem.color;
 | 
			
		||||
          }
 | 
			
		||||
          // update-end--author:liaozhiyang---date:20240407---for:【QQYUN-8762】首页默认及echars颜色调整
 | 
			
		||||
          // update-begin-author:liusq date:2023-7-12 for: [issues/613] LineMulti 在数据不对齐时,横坐标计算错误
 | 
			
		||||
          let data = [];
 | 
			
		||||
          xAxisData.forEach((x) => {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -45,12 +45,12 @@
 | 
			
		|||
        margin-top: 16px;
 | 
			
		||||
 | 
			
		||||
        span {
 | 
			
		||||
          color: rgba(0, 0, 0, 0.65);
 | 
			
		||||
          font-size: 14px;
 | 
			
		||||
          line-height: 22px;
 | 
			
		||||
 | 
			
		||||
          &:first-child {
 | 
			
		||||
            background-color: #f5f5f5;
 | 
			
		||||
            color: rgba(0, 0, 0, 0.65);
 | 
			
		||||
            border-radius: 20px;
 | 
			
		||||
            display: inline-block;
 | 
			
		||||
            font-size: 12px;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,6 +24,12 @@
 | 
			
		|||
        type: String as PropType<string>,
 | 
			
		||||
        default: 'calc(100vh - 78px)',
 | 
			
		||||
      },
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20240407---for:【QQYUN-8762】首页默认及echars颜色调整
 | 
			
		||||
      seriesColor: {
 | 
			
		||||
        type: String,
 | 
			
		||||
        default: '#1890ff',
 | 
			
		||||
      },
 | 
			
		||||
      // update-end--author:liaozhiyang---date:20240407---for:【QQYUN-8762】首页默认及echars颜色调整
 | 
			
		||||
    },
 | 
			
		||||
    setup(props) {
 | 
			
		||||
      const chartRef = ref<HTMLDivElement | null>(null);
 | 
			
		||||
| 
						 | 
				
			
			@ -53,6 +59,7 @@
 | 
			
		|||
            smooth: true,
 | 
			
		||||
            areaStyle: {},
 | 
			
		||||
            data: [],
 | 
			
		||||
            color: props.seriesColor,
 | 
			
		||||
          },
 | 
			
		||||
        ],
 | 
			
		||||
      });
 | 
			
		||||
| 
						 | 
				
			
			@ -60,7 +67,7 @@
 | 
			
		|||
      watchEffect(() => {
 | 
			
		||||
        props.chartData && initCharts();
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      
 | 
			
		||||
      function initCharts() {
 | 
			
		||||
        if (props.option) {
 | 
			
		||||
          Object.assign(option, cloneDeep(props.option));
 | 
			
		||||
| 
						 | 
				
			
			@ -72,6 +79,9 @@
 | 
			
		|||
          return item.name;
 | 
			
		||||
        });
 | 
			
		||||
        option.series[0].data = seriesData;
 | 
			
		||||
        // update-begin--author:liaozhiyang---date:20240407---for:【QQYUN-8762】首页默认及echars颜色调整
 | 
			
		||||
        option.series[0].color = props.seriesColor;
 | 
			
		||||
        // update-end--author:liaozhiyang---date:20240407---for:【QQYUN-8762】首页默认及echars颜色调整
 | 
			
		||||
        option.xAxis.data = xAxisData;
 | 
			
		||||
        setOptions(option);
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -61,76 +61,81 @@
 | 
			
		|||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="footer">
 | 
			
		||||
        <a-button type="text" class="delBtn" @click="handleDelSession">
 | 
			
		||||
          <svg
 | 
			
		||||
            t="1706504908534"
 | 
			
		||||
            class="icon"
 | 
			
		||||
            viewBox="0 0 1024 1024"
 | 
			
		||||
            version="1.1"
 | 
			
		||||
            xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
            p-id="1584"
 | 
			
		||||
            width="18"
 | 
			
		||||
            height="18"
 | 
			
		||||
        <div class="topArea">
 | 
			
		||||
          <presetQuestion @outQuestion="handleOutQuestion"></presetQuestion>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="bottomArea">
 | 
			
		||||
          <a-button type="text" class="delBtn" @click="handleDelSession">
 | 
			
		||||
            <svg
 | 
			
		||||
              t="1706504908534"
 | 
			
		||||
              class="icon"
 | 
			
		||||
              viewBox="0 0 1024 1024"
 | 
			
		||||
              version="1.1"
 | 
			
		||||
              xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
              p-id="1584"
 | 
			
		||||
              width="18"
 | 
			
		||||
              height="18"
 | 
			
		||||
            >
 | 
			
		||||
              <path
 | 
			
		||||
                d="M816.872727 158.254545h-181.527272V139.636364c0-39.563636-30.254545-69.818182-69.818182-69.818182h-107.054546c-39.563636 0-69.818182 30.254545-69.818182 69.818182v18.618181H207.127273c-48.872727 0-90.763636 41.890909-90.763637 93.09091s41.890909 90.763636 90.763637 90.763636h609.745454c51.2 0 90.763636-41.890909 90.763637-90.763636 0-51.2-41.890909-93.090909-90.763637-93.09091zM435.2 139.636364c0-13.963636 9.309091-23.272727 23.272727-23.272728h107.054546c13.963636 0 23.272727 9.309091 23.272727 23.272728v18.618181h-153.6V139.636364z m381.672727 155.927272H207.127273c-25.6 0-44.218182-20.945455-44.218182-44.218181 0-25.6 20.945455-44.218182 44.218182-44.218182h609.745454c25.6 0 44.218182 20.945455 44.218182 44.218182 0 23.272727-20.945455 44.218182-44.218182 44.218181zM835.490909 407.272727h-121.018182c-13.963636 0-23.272727 9.309091-23.272727 23.272728s9.309091 23.272727 23.272727 23.272727h97.745455V837.818182c0 39.563636-30.254545 69.818182-69.818182 69.818182h-37.236364V602.763636c0-13.963636-9.309091-23.272727-23.272727-23.272727s-23.272727 9.309091-23.272727 23.272727V907.636364h-118.690909V602.763636c0-13.963636-9.309091-23.272727-23.272728-23.272727s-23.272727 9.309091-23.272727 23.272727V907.636364H372.363636V602.763636c0-13.963636-9.309091-23.272727-23.272727-23.272727s-23.272727 9.309091-23.272727 23.272727V907.636364h-34.909091c-39.563636 0-69.818182-30.254545-69.818182-69.818182V453.818182H558.545455c13.963636 0 23.272727-9.309091 23.272727-23.272727s-9.309091-23.272727-23.272727-23.272728H197.818182c-13.963636 0-23.272727 9.309091-23.272727 23.272728V837.818182c0 65.163636 51.2 116.363636 116.363636 116.363636h451.490909c65.163636 0 116.363636-51.2 116.363636-116.363636V430.545455c0-13.963636-11.636364-23.272727-23.272727-23.272728z"
 | 
			
		||||
                fill="currentColor"
 | 
			
		||||
                p-id="1585"
 | 
			
		||||
              ></path>
 | 
			
		||||
            </svg>
 | 
			
		||||
          </a-button>
 | 
			
		||||
          <a-button type="text" class="contextBtn" :class="[usingContext && 'enabled']" @click="handleUsingContext">
 | 
			
		||||
            <svg
 | 
			
		||||
              xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
              xmlns:xlink="http://www.w3.org/1999/xlink"
 | 
			
		||||
              aria-hidden="true"
 | 
			
		||||
              role="img"
 | 
			
		||||
              class="iconify iconify--ri"
 | 
			
		||||
              width="20"
 | 
			
		||||
              height="20"
 | 
			
		||||
              viewBox="0 0 24 24"
 | 
			
		||||
            >
 | 
			
		||||
              <path
 | 
			
		||||
                fill="currentColor"
 | 
			
		||||
                d="M12 2c5.523 0 10 4.477 10 10s-4.477 10-10 10a9.956 9.956 0 0 1-4.708-1.175L2 22l1.176-5.29A9.956 9.956 0 0 1 2 12C2 6.477 6.477 2 12 2m0 2a8 8 0 0 0-8 8c0 1.335.326 2.618.94 3.766l.35.654l-.656 2.946l2.948-.654l.653.349A7.955 7.955 0 0 0 12 20a8 8 0 1 0 0-16m1 3v5h4v2h-6V7z"
 | 
			
		||||
              ></path>
 | 
			
		||||
            </svg>
 | 
			
		||||
          </a-button>
 | 
			
		||||
          <a-textarea
 | 
			
		||||
            ref="inputRef"
 | 
			
		||||
            v-model:value="prompt"
 | 
			
		||||
            :autoSize="{ minRows: 1, maxRows: 6 }"
 | 
			
		||||
            :placeholder="placeholder"
 | 
			
		||||
            @pressEnter="handleEnter"
 | 
			
		||||
            autofocus
 | 
			
		||||
          ></a-textarea>
 | 
			
		||||
          <a-button
 | 
			
		||||
            @click="
 | 
			
		||||
              () => {
 | 
			
		||||
                handleSubmit();
 | 
			
		||||
              }
 | 
			
		||||
            "
 | 
			
		||||
            :disabled="loading"
 | 
			
		||||
            type="primary"
 | 
			
		||||
            class="sendBtn"
 | 
			
		||||
          >
 | 
			
		||||
            <path
 | 
			
		||||
              d="M816.872727 158.254545h-181.527272V139.636364c0-39.563636-30.254545-69.818182-69.818182-69.818182h-107.054546c-39.563636 0-69.818182 30.254545-69.818182 69.818182v18.618181H207.127273c-48.872727 0-90.763636 41.890909-90.763637 93.09091s41.890909 90.763636 90.763637 90.763636h609.745454c51.2 0 90.763636-41.890909 90.763637-90.763636 0-51.2-41.890909-93.090909-90.763637-93.09091zM435.2 139.636364c0-13.963636 9.309091-23.272727 23.272727-23.272728h107.054546c13.963636 0 23.272727 9.309091 23.272727 23.272728v18.618181h-153.6V139.636364z m381.672727 155.927272H207.127273c-25.6 0-44.218182-20.945455-44.218182-44.218181 0-25.6 20.945455-44.218182 44.218182-44.218182h609.745454c25.6 0 44.218182 20.945455 44.218182 44.218182 0 23.272727-20.945455 44.218182-44.218182 44.218181zM835.490909 407.272727h-121.018182c-13.963636 0-23.272727 9.309091-23.272727 23.272728s9.309091 23.272727 23.272727 23.272727h97.745455V837.818182c0 39.563636-30.254545 69.818182-69.818182 69.818182h-37.236364V602.763636c0-13.963636-9.309091-23.272727-23.272727-23.272727s-23.272727 9.309091-23.272727 23.272727V907.636364h-118.690909V602.763636c0-13.963636-9.309091-23.272727-23.272728-23.272727s-23.272727 9.309091-23.272727 23.272727V907.636364H372.363636V602.763636c0-13.963636-9.309091-23.272727-23.272727-23.272727s-23.272727 9.309091-23.272727 23.272727V907.636364h-34.909091c-39.563636 0-69.818182-30.254545-69.818182-69.818182V453.818182H558.545455c13.963636 0 23.272727-9.309091 23.272727-23.272727s-9.309091-23.272727-23.272727-23.272728H197.818182c-13.963636 0-23.272727 9.309091-23.272727 23.272728V837.818182c0 65.163636 51.2 116.363636 116.363636 116.363636h451.490909c65.163636 0 116.363636-51.2 116.363636-116.363636V430.545455c0-13.963636-11.636364-23.272727-23.272727-23.272728z"
 | 
			
		||||
              fill="currentColor"
 | 
			
		||||
              p-id="1585"
 | 
			
		||||
            ></path>
 | 
			
		||||
          </svg>
 | 
			
		||||
        </a-button>
 | 
			
		||||
        <a-button type="text" class="contextBtn" :class="[usingContext && 'enabled']" @click="handleUsingContext">
 | 
			
		||||
          <svg
 | 
			
		||||
            xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
            xmlns:xlink="http://www.w3.org/1999/xlink"
 | 
			
		||||
            aria-hidden="true"
 | 
			
		||||
            role="img"
 | 
			
		||||
            class="iconify iconify--ri"
 | 
			
		||||
            width="20"
 | 
			
		||||
            height="20"
 | 
			
		||||
            viewBox="0 0 24 24"
 | 
			
		||||
          >
 | 
			
		||||
            <path
 | 
			
		||||
              fill="currentColor"
 | 
			
		||||
              d="M12 2c5.523 0 10 4.477 10 10s-4.477 10-10 10a9.956 9.956 0 0 1-4.708-1.175L2 22l1.176-5.29A9.956 9.956 0 0 1 2 12C2 6.477 6.477 2 12 2m0 2a8 8 0 0 0-8 8c0 1.335.326 2.618.94 3.766l.35.654l-.656 2.946l2.948-.654l.653.349A7.955 7.955 0 0 0 12 20a8 8 0 1 0 0-16m1 3v5h4v2h-6V7z"
 | 
			
		||||
            ></path>
 | 
			
		||||
          </svg>
 | 
			
		||||
        </a-button>
 | 
			
		||||
        <a-textarea
 | 
			
		||||
          ref="inputRef"
 | 
			
		||||
          v-model:value="prompt"
 | 
			
		||||
          :autoSize="{ minRows: 1, maxRows: 6 }"
 | 
			
		||||
          :placeholder="placeholder"
 | 
			
		||||
          @pressEnter="handleEnter"
 | 
			
		||||
          autofocus
 | 
			
		||||
        ></a-textarea>
 | 
			
		||||
        <a-button
 | 
			
		||||
          @click="
 | 
			
		||||
            () => {
 | 
			
		||||
              handleSubmit();
 | 
			
		||||
            }
 | 
			
		||||
          "
 | 
			
		||||
          :disabled="loading"
 | 
			
		||||
          type="primary"
 | 
			
		||||
          class="sendBtn"
 | 
			
		||||
        >
 | 
			
		||||
          <svg
 | 
			
		||||
            t="1706147858151"
 | 
			
		||||
            class="icon"
 | 
			
		||||
            viewBox="0 0 1024 1024"
 | 
			
		||||
            version="1.1"
 | 
			
		||||
            xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
            p-id="4237"
 | 
			
		||||
            width="1em"
 | 
			
		||||
            height="1em"
 | 
			
		||||
          >
 | 
			
		||||
            <path
 | 
			
		||||
              d="M865.28 202.5472c-17.1008-15.2576-41.0624-19.6608-62.5664-11.5712L177.7664 427.1104c-23.2448 8.8064-38.5024 29.696-39.6288 54.5792-1.1264 24.8832 11.9808 47.104 34.4064 58.0608l97.5872 47.7184c4.5056 2.2528 8.0896 6.0416 9.9328 10.6496l65.4336 161.1776c7.7824 19.1488 24.4736 32.9728 44.7488 37.0688 20.2752 4.096 41.0624-2.1504 55.6032-16.7936l36.352-36.352c6.4512-6.4512 16.5888-7.8848 24.576-3.3792l156.5696 88.8832c9.4208 5.3248 19.8656 8.0896 30.3104 8.0896 8.192 0 16.4864-1.6384 24.2688-5.0176 17.8176-7.68 30.72-22.8352 35.4304-41.6768l130.7648-527.1552c5.5296-22.016-1.7408-45.2608-18.8416-60.416z m-20.8896 50.7904L713.5232 780.4928c-1.536 6.2464-5.8368 11.3664-11.776 13.9264s-12.5952 2.1504-18.2272-1.024L526.9504 704.512c-9.4208-5.3248-19.8656-7.9872-30.208-7.9872-15.9744 0-31.744 6.144-43.52 17.92l-36.352 36.352c-3.8912 3.8912-8.9088 5.9392-14.2336 6.0416l55.6032-152.1664c0.512-1.3312 1.2288-2.56 2.2528-3.6864l240.3328-246.1696c8.2944-8.4992-2.048-21.9136-12.3904-16.0768L301.6704 559.8208c-4.096-3.584-8.704-6.656-13.6192-9.1136L190.464 502.9888c-11.264-5.5296-11.5712-16.1792-11.4688-19.3536 0.1024-3.1744 1.536-13.824 13.2096-18.2272L817.152 229.2736c10.4448-3.9936 18.0224 1.3312 20.8896 3.8912 2.8672 2.4576 9.0112 9.3184 6.3488 20.1728z"
 | 
			
		||||
              p-id="4238"
 | 
			
		||||
              fill="currentColor"
 | 
			
		||||
            ></path>
 | 
			
		||||
          </svg>
 | 
			
		||||
        </a-button>
 | 
			
		||||
            <svg
 | 
			
		||||
              t="1706147858151"
 | 
			
		||||
              class="icon"
 | 
			
		||||
              viewBox="0 0 1024 1024"
 | 
			
		||||
              version="1.1"
 | 
			
		||||
              xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
              p-id="4237"
 | 
			
		||||
              width="1em"
 | 
			
		||||
              height="1em"
 | 
			
		||||
            >
 | 
			
		||||
              <path
 | 
			
		||||
                d="M865.28 202.5472c-17.1008-15.2576-41.0624-19.6608-62.5664-11.5712L177.7664 427.1104c-23.2448 8.8064-38.5024 29.696-39.6288 54.5792-1.1264 24.8832 11.9808 47.104 34.4064 58.0608l97.5872 47.7184c4.5056 2.2528 8.0896 6.0416 9.9328 10.6496l65.4336 161.1776c7.7824 19.1488 24.4736 32.9728 44.7488 37.0688 20.2752 4.096 41.0624-2.1504 55.6032-16.7936l36.352-36.352c6.4512-6.4512 16.5888-7.8848 24.576-3.3792l156.5696 88.8832c9.4208 5.3248 19.8656 8.0896 30.3104 8.0896 8.192 0 16.4864-1.6384 24.2688-5.0176 17.8176-7.68 30.72-22.8352 35.4304-41.6768l130.7648-527.1552c5.5296-22.016-1.7408-45.2608-18.8416-60.416z m-20.8896 50.7904L713.5232 780.4928c-1.536 6.2464-5.8368 11.3664-11.776 13.9264s-12.5952 2.1504-18.2272-1.024L526.9504 704.512c-9.4208-5.3248-19.8656-7.9872-30.208-7.9872-15.9744 0-31.744 6.144-43.52 17.92l-36.352 36.352c-3.8912 3.8912-8.9088 5.9392-14.2336 6.0416l55.6032-152.1664c0.512-1.3312 1.2288-2.56 2.2528-3.6864l240.3328-246.1696c8.2944-8.4992-2.048-21.9136-12.3904-16.0768L301.6704 559.8208c-4.096-3.584-8.704-6.656-13.6192-9.1136L190.464 502.9888c-11.264-5.5296-11.5712-16.1792-11.4688-19.3536 0.1024-3.1744 1.536-13.824 13.2096-18.2272L817.152 229.2736c10.4448-3.9936 18.0224 1.3312 20.8896 3.8912 2.8672 2.4576 9.0112 9.3184 6.3488 20.1728z"
 | 
			
		||||
                p-id="4238"
 | 
			
		||||
                fill="currentColor"
 | 
			
		||||
              ></path>
 | 
			
		||||
            </svg>
 | 
			
		||||
          </a-button>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
| 
						 | 
				
			
			@ -145,8 +150,9 @@
 | 
			
		|||
  import { getToken } from '/@/utils/auth';
 | 
			
		||||
  import { getAppEnvConfig } from '/@/utils/env';
 | 
			
		||||
  import chatMessage from './chatMessage.vue';
 | 
			
		||||
  import presetQuestion from './presetQuestion.vue';
 | 
			
		||||
  import { DeleteOutlined, ExclamationCircleOutlined } from '@ant-design/icons-vue';
 | 
			
		||||
  import { message, Modal } from 'ant-design-vue';
 | 
			
		||||
  import { message, Modal, Tabs } from 'ant-design-vue';
 | 
			
		||||
  import '../style/github-markdown.less';
 | 
			
		||||
  import '../style/highlight.less';
 | 
			
		||||
  import '../style/style.less';
 | 
			
		||||
| 
						 | 
				
			
			@ -165,6 +171,7 @@
 | 
			
		|||
    return props.uuid;
 | 
			
		||||
  });
 | 
			
		||||
  let evtSource: any = null;
 | 
			
		||||
  // const presetQuestion = ref(['小红书文案', '朋友圈文案', '演讲稿生成']);
 | 
			
		||||
  const { VITE_GLOB_API_URL } = getAppEnvConfig();
 | 
			
		||||
 | 
			
		||||
  const conversationList = computed(() => props.chatData.filter((item) => !item.inversion && !!item.conversationOptions));
 | 
			
		||||
| 
						 | 
				
			
			@ -179,15 +186,17 @@
 | 
			
		|||
    }
 | 
			
		||||
  }
 | 
			
		||||
  function handleSubmit() {
 | 
			
		||||
    onConversation();
 | 
			
		||||
  }
 | 
			
		||||
  async function onConversation() {
 | 
			
		||||
    let message = prompt.value;
 | 
			
		||||
    if (loading.value) return;
 | 
			
		||||
    if (!message || message.trim() === '') return;
 | 
			
		||||
 | 
			
		||||
    loading.value = true;
 | 
			
		||||
    prompt.value = '';
 | 
			
		||||
    onConversation(message);
 | 
			
		||||
  }
 | 
			
		||||
  const handleOutQuestion = (message) => {
 | 
			
		||||
    onConversation(message);
 | 
			
		||||
  };
 | 
			
		||||
  async function onConversation(message) {
 | 
			
		||||
    if (loading.value) return;
 | 
			
		||||
    loading.value = true;
 | 
			
		||||
 | 
			
		||||
    if (props.chatData.length == 0) {
 | 
			
		||||
      const findItem = props.dataSource.history.find((item) => item.uuid === uuid.value);
 | 
			
		||||
| 
						 | 
				
			
			@ -225,7 +234,7 @@
 | 
			
		|||
      if (typeof EventSource !== 'undefined') {
 | 
			
		||||
        const token = getToken();
 | 
			
		||||
        evtSource = new EventSourcePolyfill(
 | 
			
		||||
          `${VITE_GLOB_API_URL}/ai/chat/send?message=${message}${options.parentMessageId ? '&topicId=' + options.parentMessageId : ''}`,
 | 
			
		||||
          `${VITE_GLOB_API_URL}/test/ai/chat/send?message=${message}${options.parentMessageId ? '&topicId=' + options.parentMessageId : ''}`,
 | 
			
		||||
          {
 | 
			
		||||
            withCredentials: true,
 | 
			
		||||
            headers: {
 | 
			
		||||
| 
						 | 
				
			
			@ -403,43 +412,52 @@
 | 
			
		|||
  }
 | 
			
		||||
  .footer {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    flex-direction: column;
 | 
			
		||||
    padding: 6px 16px;
 | 
			
		||||
    .ant-input {
 | 
			
		||||
      margin: 0 16px;
 | 
			
		||||
    .topArea {
 | 
			
		||||
      padding-left: 94px;
 | 
			
		||||
      margin-bottom: 6px;
 | 
			
		||||
    }
 | 
			
		||||
    .ant-input,
 | 
			
		||||
    .ant-btn {
 | 
			
		||||
      height: 36px;
 | 
			
		||||
    }
 | 
			
		||||
    textarea.ant-input {
 | 
			
		||||
      padding-top: 6px;
 | 
			
		||||
      padding-bottom: 6px;
 | 
			
		||||
    }
 | 
			
		||||
    .contextBtn,
 | 
			
		||||
    .delBtn {
 | 
			
		||||
      padding: 0;
 | 
			
		||||
      width: 40px;
 | 
			
		||||
      border-radius: 50%;
 | 
			
		||||
    .bottomArea {
 | 
			
		||||
      display: flex;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      justify-content: center;
 | 
			
		||||
    }
 | 
			
		||||
    .delBtn {
 | 
			
		||||
      margin-right: 8px;
 | 
			
		||||
    }
 | 
			
		||||
    .contextBtn {
 | 
			
		||||
      color: #a8071a;
 | 
			
		||||
      &.enabled {
 | 
			
		||||
        color: @primary-color;
 | 
			
		||||
 | 
			
		||||
      .ant-input {
 | 
			
		||||
        margin: 0 16px;
 | 
			
		||||
      }
 | 
			
		||||
      .ant-input,
 | 
			
		||||
      .ant-btn {
 | 
			
		||||
        height: 36px;
 | 
			
		||||
      }
 | 
			
		||||
      textarea.ant-input {
 | 
			
		||||
        padding-top: 6px;
 | 
			
		||||
        padding-bottom: 6px;
 | 
			
		||||
      }
 | 
			
		||||
      .contextBtn,
 | 
			
		||||
      .delBtn {
 | 
			
		||||
        padding: 0;
 | 
			
		||||
        width: 40px;
 | 
			
		||||
        border-radius: 50%;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        justify-content: center;
 | 
			
		||||
      }
 | 
			
		||||
      .delBtn {
 | 
			
		||||
        margin-right: 8px;
 | 
			
		||||
      }
 | 
			
		||||
      .contextBtn {
 | 
			
		||||
        color: #a8071a;
 | 
			
		||||
        &.enabled {
 | 
			
		||||
          color: @primary-color;
 | 
			
		||||
        }
 | 
			
		||||
        font-size: 18px;
 | 
			
		||||
      }
 | 
			
		||||
      .sendBtn {
 | 
			
		||||
        padding: 0 10px;
 | 
			
		||||
        font-size: 22px;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
      }
 | 
			
		||||
      font-size: 18px;
 | 
			
		||||
    }
 | 
			
		||||
    .sendBtn {
 | 
			
		||||
      padding: 0 10px;
 | 
			
		||||
      font-size: 22px;
 | 
			
		||||
      display: flex;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,9 +23,10 @@
 | 
			
		|||
  import defaultAvatar from '../assets/avatar.jpg';
 | 
			
		||||
  import { useUserStore } from '/@/store/modules/user';
 | 
			
		||||
  const props = defineProps(['dateTime', 'text', 'inversion', 'error', 'loading']);
 | 
			
		||||
  import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
 | 
			
		||||
  const { userInfo } = useUserStore();
 | 
			
		||||
  const avatar = () => {
 | 
			
		||||
    return userInfo?.avatar || defaultAvatar;
 | 
			
		||||
    return getFileAccessHttpUrl(userInfo?.avatar)|| defaultAvatar;
 | 
			
		||||
  };
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,151 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <div class="presetQuestion-wrap">
 | 
			
		||||
    <svg
 | 
			
		||||
      v-if="btnShow"
 | 
			
		||||
      class="leftBtn"
 | 
			
		||||
      :class="leftBtnStatus"
 | 
			
		||||
      t="1710296339017"
 | 
			
		||||
      viewBox="0 0 1024 1024"
 | 
			
		||||
      version="1.1"
 | 
			
		||||
      xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
      p-id="5070"
 | 
			
		||||
      @click="onScroll('prev')"
 | 
			
		||||
    >
 | 
			
		||||
      <path
 | 
			
		||||
        d="M970.496 543.829333l30.165333-30.165333-415.829333-415.914667a42.837333 42.837333 0 0 0-60.288 0 42.538667 42.538667 0 0 0 0 60.330667l355.413333 355.498667-355.413333 355.285333a42.496 42.496 0 0 0 0 60.288c16.64 16.64 43.861333 16.469333 60.288 0.042667l383.914667-383.701334 1.749333-1.664z"
 | 
			
		||||
        fill="currentColor"
 | 
			
		||||
        p-id="5071"
 | 
			
		||||
      ></path>
 | 
			
		||||
    </svg>
 | 
			
		||||
    <div class="content">
 | 
			
		||||
      <ul ref="ulElemRef">
 | 
			
		||||
        <li v-for="(item, index) in data" :key="index" class="item" @click="handleQuestion(item)">{{ item }}</li>
 | 
			
		||||
      </ul>
 | 
			
		||||
    </div>
 | 
			
		||||
    <svg
 | 
			
		||||
      v-if="btnShow"
 | 
			
		||||
      class="rightBtn"
 | 
			
		||||
      :class="rightBtnStatus"
 | 
			
		||||
      t="1710296339017"
 | 
			
		||||
      viewBox="0 0 1024 1024"
 | 
			
		||||
      version="1.1"
 | 
			
		||||
      xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
      p-id="5070"
 | 
			
		||||
      @click="onScroll('next')"
 | 
			
		||||
    >
 | 
			
		||||
      <path
 | 
			
		||||
        d="M970.496 543.829333l30.165333-30.165333-415.829333-415.914667a42.837333 42.837333 0 0 0-60.288 0 42.538667 42.538667 0 0 0 0 60.330667l355.413333 355.498667-355.413333 355.285333a42.496 42.496 0 0 0 0 60.288c16.64 16.64 43.861333 16.469333 60.288 0.042667l383.914667-383.701334 1.749333-1.664z"
 | 
			
		||||
        fill="currentColor"
 | 
			
		||||
        p-id="5071"
 | 
			
		||||
      ></path>
 | 
			
		||||
    </svg>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script name="presetQuestion" setup lang="ts">
 | 
			
		||||
  import { ref, onMounted, onBeforeUnmount } from 'vue';
 | 
			
		||||
  const emit = defineEmits(['outQuestion']);
 | 
			
		||||
  const data = ref(['请介绍一下JeecgBoot', 'JEECG有哪些优势?', 'JEECG可以做哪些事情?']);
 | 
			
		||||
  const leftBtnStatus = ref('');
 | 
			
		||||
  const rightBtnStatus = ref('');
 | 
			
		||||
  const rightBtn = ref('');
 | 
			
		||||
  const ulElemRef = ref(null);
 | 
			
		||||
  const btnShow = ref(false);
 | 
			
		||||
  let timer = null;
 | 
			
		||||
  const handleScroll = (e) => {
 | 
			
		||||
    clearTimeout(timer);
 | 
			
		||||
    timer = setTimeout(() => {
 | 
			
		||||
      const scrollLeft = e.target.scrollLeft;
 | 
			
		||||
      const offsetWidth = e.target.offsetWidth;
 | 
			
		||||
      const scrollWidth = e.target.scrollWidth;
 | 
			
		||||
      if (scrollWidth > offsetWidth) {
 | 
			
		||||
        btnShow.value = true;
 | 
			
		||||
      } else {
 | 
			
		||||
        btnShow.value = false;
 | 
			
		||||
      }
 | 
			
		||||
      if (scrollLeft <= 0) {
 | 
			
		||||
        leftBtnStatus.value = 'disabled';
 | 
			
		||||
      } else if (scrollWidth - offsetWidth == scrollLeft) {
 | 
			
		||||
        rightBtnStatus.value = 'disabled';
 | 
			
		||||
      } else {
 | 
			
		||||
        leftBtnStatus.value = '';
 | 
			
		||||
        rightBtnStatus.value = '';
 | 
			
		||||
      }
 | 
			
		||||
    }, 100);
 | 
			
		||||
  };
 | 
			
		||||
  const onScroll = (flag) => {
 | 
			
		||||
    const offsetWidth = ulElemRef.value.offsetWidth;
 | 
			
		||||
    if (flag == 'prev') {
 | 
			
		||||
      ulElemRef.value.scrollLeft = ulElemRef.value.scrollLeft - offsetWidth;
 | 
			
		||||
    } else if (flag == 'next') {
 | 
			
		||||
      ulElemRef.value.scrollLeft = ulElemRef.value.scrollLeft + offsetWidth;
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
  const handleQuestion = (item) => {
 | 
			
		||||
    emit('outQuestion', item);
 | 
			
		||||
  };
 | 
			
		||||
  onMounted(() => {
 | 
			
		||||
    ulElemRef.value.addEventListener('scroll', handleScroll, false);
 | 
			
		||||
    handleScroll({ target: ulElemRef.value });
 | 
			
		||||
  });
 | 
			
		||||
  onBeforeUnmount(() => {
 | 
			
		||||
    ulElemRef.value.removeEventListener('scroll', handleScroll);
 | 
			
		||||
  });
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="less" scoped>
 | 
			
		||||
  .presetQuestion-wrap {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    svg {
 | 
			
		||||
      width: 14px;
 | 
			
		||||
      height: 14px;
 | 
			
		||||
      flex: none;
 | 
			
		||||
      cursor: pointer;
 | 
			
		||||
      color: #333;
 | 
			
		||||
      &.leftBtn {
 | 
			
		||||
        transform: rotate(180deg);
 | 
			
		||||
      }
 | 
			
		||||
      &.disabled {
 | 
			
		||||
        opacity: 0.5;
 | 
			
		||||
        pointer-events: none;
 | 
			
		||||
        cursor: default;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    .content {
 | 
			
		||||
      flex: 1;
 | 
			
		||||
      min-width: 0;
 | 
			
		||||
      overflow: hidden;
 | 
			
		||||
    }
 | 
			
		||||
    ul {
 | 
			
		||||
      display: flex;
 | 
			
		||||
      margin-bottom: 0;
 | 
			
		||||
      width: 100%;
 | 
			
		||||
      overflow-y: auto;
 | 
			
		||||
      /* 隐藏所有滚动条 */
 | 
			
		||||
      &::-webkit-scrollbar {
 | 
			
		||||
        display: none;
 | 
			
		||||
        height: 0;
 | 
			
		||||
        width: 0;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    .item {
 | 
			
		||||
      border: 1px solid rgba(0, 0, 0, 0.1);
 | 
			
		||||
      border-radius: 16px;
 | 
			
		||||
      cursor: pointer;
 | 
			
		||||
      font-size: 14px;
 | 
			
		||||
      padding: 2px 10px;
 | 
			
		||||
      width: max-content;
 | 
			
		||||
      margin-right: 6px;
 | 
			
		||||
      white-space: nowrap;
 | 
			
		||||
      transition: all 300ms ease;
 | 
			
		||||
      &:last-child {
 | 
			
		||||
        margin-right: 0;
 | 
			
		||||
      }
 | 
			
		||||
      &:hover {
 | 
			
		||||
        color: @primary-color;
 | 
			
		||||
        border-color: @primary-color;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			@ -67,6 +67,7 @@
 | 
			
		|||
                width="1em"
 | 
			
		||||
                height="1em"
 | 
			
		||||
                viewBox="0 0 24 24"
 | 
			
		||||
                @click.stop=""
 | 
			
		||||
              >
 | 
			
		||||
                <path
 | 
			
		||||
                  fill="currentColor"
 | 
			
		||||
| 
						 | 
				
			
			@ -212,6 +213,11 @@
 | 
			
		|||
        height: 8px;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    .historyArea ul li:hover{
 | 
			
		||||
      .del{
 | 
			
		||||
        display: block;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    .createArea {
 | 
			
		||||
      padding: 20px;
 | 
			
		||||
      padding-bottom: 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,8 +33,8 @@
 | 
			
		|||
  import { JEECG_CHAT_KEY } from '/@/enums/cacheEnum';
 | 
			
		||||
  import { defHttp } from '/@/utils/http/axios';
 | 
			
		||||
  const configUrl = {
 | 
			
		||||
    get: '/ai/chat/history/get',
 | 
			
		||||
    save: '/ai/chat/history/save',
 | 
			
		||||
    get: '/test/ai/chat/history/get',
 | 
			
		||||
    save: '/test/ai/chat/history/save',
 | 
			
		||||
  };
 | 
			
		||||
  const userId = useUserStore().getUserInfo?.id;
 | 
			
		||||
  const localKey = JEECG_CHAT_KEY + userId;
 | 
			
		||||
| 
						 | 
				
			
			@ -199,5 +199,6 @@
 | 
			
		|||
      margin-left: 0;
 | 
			
		||||
    }
 | 
			
		||||
    flex: 1;
 | 
			
		||||
    min-width: 0;
 | 
			
		||||
  }
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,8 @@
 | 
			
		|||
import { defineComponent, h, ref, useSlots } from 'vue';
 | 
			
		||||
import { defineComponent, h, nextTick, ref, useSlots } from 'vue';
 | 
			
		||||
import { vxeEmits, vxeProps } from './vxe.data';
 | 
			
		||||
import { useData, useRefs, useResolveComponent as rc } from './hooks/useData';
 | 
			
		||||
import { useColumns } from './hooks/useColumns';
 | 
			
		||||
import { useColumnsCache } from './hooks/useColumnsCache';
 | 
			
		||||
import { useMethods } from './hooks/useMethods';
 | 
			
		||||
import { useDataSource } from './hooks/useDataSource';
 | 
			
		||||
import { useDragSort } from './hooks/useDragSort';
 | 
			
		||||
| 
						 | 
				
			
			@ -25,6 +26,10 @@ export default defineComponent({
 | 
			
		|||
    useColumns(props, data, methods, slots);
 | 
			
		||||
    useDataSource(props, data, methods, refs);
 | 
			
		||||
    useDragSort(props, methods);
 | 
			
		||||
    // update-begin--author:liaozhiyang---date:20240321---for:【QQYUN-8566】JVXETable无法记住列设置
 | 
			
		||||
    const { initSetting } = useColumnsCache({ cacheColumnsKey: props.cacheColumnsKey });
 | 
			
		||||
    initSetting(props);
 | 
			
		||||
    // update-end--author:liaozhiyang---date:20240321---for:【QQYUN-8566】JVXETable无法记住列设置
 | 
			
		||||
    // 最终传入到 template 里的 props
 | 
			
		||||
    const finallyProps = useFinallyProps(props, data, methods);
 | 
			
		||||
    // 渲染子组件
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <div :class="boxClass">
 | 
			
		||||
    <vxe-toolbar ref="xToolbarRef" custom>
 | 
			
		||||
    <vxe-toolbar ref="xToolbarRef" :custom="custom">
 | 
			
		||||
      <!-- 工具按钮 -->
 | 
			
		||||
      <template #buttons>
 | 
			
		||||
        <div :class="`${prefixCls}-button div`" :size="btnSize">
 | 
			
		||||
| 
						 | 
				
			
			@ -41,6 +41,7 @@
 | 
			
		|||
  const props = defineProps({
 | 
			
		||||
    size: propTypes.string,
 | 
			
		||||
    disabled: propTypes.bool.def(false),
 | 
			
		||||
    custom: propTypes.bool.def(false),
 | 
			
		||||
    toolbarConfig: propTypes.object,
 | 
			
		||||
    disabledRows: propTypes.object,
 | 
			
		||||
    hasBtnAuth: propTypes.func,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <div :class="boxClass" :style="boxStyle">
 | 
			
		||||
  <div :class="boxClass" :style="boxStyle" title="">
 | 
			
		||||
    <a-checkbox :checked="innerValue" v-bind="cellProps" @change="handleChange" />
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,12 +2,14 @@
 | 
			
		|||
  <a-date-picker
 | 
			
		||||
    :value="innerDateValue"
 | 
			
		||||
    allowClear
 | 
			
		||||
    :format="dateFormat"
 | 
			
		||||
    :format="picker ? null : dateFormat"
 | 
			
		||||
    :showTime="isDatetime"
 | 
			
		||||
    :valueFormat="picker ? dateFormat : null"
 | 
			
		||||
    popupClassName="j-vxe-date-picker"
 | 
			
		||||
    style="min-width: 0"
 | 
			
		||||
    v-model:open="openPicker"
 | 
			
		||||
    v-bind="cellProps"
 | 
			
		||||
    :picker="picker"
 | 
			
		||||
    @change="handleChange"
 | 
			
		||||
  />
 | 
			
		||||
</template>
 | 
			
		||||
| 
						 | 
				
			
			@ -18,6 +20,7 @@
 | 
			
		|||
  import { JVxeComponent, JVxeTypes } from '/@/components/jeecg/JVxeTable/types';
 | 
			
		||||
  import { useJVxeComponent, useJVxeCompProps } from '/@/components/jeecg/JVxeTable/hooks';
 | 
			
		||||
  import { isEmpty } from '/@/utils/is';
 | 
			
		||||
  import { getWeekMonthQuarterYear } from '/@/utils';
 | 
			
		||||
 | 
			
		||||
  export default defineComponent({
 | 
			
		||||
    name: 'JVxeDateCell',
 | 
			
		||||
| 
						 | 
				
			
			@ -31,6 +34,12 @@
 | 
			
		|||
        return format ? format : isDatetime.value ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD';
 | 
			
		||||
      });
 | 
			
		||||
      const openPicker = ref(true);
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20240509---for:【QQYUN-9205】一对多(jVxetable组件date)支持年,年月,年度度,年周
 | 
			
		||||
      const picker = computed(() => {
 | 
			
		||||
        const picker = originColumn.value.picker;
 | 
			
		||||
        return picker ? picker : null;
 | 
			
		||||
      });
 | 
			
		||||
      // update-end--author:liaozhiyang---date:20240509---for:【QQYUN-9205】一对多(jVxetable组件date)支持年,年月,年度度,年周
 | 
			
		||||
      watch(
 | 
			
		||||
        innerValue,
 | 
			
		||||
        (val) => {
 | 
			
		||||
| 
						 | 
				
			
			@ -44,7 +53,13 @@
 | 
			
		|||
      );
 | 
			
		||||
 | 
			
		||||
      function handleChange(_mom, dateStr) {
 | 
			
		||||
        handleChangeCommon(dateStr);
 | 
			
		||||
        // update-begin--author:liaozhiyang---date:20240509---for:【QQYUN-9205】一对多(jVxetable组件date)支持年,年月,年度度,年周
 | 
			
		||||
        if (picker.value) {
 | 
			
		||||
          handleChangeCommon(_mom);
 | 
			
		||||
        } else {
 | 
			
		||||
          handleChangeCommon(dateStr);
 | 
			
		||||
        }
 | 
			
		||||
        // update-begin--author:liaozhiyang---date:20240509---for:【QQYUN-9205】一对多(jVxetable组件date)支持年,年月,年度度,年周
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return {
 | 
			
		||||
| 
						 | 
				
			
			@ -54,12 +69,26 @@
 | 
			
		|||
        innerDateValue,
 | 
			
		||||
        openPicker,
 | 
			
		||||
        handleChange,
 | 
			
		||||
        picker,
 | 
			
		||||
      };
 | 
			
		||||
    },
 | 
			
		||||
    // 【组件增强】注释详见:JVxeComponent.Enhanced
 | 
			
		||||
    enhanced: {
 | 
			
		||||
      aopEvents: {
 | 
			
		||||
      },
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20240509---for:【QQYUN-9205】一对多(jVxetable组件date)支持年,年月,年度度,年周
 | 
			
		||||
      translate: {
 | 
			
		||||
        enabled: true,
 | 
			
		||||
        handler(value, ctx) {
 | 
			
		||||
          let { props, context } = ctx!;
 | 
			
		||||
          let { row, originColumn } = context;
 | 
			
		||||
          if (originColumn.value.picker && value) {
 | 
			
		||||
            return getWeekMonthQuarterYear(value)[originColumn.value.picker];
 | 
			
		||||
          }
 | 
			
		||||
          return value;
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
      // update-end--author:liaozhiyang---date:20240509---for:【QQYUN-9205】一对多(jVxetable组件date)支持年,年月,年度度,年周
 | 
			
		||||
    } as JVxeComponent.EnhancedPartial,
 | 
			
		||||
  });
 | 
			
		||||
</script>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,10 +1,12 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <div class="j-vxe-drag-box">
 | 
			
		||||
    <a-dropdown :trigger="['click']">
 | 
			
		||||
     <span v-if="!isAllowDrag"><span class="not-drag-btn"> <Icon icon="mi:drag" /> </span
 | 
			
		||||
      ></span>
 | 
			
		||||
    <a-dropdown v-else :trigger="['click']" >
 | 
			
		||||
      <span
 | 
			
		||||
        ><span class="drag-btn"> <Icon icon="mi:drag" /> </span
 | 
			
		||||
      ></span>
 | 
			
		||||
      <template #overlay>
 | 
			
		||||
      <template #overlay >
 | 
			
		||||
        <a-menu>
 | 
			
		||||
          <a-menu-item key="0" :disabled="disabledMoveUp" @click="handleRowMoveUp">向上移</a-menu-item>
 | 
			
		||||
          <a-menu-item key="1" :disabled="disabledMoveDown" @click="handleRowMoveDown">向下移</a-menu-item>
 | 
			
		||||
| 
						 | 
				
			
			@ -27,8 +29,22 @@
 | 
			
		|||
    components: { Icon },
 | 
			
		||||
    props: useJVxeCompProps(),
 | 
			
		||||
    setup(props: JVxeComponent.Props) {
 | 
			
		||||
      const { rowIndex, fullDataLength, trigger } = useJVxeComponent(props);
 | 
			
		||||
 | 
			
		||||
      const { rowIndex, originColumn, fullDataLength, trigger } = useJVxeComponent(props);
 | 
			
		||||
      // update-begin--author:liaozhiyang---date:20240417---for:【QQYUN-8785】online表单列位置的id未做限制,拖动其他列到id列上面,同步数据库时报错
 | 
			
		||||
      const isAllowDrag = computed(() => {
 | 
			
		||||
        const notAllowDrag = originColumn.value.notAllowDrag;
 | 
			
		||||
        if (notAllowDrag.length) {
 | 
			
		||||
          const row = props.params.row;
 | 
			
		||||
          const find = notAllowDrag.find((item: any) => {
 | 
			
		||||
            const { key, value } = item;
 | 
			
		||||
            return row[key] == value;
 | 
			
		||||
          });
 | 
			
		||||
          return !find;
 | 
			
		||||
        } else {
 | 
			
		||||
          return true;
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
      // update-end--author:liaozhiyang---date:20240417---for:【QQYUN-8785】online表单列位置的id未做限制,拖动其他列到id列上面,同步数据库时报错
 | 
			
		||||
      const disabledMoveUp = computed(() => rowIndex.value === 0);
 | 
			
		||||
      const disabledMoveDown = computed(() => rowIndex.value === fullDataLength.value - 1);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -63,6 +79,7 @@
 | 
			
		|||
        handleRowMoveUp,
 | 
			
		||||
        handleRowMoveDown,
 | 
			
		||||
        handleRowInsertDown,
 | 
			
		||||
        isAllowDrag
 | 
			
		||||
      };
 | 
			
		||||
    },
 | 
			
		||||
    // 【组件增强】注释详见:JVxeComponent.Enhanced
 | 
			
		||||
| 
						 | 
				
			
			@ -90,3 +107,11 @@
 | 
			
		|||
    }
 | 
			
		||||
  }
 | 
			
		||||
</style>
 | 
			
		||||
<style scoped>
 | 
			
		||||
  .not-drag-btn {
 | 
			
		||||
    opacity: 0.5;
 | 
			
		||||
     .app-iconify {
 | 
			
		||||
      cursor: not-allowed;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,7 +26,7 @@
 | 
			
		|||
    components: { LoadingOutlined },
 | 
			
		||||
    props: useJVxeCompProps(),
 | 
			
		||||
    setup(props: JVxeComponent.Props) {
 | 
			
		||||
      const { innerValue, cellProps, row, originColumn, handleChangeCommon, handleBlurCommon } = useJVxeComponent(props);
 | 
			
		||||
      const { innerValue, cellProps, row, originColumn, scrolling, handleChangeCommon, handleBlurCommon } = useJVxeComponent(props);
 | 
			
		||||
      const loading = ref(false);
 | 
			
		||||
      // 异步加载的options(用于多级联动)
 | 
			
		||||
      const asyncOptions = ref<any[] | null>(null);
 | 
			
		||||
| 
						 | 
				
			
			@ -36,7 +36,7 @@
 | 
			
		|||
          ...cellProps.value,
 | 
			
		||||
          allowClear: true,
 | 
			
		||||
          autofocus: true,
 | 
			
		||||
          defaultOpen: true,
 | 
			
		||||
          defaultOpen: !scrolling.value,
 | 
			
		||||
          style: { width: '100%' },
 | 
			
		||||
          filterOption: handleSelectFilterOption,
 | 
			
		||||
          onBlur: handleBlur,
 | 
			
		||||
| 
						 | 
				
			
			@ -136,6 +136,9 @@
 | 
			
		|||
      
 | 
			
		||||
        let { allowSearch, allowInput } = originColumn.value;
 | 
			
		||||
        if (allowSearch === true || allowInput === true) {
 | 
			
		||||
          // update-begin--author:liaozhiyang---date:20240321---for:【QQYUN-5806】js增强改变下拉搜索options (防止option.title为null报错)
 | 
			
		||||
          if (option.title == null) return false;
 | 
			
		||||
          // update-begin--author:liaozhiyang---date:20240321---for:【QQYUN-5806】js增强改变下拉搜索options (防止option.title为null报错)
 | 
			
		||||
          // update-begin--author:liaozhiyang---date:20230904---for:【issues/5305】JVxeTypes.select 无法按照预期进行搜索
 | 
			
		||||
          return option.title.toLowerCase().indexOf(input.toLowerCase()) >= 0;
 | 
			
		||||
          // update-begin--author:liaozhiyang---date:20230904---for:【issues/5305】JVxeTypes.select 无法按照预期进行搜索
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue