Compare commits
44 Commits
v3.6.0
...
v3.6.1last
Author | SHA1 | Date | |
---|---|---|---|
![]() |
38e6584e10 | ||
![]() |
318b834857 | ||
![]() |
81579acf0e | ||
![]() |
26ab89b700 | ||
![]() |
55a09678cd | ||
![]() |
dcd923aae4 | ||
![]() |
3c0f15bb6e | ||
![]() |
348a8a3f6a | ||
![]() |
2ee3d66d7e | ||
![]() |
06a13a9acd | ||
![]() |
08f4c122db | ||
![]() |
40fe2ed0fe | ||
![]() |
c2bb591582 | ||
![]() |
37521946f8 | ||
![]() |
4c61aa136a | ||
![]() |
a67f074690 | ||
![]() |
75bf9784e4 | ||
![]() |
29c1145a29 | ||
![]() |
d0ff2225c7 | ||
![]() |
7f6f07f72c | ||
![]() |
0e45068cbd | ||
![]() |
e70455df94 | ||
![]() |
80b9f0cfee | ||
![]() |
ca2c6aa5da | ||
![]() |
4856c436d9 | ||
![]() |
256594e384 | ||
![]() |
5eeab9c448 | ||
![]() |
9c77d526e4 | ||
![]() |
f4b902011e | ||
![]() |
ab28f8fd87 | ||
![]() |
98dc3b87e1 | ||
![]() |
9b87a03522 | ||
![]() |
bffd067985 | ||
![]() |
df17b4b6f1 | ||
![]() |
0b1c464e2c | ||
![]() |
734068c685 | ||
![]() |
ce1aa4264f | ||
![]() |
38d0e5602b | ||
![]() |
ff3634ffd8 | ||
![]() |
1cc2d16bfd | ||
![]() |
7741ad0de2 | ||
![]() |
afecda73a7 | ||
![]() |
44f51ab6cb | ||
![]() |
a3cba83533 |
@@ -1,11 +1,11 @@
|
|||||||
JEECG BOOT 低代码开发平台(Vue3前端)
|
JEECG BOOT 低代码开发平台(Vue3前端)
|
||||||
===============
|
===============
|
||||||
当前最新版本: 3.6.0(发布时间:2023-10-23)
|
当前最新版本: 3.6.1(发布时间:2023-12-11)
|
||||||
|
|
||||||
[](https://github.com/zhangdaiscott/jeecg-boot/blob/master/LICENSE)
|
[](https://github.com/zhangdaiscott/jeecg-boot/blob/master/LICENSE)
|
||||||
[](http://jeecg.com/aboutusIndex)
|
[](http://jeecg.com/aboutusIndex)
|
||||||
[](https://jeecg.blog.csdn.net)
|
[](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)
|
||||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||||
|
|
||||||
@@ -47,7 +47,7 @@ JeecgBoot-Vue3采用 Vue3.0、Vite、 Ant-Design-Vue3、TypeScript 等新技术
|
|||||||
- 官方文档:[http://help.jeecg.com](http://help.jeecg.com)
|
- 官方文档:[http://help.jeecg.com](http://help.jeecg.com)
|
||||||
- 官方网站: [http://www.jeecg.com](http://www.jeecg.com)
|
- 官方网站: [http://www.jeecg.com](http://www.jeecg.com)
|
||||||
- 快速入门:[快速入门](http://jeecg.com/doc/quickstart) | [常见问题](http://help.jeecg.com/qa.html) | [视频教程](https://www.bilibili.com/video/BV1V34y187Y9 "入门视频") | [ 代码生成](http://help.jeecg.com/vue3/codegen/online.html)
|
- 快速入门:[快速入门](http://jeecg.com/doc/quickstart) | [常见问题](http://help.jeecg.com/qa.html) | [视频教程](https://www.bilibili.com/video/BV1V34y187Y9 "入门视频") | [ 代码生成](http://help.jeecg.com/vue3/codegen/online.html)
|
||||||
- QQ交流群:⑦791696430、683903138
|
- QQ交流群:⑧825232878、⑦791696430(满)、683903138(满)
|
||||||
- 在线演示 : [Vue3演示](http://boot3.jeecg.com) | [APP演示](http://jeecg.com/appIndex)| [敲敲云零代码](https://www.qiaoqiaoyun.com)
|
- 在线演示 : [Vue3演示](http://boot3.jeecg.com) | [APP演示](http://jeecg.com/appIndex)| [敲敲云零代码](https://www.qiaoqiaoyun.com)
|
||||||
> 演示系统的登录账号密码,请点击 [获取账号密码](http://jeecg.com/doc/demo) 获取
|
> 演示系统的登录账号密码,请点击 [获取账号密码](http://jeecg.com/doc/demo) 获取
|
||||||
|
|
||||||
|
10
package.json
10
package.json
@@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "jeecgboot-vue3",
|
"name": "jeecgboot-vue3",
|
||||||
"version": "3.6.0",
|
"version": "3.6.1",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "jeecg",
|
"name": "北京国炬信息技术有限公司",
|
||||||
"email": "jeecgos@163.com",
|
"email": "jeecgos@163.com",
|
||||||
"url": "https://github.com/jeecgboot/jeecgboot-vue3"
|
"url": "http://guojusoft.com"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"pinstall": "pnpm install",
|
"pinstall": "pnpm install",
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
"husky:install": "husky install"
|
"husky:install": "husky install"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jeecg/online": "3.5.3-vite4",
|
"@jeecg/online": "3.6.0-beta",
|
||||||
"@qiaoqiaoyun/drag-free": "^1.1.4",
|
"@qiaoqiaoyun/drag-free": "^1.1.4",
|
||||||
"@iconify/iconify": "^3.1.1",
|
"@iconify/iconify": "^3.1.1",
|
||||||
"@ant-design/colors": "^7.0.0",
|
"@ant-design/colors": "^7.0.0",
|
||||||
@@ -166,7 +166,7 @@
|
|||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/jeecgboot/jeecgboot-vue3/issues"
|
"url": "https://github.com/jeecgboot/jeecgboot-vue3/issues"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/jeecgboot/jeecgboot-vue3",
|
"homepage": "https://www.jeecg.com",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^12 || >=14"
|
"node": "^12 || >=14"
|
||||||
}
|
}
|
||||||
|
2176
pnpm-lock.yaml
generated
2176
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -12,7 +12,9 @@
|
|||||||
:disabled="item.disabled"
|
:disabled="item.disabled"
|
||||||
:class="[{ 'is-pop-confirm': item.popConfirm }, item.class ?? []]"
|
:class="[{ 'is-pop-confirm': item.popConfirm }, item.class ?? []]"
|
||||||
>
|
>
|
||||||
<a-popconfirm v-if="popconfirm && item.popConfirm" v-bind="getPopConfirmAttrs(item.popConfirm)">
|
<!-- update-begin--author:liaozhiyang---date:20231110---for:【issues/839】BasicTable表格的更多操作按钮禁用还能点击弹出气泡框 -->
|
||||||
|
<a-popconfirm :disabled="item.disabled" v-if="popconfirm && item.popConfirm" v-bind="getPopConfirmAttrs(item.popConfirm)">
|
||||||
|
<!-- update-end--author:liaozhiyang---date:20231110---for:【issues/839】BasicTable表格的更多操作按钮禁用还能点击弹出气泡框 -->
|
||||||
<template #icon v-if="item.popConfirm.icon">
|
<template #icon v-if="item.popConfirm.icon">
|
||||||
<Icon v-if="item.iconColor" :icon="item.popConfirm.icon" :color="item.iconColor" />
|
<Icon v-if="item.iconColor" :icon="item.popConfirm.icon" :color="item.iconColor" />
|
||||||
<Icon v-else :icon="item.popConfirm.icon" />
|
<Icon v-else :icon="item.popConfirm.icon" />
|
||||||
@@ -41,7 +43,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, PropType } from 'vue';
|
import { computed, PropType, ref } from 'vue';
|
||||||
import type { DropMenu } from './typing';
|
import type { DropMenu } from './typing';
|
||||||
import { Dropdown, Menu, Popconfirm } from 'ant-design-vue';
|
import { Dropdown, Menu, Popconfirm } from 'ant-design-vue';
|
||||||
import { Icon } from '/@/components/Icon';
|
import { Icon } from '/@/components/Icon';
|
||||||
|
@@ -113,6 +113,10 @@
|
|||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true }
|
||||||
);
|
);
|
||||||
|
//监听数值修改,查询数据
|
||||||
|
watchEffect(() => {
|
||||||
|
props.value && handleFetch();
|
||||||
|
});
|
||||||
|
|
||||||
async function fetch() {
|
async function fetch() {
|
||||||
const api = props.api;
|
const api = props.api;
|
||||||
|
@@ -94,6 +94,9 @@
|
|||||||
// 启用代码折叠相关功能:结束
|
// 启用代码折叠相关功能:结束
|
||||||
// 光标行高亮
|
// 光标行高亮
|
||||||
styleActiveLine: true,
|
styleActiveLine: true,
|
||||||
|
// 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
|
||||||
//代码格式化
|
//代码格式化
|
||||||
extraKeys: {
|
extraKeys: {
|
||||||
Tab: function autoFormat(editor) {
|
Tab: function autoFormat(editor) {
|
||||||
|
@@ -31,7 +31,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, PropType, ref, reactive, watchEffect, computed, unref, watch, onMounted } from 'vue';
|
import { defineComponent, PropType, ref, reactive, watchEffect, computed, unref, watch, onMounted, nextTick } from 'vue';
|
||||||
import { LoadingOutlined, UploadOutlined } from '@ant-design/icons-vue';
|
import { LoadingOutlined, UploadOutlined } from '@ant-design/icons-vue';
|
||||||
import { useRuleFormItem } from '/@/hooks/component/useFormItem';
|
import { useRuleFormItem } from '/@/hooks/component/useFormItem';
|
||||||
import { propTypes } from '/@/utils/propTypes';
|
import { propTypes } from '/@/utils/propTypes';
|
||||||
@@ -175,28 +175,36 @@
|
|||||||
*/
|
*/
|
||||||
function handleChange({ file, fileList, event }) {
|
function handleChange({ file, fileList, event }) {
|
||||||
initTag.value = false;
|
initTag.value = false;
|
||||||
uploadFileList.value = fileList;
|
// update-begin--author:liaozhiyang---date:20231116---for:【issues/846】上传多个列表只显示一个
|
||||||
|
// uploadFileList.value = fileList;
|
||||||
if (file.status === 'error') {
|
if (file.status === 'error') {
|
||||||
createMessage.error(`${file.name} 上传失败.`);
|
createMessage.error(`${file.name} 上传失败.`);
|
||||||
}
|
}
|
||||||
let fileUrls = [];
|
let fileUrls = [];
|
||||||
//上传完成
|
let noUploadingFileCount = 0;
|
||||||
if (file.status != 'uploading') {
|
if (file.status != 'uploading') {
|
||||||
fileList.forEach((file) => {
|
fileList.forEach((file) => {
|
||||||
if (file.status === 'done') {
|
if (file.status === 'done') {
|
||||||
//update-begin---author:wangshuai ---date:20221121 for:[issues/248]原生表单内使用图片组件,关闭弹窗图片组件值不会被清空------------
|
|
||||||
initTag.value = true;
|
|
||||||
//update-end---author:wangshuai ---date:20221121 for:[issues/248]原生表单内使用图片组件,关闭弹窗图片组件值不会被清空------------
|
|
||||||
fileUrls.push(file.response.message);
|
fileUrls.push(file.response.message);
|
||||||
}
|
}
|
||||||
|
if (file.status != 'uploading') {
|
||||||
|
noUploadingFileCount++;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
if (file.status === 'removed') {
|
if (file.status === 'removed') {
|
||||||
handleDelete(file);
|
handleDelete(file);
|
||||||
}
|
}
|
||||||
|
if (noUploadingFileCount == fileList.length) {
|
||||||
|
state.value = fileUrls.join(',');
|
||||||
|
emit('update:value', fileUrls.join(','));
|
||||||
|
// update-begin---author:wangshuai ---date:20221121 for:[issues/248]原生表单内使用图片组件,关闭弹窗图片组件值不会被清空------------
|
||||||
|
nextTick(() => {
|
||||||
|
initTag.value = true;
|
||||||
|
});
|
||||||
|
// update-end---author:wangshuai ---date:20221121 for:[issues/248]原生表单内使用图片组件,关闭弹窗图片组件值不会被清空------------
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// emitData.value = fileUrls.join(',');
|
// update-end--author:liaozhiyang---date:20231116---for:【issues/846】上传多个列表只显示一个
|
||||||
state.value = fileUrls.join(',');
|
|
||||||
emit('update:value', fileUrls.join(','));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -3,10 +3,11 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, PropType, ref, watchEffect, unref, watch } from 'vue';
|
import { defineComponent, PropType, ref, watchEffect, unref, watch, computed } from 'vue';
|
||||||
import { useAttrs } from '/@/hooks/core/useAttrs';
|
import { useAttrs } from '/@/hooks/core/useAttrs';
|
||||||
import { propTypes } from '/@/utils/propTypes';
|
import { propTypes } from '/@/utils/propTypes';
|
||||||
import { JInputTypeEnum } from '/@/enums/jeecgEnum.ts';
|
import { JInputTypeEnum } from '/@/enums/jeecgEnum.ts';
|
||||||
|
import { omit } from 'lodash-es';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'JInput',
|
name: 'JInput',
|
||||||
@@ -22,8 +23,12 @@
|
|||||||
const attrs = useAttrs();
|
const attrs = useAttrs();
|
||||||
//表单值
|
//表单值
|
||||||
const showText = ref('');
|
const showText = ref('');
|
||||||
|
// update-begin--author:liaozhiyang---date:20231026---for:【issues/803】JIput updateSchema不生效
|
||||||
//绑定属性
|
//绑定属性
|
||||||
const getBindValue = Object.assign({}, unref(props), unref(attrs));
|
const getBindValue = computed(() => {
|
||||||
|
return omit(Object.assign({}, unref(props), unref(attrs)), ['value']);
|
||||||
|
});
|
||||||
|
// update-end--author:liaozhiyang---date:20231026---for:【issues/803】JIput updateSchema不生效
|
||||||
//监听类型变化
|
//监听类型变化
|
||||||
watch(
|
watch(
|
||||||
() => props.type,
|
() => props.type,
|
||||||
|
@@ -83,7 +83,9 @@
|
|||||||
setup(props, { emit, refs }) {
|
setup(props, { emit, refs }) {
|
||||||
const options = ref<any[]>([]);
|
const options = ref<any[]>([]);
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const attrs = useAttrs();
|
// update-begin--author:liaozhiyang---date:20231205---for:【issues/897】JSearchSelect组件添加class/style样式不生效
|
||||||
|
const attrs = useAttrs({'excludeDefaultKeys': false});
|
||||||
|
// update-end--author:liaozhiyang---date:20231205---for:【issues/897】JSearchSelect组件添加class/style样式不生效
|
||||||
const selectedValue = ref([]);
|
const selectedValue = ref([]);
|
||||||
const selectedAsyncValue = ref([]);
|
const selectedAsyncValue = ref([]);
|
||||||
const lastLoad = ref(0);
|
const lastLoad = ref(0);
|
||||||
|
@@ -151,10 +151,12 @@
|
|||||||
watch(
|
watch(
|
||||||
() => props.param,
|
() => props.param,
|
||||||
() => {
|
() => {
|
||||||
if (visible) {
|
// update-begin--author:liaozhiyang---date:20231213---for:【issues/901】JPopup组件配置param参数后异常
|
||||||
|
if (visible.value) {
|
||||||
dynamicParamHandler();
|
dynamicParamHandler();
|
||||||
loadData();
|
loadData();
|
||||||
}
|
}
|
||||||
|
// update-end--author:liaozhiyang---date:20231213---for:【issues/901】JPopup组件配置param参数后异常
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
/**
|
/**
|
||||||
|
@@ -100,6 +100,16 @@
|
|||||||
xl: 10,
|
xl: 10,
|
||||||
xxl: 10,
|
xxl: 10,
|
||||||
},
|
},
|
||||||
|
//update-begin-author:liusq date:2023-10-30 for: [issues/5514]组件页面显示错位
|
||||||
|
actionColOptions: {
|
||||||
|
xs: 24,
|
||||||
|
sm: 8,
|
||||||
|
md: 8,
|
||||||
|
lg: 8,
|
||||||
|
xl: 8,
|
||||||
|
xxl: 8,
|
||||||
|
},
|
||||||
|
//update-end-author:liusq date:2023-10-30 for: [issues/5514]组件页面显示错位
|
||||||
schemas: [
|
schemas: [
|
||||||
{
|
{
|
||||||
label: '职务名称',
|
label: '职务名称',
|
||||||
|
@@ -67,6 +67,16 @@
|
|||||||
xl: 14,
|
xl: 14,
|
||||||
xxl: 14,
|
xxl: 14,
|
||||||
},
|
},
|
||||||
|
//update-begin-author:liusq date:2023-10-30 for: [issues/5514]组件页面显示错位
|
||||||
|
actionColOptions: {
|
||||||
|
xs: 24,
|
||||||
|
sm: 8,
|
||||||
|
md: 8,
|
||||||
|
lg: 8,
|
||||||
|
xl: 8,
|
||||||
|
xxl: 8,
|
||||||
|
},
|
||||||
|
//update-end-author:liusq date:2023-10-30 for: [issues/5514]组件页面显示错位
|
||||||
schemas: [
|
schemas: [
|
||||||
{
|
{
|
||||||
label: '角色名称',
|
label: '角色名称',
|
||||||
|
@@ -110,6 +110,16 @@
|
|||||||
xl: 6,
|
xl: 6,
|
||||||
xxl: 10,
|
xxl: 10,
|
||||||
},
|
},
|
||||||
|
//update-begin-author:liusq date:2023-10-30 for: [issues/5514]组件页面显示错位
|
||||||
|
actionColOptions: {
|
||||||
|
xs: 24,
|
||||||
|
sm: 12,
|
||||||
|
md: 12,
|
||||||
|
lg: 12,
|
||||||
|
xl: 8,
|
||||||
|
xxl: 8,
|
||||||
|
},
|
||||||
|
//update-end-author:liusq date:2023-10-30 for: [issues/5514]组件页面显示错位
|
||||||
schemas: [
|
schemas: [
|
||||||
{
|
{
|
||||||
label: '账号',
|
label: '账号',
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
import { inject, reactive, ref, watch, unref, Ref } from 'vue';
|
import { inject, reactive, ref, watch, unref, Ref } from 'vue';
|
||||||
import { useMessage } from '/@/hooks/web/useMessage';
|
import { useMessage } from '/@/hooks/web/useMessage';
|
||||||
|
import { isEmpty } from '@/utils/is';
|
||||||
|
|
||||||
export function useSelectBiz(getList, props) {
|
export function useSelectBiz(getList, props) {
|
||||||
//接收下拉框选项
|
//接收下拉框选项
|
||||||
@@ -25,7 +26,10 @@ export function useSelectBiz(getList, props) {
|
|||||||
watch(
|
watch(
|
||||||
selectValues,
|
selectValues,
|
||||||
() => {
|
() => {
|
||||||
if (selectValues['change'] == false) {
|
//update-begin-author:liusq---date:2023-10-19--for: [issues/788]判断有设置数值才去加载
|
||||||
|
//if (selectValues['change'] == false && !isEmpty(selectValues['value'])) {
|
||||||
|
if (selectValues['change'] == false && !isEmpty(selectValues['value'])) {
|
||||||
|
//update-end-author:liusq---date:2023-10-19--for: [issues/788]判断有设置数值才去加载
|
||||||
//update-begin---author:wangshuai ---date:20220412 for:[VUEN-672]发文草稿箱编辑时拟稿人显示用户名------------
|
//update-begin---author:wangshuai ---date:20220412 for:[VUEN-672]发文草稿箱编辑时拟稿人显示用户名------------
|
||||||
let params = {};
|
let params = {};
|
||||||
params[props.rowKey] = selectValues['value'].join(',');
|
params[props.rowKey] = selectValues['value'].join(',');
|
||||||
|
@@ -1,22 +1,130 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-html="getHtmlData" :class="$props.class" class="markdown-viewer"></div>
|
<!-- <div v-html="getHtmlData" :class="$props.class" class="markdown-viewer markdown-body"></div> -->
|
||||||
|
<!-- update-begin--author:liaozhiyang---date:20231201---for:【issues/872】MarkdownViewer组件无样式 -->
|
||||||
|
<div class="preview" :class="[{ preview_dark: isDarkTheme }]">
|
||||||
|
<div v-html="getHtmlData" :class="$props.class" class="markdown-viewer vditor-reset"></div>
|
||||||
|
</div>
|
||||||
|
<!-- update-begin--author:liaozhiyang---date:20231201---for:【issues/872】MarkdownViewer组件无样式 -->
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed } from 'vue';
|
import { computed, watch, ref } from 'vue';
|
||||||
import showdown from 'showdown';
|
import showdown from 'showdown';
|
||||||
|
import 'vditor/dist/index.css';
|
||||||
|
import { useRootSetting } from '/@/hooks/setting/useRootSetting';
|
||||||
|
import { ThemeEnum } from '/@/enums/appEnum';
|
||||||
|
|
||||||
const converter = new showdown.Converter();
|
const converter = new showdown.Converter();
|
||||||
converter.setOption('tables', true);
|
converter.setOption('tables', true);
|
||||||
|
converter.setOption('emoji', true);
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
value: { type: String },
|
value: { type: String },
|
||||||
class: { type: String },
|
class: { type: String },
|
||||||
});
|
});
|
||||||
const getHtmlData = computed(() => converter.makeHtml(props.value || ''));
|
const getHtmlData = computed(() => converter.makeHtml(props.value || ''));
|
||||||
|
|
||||||
|
// update-begin--author:liaozhiyang---date:20231213---for:【issues/918】MarkdownViewer加上暗黑主题
|
||||||
|
const isDarkTheme = ref(false);
|
||||||
|
const { getDarkMode } = useRootSetting();
|
||||||
|
watch(
|
||||||
|
() => getDarkMode.value,
|
||||||
|
(value) => {
|
||||||
|
isDarkTheme.value = value === ThemeEnum.DARK;
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
|
// update-end--author:liaozhiyang---date:20231213---for:【issues/918】MarkdownViewer加上暗黑主题
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style lang="less" scoped>
|
||||||
.markdown-viewer {
|
.markdown-viewer {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.preview {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.preview_dark {
|
||||||
|
.vditor-reset {
|
||||||
|
color: #d1d5da;
|
||||||
|
}
|
||||||
|
.vditor-reset a,
|
||||||
|
.vditor-ir__link {
|
||||||
|
color: #4285f4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vditor-reset h1,
|
||||||
|
.vditor-reset h2 {
|
||||||
|
padding-bottom: 0.3em;
|
||||||
|
border-bottom: 1px solid #d1d5da;
|
||||||
|
}
|
||||||
|
.vditor-reset hr {
|
||||||
|
background-color: #d1d5da;
|
||||||
|
}
|
||||||
|
.vditor-reset blockquote {
|
||||||
|
padding: 0 1em;
|
||||||
|
color: #b9b9b9;
|
||||||
|
border-left: 0.25em solid #d1d5da;
|
||||||
|
}
|
||||||
|
.vditor-reset iframe {
|
||||||
|
border: 1px solid #141414;
|
||||||
|
}
|
||||||
|
.vditor-reset table tr {
|
||||||
|
background-color: #2f363d;
|
||||||
|
}
|
||||||
|
.vditor-reset table td,
|
||||||
|
.vditor-reset table th {
|
||||||
|
border: 1px solid #dfe2e5;
|
||||||
|
}
|
||||||
|
.vditor-reset table tbody tr:nth-child(2n) {
|
||||||
|
background-color: #24292e;
|
||||||
|
}
|
||||||
|
.vditor-reset code:not(.hljs):not(.highlight-chroma) {
|
||||||
|
background-color: rgba(66, 133, 244, 0.36);
|
||||||
|
}
|
||||||
|
.vditor-reset .language-abc svg,
|
||||||
|
.vditor-reset .language-abc path {
|
||||||
|
fill: currentColor;
|
||||||
|
color: #d1d5da;
|
||||||
|
}
|
||||||
|
.language-graphviz polygon {
|
||||||
|
fill: rgba(66, 133, 244, 0.36);
|
||||||
|
}
|
||||||
|
.vditor-reset kbd {
|
||||||
|
color: #d1d5da;
|
||||||
|
background-color: #2f363d;
|
||||||
|
border: 1px solid #141414;
|
||||||
|
box-shadow: inset 0 -1px 0 #141414;
|
||||||
|
}
|
||||||
|
.vditor-copy svg {
|
||||||
|
color: #b9b9b9;
|
||||||
|
}
|
||||||
|
.vditor-speech {
|
||||||
|
background-color: #1d2125;
|
||||||
|
border: 1px solid #141414;
|
||||||
|
color: #b9b9b9;
|
||||||
|
}
|
||||||
|
.vditor-speech--current,
|
||||||
|
.vditor-speech:hover {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.vditor-linkcard a {
|
||||||
|
background-color: #1d2125;
|
||||||
|
}
|
||||||
|
.vditor-linkcard a:visited .vditor-linkcard__abstract {
|
||||||
|
color: hsla(0, 0%, 72.5%, 0.36);
|
||||||
|
}
|
||||||
|
.vditor-linkcard__title {
|
||||||
|
color: #d1d5da;
|
||||||
|
}
|
||||||
|
.vditor-linkcard__abstract {
|
||||||
|
color: #b9b9b9;
|
||||||
|
}
|
||||||
|
.vditor-linkcard__site {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.vditor-linkcard__image {
|
||||||
|
background-color: hsla(0, 0%, 72.5%, 0.36);
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@@ -42,19 +42,23 @@
|
|||||||
|
|
||||||
function handleChange(e: ChangeEvent) {
|
function handleChange(e: ChangeEvent) {
|
||||||
innerValueRef.value = e.target.value;
|
innerValueRef.value = e.target.value;
|
||||||
|
// update-end--author:liaozhiyang---date:20231122---for:【issues/5579】密码组件第一次输入值规则校验没触发
|
||||||
|
emit('change', e.target.value);
|
||||||
|
// update-end--author:liaozhiyang---date:20231122---for:【issues/5579】密码组件第一次输入值规则校验没触发
|
||||||
}
|
}
|
||||||
|
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
innerValueRef.value = props.value || '';
|
innerValueRef.value = props.value || '';
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(
|
// update-end--author:liaozhiyang---date:20231122---for:【issues/5579】密码组件第一次输入值规则校验没触发
|
||||||
() => unref(innerValueRef),
|
// watch(
|
||||||
(val) => {
|
// () => unref(innerValueRef),
|
||||||
emit('change', val);
|
// (val) => {
|
||||||
}
|
// emit('change', val);
|
||||||
);
|
// }
|
||||||
|
// );
|
||||||
|
// update-end--author:liaozhiyang---date:20231122---for:【issues/5579】密码组件第一次输入值规则校验没触发
|
||||||
return {
|
return {
|
||||||
getPasswordStrength,
|
getPasswordStrength,
|
||||||
handleChange,
|
handleChange,
|
||||||
|
@@ -375,38 +375,6 @@
|
|||||||
|
|
||||||
emit('register', tableAction, formActions);
|
emit('register', tableAction, formActions);
|
||||||
|
|
||||||
// update-begin--author:liaozhiyang---date:20230804---for:【issues/638】表格合计,列表table和合计table滚动联动
|
|
||||||
if (getProps.value.showSummary) {
|
|
||||||
let tableBody;
|
|
||||||
const handleSroll = function () {
|
|
||||||
const scrollLeft = this.scrollLeft;
|
|
||||||
tableBody.forEach((elem) => (elem.scrollLeft = scrollLeft));
|
|
||||||
};
|
|
||||||
onMounted(() => {
|
|
||||||
const unwatch = watch(
|
|
||||||
getDataSourceRef,
|
|
||||||
(newVal) => {
|
|
||||||
if (newVal.length > 0) {
|
|
||||||
setTimeout(() => {
|
|
||||||
unwatch();
|
|
||||||
tableBody = wrapRef.value.querySelectorAll('.ant-table-body');
|
|
||||||
tableBody.forEach((elem) => {
|
|
||||||
elem.addEventListener('scroll', handleSroll, false);
|
|
||||||
});
|
|
||||||
}, 0);
|
|
||||||
console.log("---表格合计滚动---")
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ immediate: true }
|
|
||||||
);
|
|
||||||
});
|
|
||||||
onUnmounted(() => {
|
|
||||||
if (tableBody.length) {
|
|
||||||
tableBody.forEach((elem) => elem.removeEventListener('scroll', handleSroll));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// update-begin--author:liaozhiyang---date:20230804---for:【issues/638】表格合计,列表table和合计table滚动联动
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
tableElRef,
|
tableElRef,
|
||||||
|
@@ -1,10 +1,17 @@
|
|||||||
<!-- 自定义选择列,表头实现部分 -->
|
<!-- 自定义选择列,表头实现部分 -->
|
||||||
<template>
|
<template>
|
||||||
|
<!-- update-begin--author:liaozhiyang---date:20231130---for:【issues/5595】BasicTable组件hideSelectAll: true无法隐藏全选框 -->
|
||||||
<template v-if="isRadio">
|
<template v-if="isRadio">
|
||||||
<!-- radio不存在全选,所以放个空标签 -->
|
<!-- radio不存在全选,所以放个空标签 -->
|
||||||
<span></span>
|
<span></span>
|
||||||
</template>
|
</template>
|
||||||
<a-checkbox :disabled="disabled" v-else :checked="checked" :indeterminate="isHalf" @update:checked="onChange" />
|
<template v-else>
|
||||||
|
<template v-if="hideSelectAll">
|
||||||
|
<span></span>
|
||||||
|
</template>
|
||||||
|
<a-checkbox :disabled="disabled" v-else :checked="checked" :indeterminate="isHalf" @update:checked="onChange" />
|
||||||
|
</template>
|
||||||
|
<!-- update-end--author:liaozhiyang---date:20231130---for:【issues/5595】BasicTable组件hideSelectAll: true无法隐藏全选框 -->
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
@@ -23,6 +30,10 @@
|
|||||||
type: Number,
|
type: Number,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
hideSelectAll: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
// update-begin--author:liaozhiyang---date:20231016---for:【QQYUN-6774】解决checkbox禁用后全选仍能勾选问题
|
// update-begin--author:liaozhiyang---date:20231016---for:【QQYUN-6774】解决checkbox禁用后全选仍能勾选问题
|
||||||
disabled: {
|
disabled: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
|
@@ -67,7 +67,10 @@
|
|||||||
|
|
||||||
const getColumns = computed(() => {
|
const getColumns = computed(() => {
|
||||||
const dataSource = unref(getDataSource);
|
const dataSource = unref(getDataSource);
|
||||||
const columns: BasicColumn[] = cloneDeep(table.getColumns());
|
let columns: BasicColumn[] = cloneDeep(table.getColumns());
|
||||||
|
// update-begin--author:liaozhiyang---date:220230804---for:【issues/638】表格合计,列自定义隐藏或展示时,合计栏会错位
|
||||||
|
columns = columns.filter((item) => !item.defaultHidden);
|
||||||
|
// update-begin--author:liaozhiyang---date:220230804---for:【issues/638】表格合计,列自定义隐藏或展示时,合计栏会错位
|
||||||
const index = columns.findIndex((item) => item.flag === INDEX_COLUMN_FLAG);
|
const index = columns.findIndex((item) => item.flag === INDEX_COLUMN_FLAG);
|
||||||
const hasRowSummary = dataSource.some((item) => Reflect.has(item, SUMMARY_ROW_KEY));
|
const hasRowSummary = dataSource.some((item) => Reflect.has(item, SUMMARY_ROW_KEY));
|
||||||
const hasIndexSummary = dataSource.some((item) => Reflect.has(item, SUMMARY_INDEX_KEY));
|
const hasIndexSummary = dataSource.some((item) => Reflect.has(item, SUMMARY_INDEX_KEY));
|
||||||
|
@@ -289,7 +289,15 @@
|
|||||||
|
|
||||||
// reset columns
|
// reset columns
|
||||||
function reset() {
|
function reset() {
|
||||||
state.checkedList = [...state.defaultCheckList];
|
// state.checkedList = [...state.defaultCheckList];
|
||||||
|
// update-begin--author:liaozhiyang---date:20231103---for:【issues/825】tabel的列设置隐藏列保存后切换路由问题[重置没勾选]
|
||||||
|
state.checkedList = table
|
||||||
|
.getColumns({ ignoreAction: true })
|
||||||
|
.map((item) => {
|
||||||
|
return item.dataIndex || item.title;
|
||||||
|
})
|
||||||
|
.filter(Boolean) as string[];
|
||||||
|
// update-end--author:liaozhiyang---date:20231103---for:【issues/825】tabel的列设置隐藏列保存后切换路由问题[重置没勾选]
|
||||||
state.checkAll = true;
|
state.checkAll = true;
|
||||||
plainOptions.value = unref(cachePlainOptions);
|
plainOptions.value = unref(cachePlainOptions);
|
||||||
plainSortOptions.value = unref(cachePlainOptions);
|
plainSortOptions.value = unref(cachePlainOptions);
|
||||||
|
@@ -277,9 +277,6 @@ export function useColumns(
|
|||||||
columns = columns.filter((item) => item.key !== CUS_SEL_COLUMN_KEY);
|
columns = columns.filter((item) => item.key !== CUS_SEL_COLUMN_KEY);
|
||||||
// update-enb--author:sunjianlei---date:220230630---for:【QQYUN-5571】自封装选择列,解决数据行选择卡顿问题
|
// update-enb--author:sunjianlei---date:220230630---for:【QQYUN-5571】自封装选择列,解决数据行选择卡顿问题
|
||||||
|
|
||||||
// update-begin--author:liaozhiyang---date:220230804---for:【issues/638】表格合计,列自定义隐藏或展示时,合计栏会错位
|
|
||||||
columns = columns.filter((item) => !item.defaultHidden);
|
|
||||||
// update-begin--author:liaozhiyang---date:220230804---for:【issues/638】表格合计,列自定义隐藏或展示时,合计栏会错位
|
|
||||||
if (sort) {
|
if (sort) {
|
||||||
columns = sortFixedColumn(columns);
|
columns = sortFixedColumn(columns);
|
||||||
}
|
}
|
||||||
|
@@ -39,6 +39,9 @@ export function useCustomSelection(
|
|||||||
const selectedKeys = ref<string[]>([]);
|
const selectedKeys = ref<string[]>([]);
|
||||||
// 选择的行
|
// 选择的行
|
||||||
const selectedRows = ref<Recordable[]>([]);
|
const selectedRows = ref<Recordable[]>([]);
|
||||||
|
// 变更的行
|
||||||
|
let changeRows: Recordable[] = [];
|
||||||
|
let allSelected: boolean = false;
|
||||||
|
|
||||||
// 扁平化数据,children数据也会放到一起
|
// 扁平化数据,children数据也会放到一起
|
||||||
const flattedData = computed(() => {
|
const flattedData = computed(() => {
|
||||||
@@ -120,6 +123,7 @@ export function useCustomSelection(
|
|||||||
pageSize: currentPageSize.value,
|
pageSize: currentPageSize.value,
|
||||||
// 【QQYUN-6774】解决checkbox禁用后全选仍能勾选问题
|
// 【QQYUN-6774】解决checkbox禁用后全选仍能勾选问题
|
||||||
disabled: flattedData.value.length == 0,
|
disabled: flattedData.value.length == 0,
|
||||||
|
hideSelectAll: unref(propsRef)?.rowSelection?.hideSelectAll,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -127,8 +131,10 @@ export function useCustomSelection(
|
|||||||
watch(
|
watch(
|
||||||
() => unref(propsRef)?.rowSelection?.selectedRowKeys,
|
() => unref(propsRef)?.rowSelection?.selectedRowKeys,
|
||||||
(val: string[]) => {
|
(val: string[]) => {
|
||||||
if (Array.isArray(val)) {
|
// 解决selectedRowKeys在页面调用处使用ref失效
|
||||||
setSelectedRowKeys(val);
|
const value = unref(val);
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
setSelectedRowKeys(value);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
@@ -184,11 +190,17 @@ export function useCustomSelection(
|
|||||||
|
|
||||||
// 选择全部
|
// 选择全部
|
||||||
function onSelectAll(checked: boolean) {
|
function onSelectAll(checked: boolean) {
|
||||||
|
// update-begin--author:liaozhiyang---date:20231122---for:【issues/5577】BasicTable组件全选和取消全选时不触发onSelectAll事件
|
||||||
|
if (unref(propsRef)?.rowSelection?.onSelectAll) {
|
||||||
|
allSelected = checked;
|
||||||
|
changeRows = getInvertRows(selectedRows.value);
|
||||||
|
}
|
||||||
|
// update-end--author:liaozhiyang---date:20231122---for:【issues/5577】BasicTable组件全选和取消全选时不触发onSelectAll事件
|
||||||
// 取消全选
|
// 取消全选
|
||||||
if (!checked) {
|
if (!checked) {
|
||||||
selectedKeys.value = [];
|
selectedKeys.value = [];
|
||||||
selectedRows.value = [];
|
selectedRows.value = [];
|
||||||
emitChange();
|
emitChange('all');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let modal: Nullable<ReturnType<ModalFunc>> = null;
|
let modal: Nullable<ReturnType<ModalFunc>> = null;
|
||||||
@@ -219,7 +231,7 @@ export function useCustomSelection(
|
|||||||
if (hidden.length > 0) {
|
if (hidden.length > 0) {
|
||||||
return batchesSelectAll(hidden, checked, minSelect);
|
return batchesSelectAll(hidden, checked, minSelect);
|
||||||
} else {
|
} else {
|
||||||
emitChange();
|
emitChange('all');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -250,7 +262,7 @@ export function useCustomSelection(
|
|||||||
call();
|
call();
|
||||||
} else {
|
} else {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
emitChange();
|
emitChange('all');
|
||||||
// update-begin--author:liaozhiyang---date:20230811---for:【QQYUN-5687】批量选择,提示成功后,又来一个提示
|
// update-begin--author:liaozhiyang---date:20230811---for:【QQYUN-5687】批量选择,提示成功后,又来一个提示
|
||||||
setTimeout(() =>resolve(), 0);
|
setTimeout(() =>resolve(), 0);
|
||||||
// update-end--author:liaozhiyang---date:20230811---for:【QQYUN-5687】批量选择,提示成功后,又来一个提示
|
// update-end--author:liaozhiyang---date:20230811---for:【QQYUN-5687】批量选择,提示成功后,又来一个提示
|
||||||
@@ -289,7 +301,7 @@ export function useCustomSelection(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 调用用户自定义的onChange事件
|
// 调用用户自定义的onChange事件
|
||||||
function emitChange() {
|
function emitChange(mode = 'single') {
|
||||||
const { rowSelection } = unref(propsRef);
|
const { rowSelection } = unref(propsRef);
|
||||||
if (rowSelection) {
|
if (rowSelection) {
|
||||||
const { onChange } = rowSelection;
|
const { onChange } = rowSelection;
|
||||||
@@ -303,6 +315,14 @@ export function useCustomSelection(
|
|||||||
keys: getSelectRowKeys(),
|
keys: getSelectRowKeys(),
|
||||||
rows: getSelectRows(),
|
rows: getSelectRows(),
|
||||||
});
|
});
|
||||||
|
// update-begin--author:liaozhiyang---date:20231122---for:【issues/5577】BasicTable组件全选和取消全选时不触发onSelectAll事件
|
||||||
|
if (mode == 'all') {
|
||||||
|
const rowSelection = unref(propsRef)?.rowSelection;
|
||||||
|
if (rowSelection?.onSelectAll) {
|
||||||
|
rowSelection.onSelectAll(allSelected, toRaw(getSelectRows()), toRaw(changeRows));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// update-end--author:liaozhiyang---date:20231122---for:【issues/5577】BasicTable组件全选和取消全选时不触发
|
||||||
}
|
}
|
||||||
|
|
||||||
// 用于判断是否是自定义选择列
|
// 用于判断是否是自定义选择列
|
||||||
@@ -432,6 +452,7 @@ export function useCustomSelection(
|
|||||||
|
|
||||||
// 设置选择的key
|
// 设置选择的key
|
||||||
function setSelectedRowKeys(rowKeys: string[]) {
|
function setSelectedRowKeys(rowKeys: string[]) {
|
||||||
|
const isSomeRowKeys = selectedKeys.value === rowKeys;
|
||||||
selectedKeys.value = rowKeys;
|
selectedKeys.value = rowKeys;
|
||||||
const allSelectedRows = findNodeAll(
|
const allSelectedRows = findNodeAll(
|
||||||
toRaw(unref(flattedData)).concat(toRaw(unref(selectedRows))),
|
toRaw(unref(flattedData)).concat(toRaw(unref(selectedRows))),
|
||||||
@@ -445,16 +466,58 @@ export function useCustomSelection(
|
|||||||
const found = allSelectedRows.find((item) => getRecordKey(item) === key);
|
const found = allSelectedRows.find((item) => getRecordKey(item) === key);
|
||||||
found && trueSelectedRows.push(found);
|
found && trueSelectedRows.push(found);
|
||||||
});
|
});
|
||||||
// update-begin--author:liaozhiyang---date:20230823---for:【QQYUN-6283】点击表格清空,rowSelect里面的selectedRowKeys没置空。
|
// update-begin--author:liaozhiyang---date:20231103---for:【issues/828】解决卡死问题
|
||||||
// update-begin--author:liaozhiyang---date:20230811---for:【issues/657】浏览器卡死问题
|
if (!(isSomeRowKeys && equal(selectedRows.value, trueSelectedRows))) {
|
||||||
if (trueSelectedRows.length || !rowKeys.length) {
|
|
||||||
selectedRows.value = trueSelectedRows;
|
selectedRows.value = trueSelectedRows;
|
||||||
emitChange();
|
emitChange();
|
||||||
}
|
}
|
||||||
// update-end--author:liaozhiyang---date:20230811---for:【issues/657】】浏览器卡死问题
|
// update-end--author:liaozhiyang---date:20231103---for:【issues/828】解决卡死问题
|
||||||
// update-end--author:liaozhiyang---date:20230823---for:【QQYUN-6283】点击表格清空,rowSelect里面的selectedRowKeys没置空。
|
}
|
||||||
|
/**
|
||||||
|
*2023-11-03
|
||||||
|
*廖志阳
|
||||||
|
*检测selectedRows.value和trueSelectedRows是否相等,防止死循环
|
||||||
|
*/
|
||||||
|
function equal(oldVal, newVal) {
|
||||||
|
let oldKeys = [],
|
||||||
|
newKeys = [];
|
||||||
|
if (oldVal.length === newVal.length) {
|
||||||
|
oldKeys = oldVal.map((item) => getRecordKey(item));
|
||||||
|
newKeys = newVal.map((item) => getRecordKey(item));
|
||||||
|
for (let i = 0, len = oldKeys.length; i < len; i++) {
|
||||||
|
const findItem = newKeys.find((item) => item === oldKeys[i]);
|
||||||
|
if (!findItem) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*2023-11-22
|
||||||
|
*廖志阳
|
||||||
|
*根据全选或者反选返回源数据中这次需要变更的数据
|
||||||
|
*/
|
||||||
|
function getInvertRows(rows: any): any {
|
||||||
|
const allRows = findNodeAll(toRaw(unref(flattedData)), () => true, {
|
||||||
|
children: propsRef.value.childrenColumnName ?? 'children',
|
||||||
|
});
|
||||||
|
if (rows.length === 0 || rows.length === allRows.length) {
|
||||||
|
return allRows;
|
||||||
|
} else {
|
||||||
|
const allRowsKey = allRows.map((item) => getRecordKey(item));
|
||||||
|
rows.forEach((rItem) => {
|
||||||
|
const rItemKey = getRecordKey(rItem);
|
||||||
|
const findIndex = allRowsKey.findIndex((item) => rItemKey === item);
|
||||||
|
if (findIndex != -1) {
|
||||||
|
allRowsKey.splice(findIndex, 1);
|
||||||
|
allRows.splice(findIndex, 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return allRows;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSelectRows<T = Recordable>() {
|
function getSelectRows<T = Recordable>() {
|
||||||
return unref(selectedRows) as T[];
|
return unref(selectedRows) as T[];
|
||||||
}
|
}
|
||||||
|
@@ -302,7 +302,9 @@
|
|||||||
watch(
|
watch(
|
||||||
() => props.value,
|
() => props.value,
|
||||||
() => {
|
() => {
|
||||||
state.checkedKeys = toRaw(props.value || []);
|
// update-end--author:liaozhiyang---date:20231122---for:【issues/863】关闭选择部门弹窗,再打开之前勾选的消失了
|
||||||
|
state.checkedKeys = toRaw(props.value || props.checkedKeys || []);
|
||||||
|
// update-end--author:liaozhiyang---date:20231122---for:【issues/863】关闭选择部门弹窗,再打开之前勾选的消失了
|
||||||
},
|
},
|
||||||
{ immediate: true },
|
{ immediate: true },
|
||||||
);
|
);
|
||||||
|
@@ -18,8 +18,13 @@ import JVxeTextareaCell from './components/cells/JVxeTextareaCell.vue';
|
|||||||
// import JVxeDepartSelectCell from './components/cells/JVxeDepartSelectCell.vue'
|
// import JVxeDepartSelectCell from './components/cells/JVxeDepartSelectCell.vue'
|
||||||
// import JVxeUserSelectCell from './components/cells/JVxeUserSelectCell.vue'
|
// import JVxeUserSelectCell from './components/cells/JVxeUserSelectCell.vue'
|
||||||
|
|
||||||
const componentMap = new Map<JVxeTypes | string, JVxeVueComponent>();
|
let componentMap = new Map<JVxeTypes | string, JVxeVueComponent>();
|
||||||
|
// update-begin--author:liaozhiyang---date:20231208---for:【issues/860】生成的一对多代码,热更新之后点击新增卡死[暂时先解决]
|
||||||
|
const JVxeComponents = 'JVxeComponents__';
|
||||||
|
if (import.meta.env.DEV && componentMap.size === 0 && window[JVxeComponents] && window[JVxeComponents].size > 0) {
|
||||||
|
componentMap = window[JVxeComponents];
|
||||||
|
}
|
||||||
|
// update-end--author:liaozhiyang---date:20231027---for:【issues/860】生成的一对多代码,热更新之后点击新增卡死[暂时先解决]
|
||||||
/** span 组件结尾 */
|
/** span 组件结尾 */
|
||||||
export const spanEnds: string = ':span';
|
export const spanEnds: string = ':span';
|
||||||
|
|
||||||
@@ -50,11 +55,17 @@ export function addComponent(type: JVxeTypes, component: JVxeVueComponent, spanC
|
|||||||
if (spanComponent) {
|
if (spanComponent) {
|
||||||
componentMap.set(type + spanEnds, spanComponent);
|
componentMap.set(type + spanEnds, spanComponent);
|
||||||
}
|
}
|
||||||
|
// update-begin--author:liaozhiyang---date:20231208---for:【issues/860】生成的一对多代码,热更新之后点击新增卡死[暂时先解决]
|
||||||
|
import.meta.env.DEV && (window[JVxeComponents] = componentMap);
|
||||||
|
// update-end--author:liaozhiyang---date:20231208---for:【issues/860】生成的一对多代码,热更新之后点击新增卡死[暂时先解决]
|
||||||
}
|
}
|
||||||
|
|
||||||
export function deleteComponent(type: JVxeTypes) {
|
export function deleteComponent(type: JVxeTypes) {
|
||||||
componentMap.delete(type);
|
componentMap.delete(type);
|
||||||
componentMap.delete(type + spanEnds);
|
componentMap.delete(type + spanEnds);
|
||||||
|
// update-begin--author:liaozhiyang---date:20231208---for:【issues/860】生成的一对多代码,热更新之后点击新增卡死[暂时先解决]
|
||||||
|
import.meta.env.DEV && (window[JVxeComponents] = componentMap);
|
||||||
|
// update-end--author:liaozhiyang---date:20231208---for:【issues/860】生成的一对多代码,热更新之后点击新增卡死[暂时先解决]
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 定义内置自定义组件 */
|
/** 定义内置自定义组件 */
|
||||||
|
@@ -639,13 +639,45 @@ export function useMethods(props: JVxeTableProps, { emit }, data: JVxeDataProps,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** 删除一行或多行数据 */
|
/** 删除一行或多行数据 */
|
||||||
async function removeRows(rows) {
|
async function removeRows(rows, asyncRemove = false) {
|
||||||
|
// update-begin--author:liaozhiyang---date:20231123---for:vxe-table removeRows方法加上异步删除
|
||||||
const xTable = getXTable();
|
const xTable = getXTable();
|
||||||
const res = await xTable.remove(rows);
|
const removeEvent: any = { deleteRows: rows, $table: xTable };
|
||||||
let removeEvent: any = { deleteRows: rows, $table: xTable };
|
if (asyncRemove) {
|
||||||
trigger('removed', removeEvent);
|
const selectedRows = Array.isArray(rows) ? rows : [rows];
|
||||||
await recalcSortNumber();
|
const deleteOldRows = filterNewRows(selectedRows);
|
||||||
return res;
|
if (deleteOldRows.length) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
// 确认删除,只有调用这个方法才会真删除
|
||||||
|
removeEvent.confirmRemove = async () => {
|
||||||
|
const insertRecords = xTable.getInsertRecords();
|
||||||
|
selectedRows.forEach((item) => {
|
||||||
|
// 删除新添加的数据id
|
||||||
|
if (insertRecords.includes(item)) {
|
||||||
|
delete item.id;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const res = await xTable.remove(rows);
|
||||||
|
await recalcSortNumber();
|
||||||
|
resolve(res);
|
||||||
|
};
|
||||||
|
trigger('removed', removeEvent);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 全新的行立马删除,不等待。
|
||||||
|
const res = await xTable.remove(rows);
|
||||||
|
removeEvent.confirmRemove = () => {};
|
||||||
|
trigger('removed', removeEvent);
|
||||||
|
await recalcSortNumber();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const res = await xTable.remove(rows);
|
||||||
|
trigger('removed', removeEvent);
|
||||||
|
await recalcSortNumber();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
// update-end--author:liaozhiyang---date:20231123---for:vxe-table removeRows方法加上异步删除
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 根据id删除一行或多行 */
|
/** 根据id删除一行或多行 */
|
||||||
@@ -781,7 +813,6 @@ export function useMethods(props: JVxeTableProps, { emit }, data: JVxeDataProps,
|
|||||||
emit(name, event);
|
emit(name, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取选中的行-和 getSelectionData 区别在于对于新增的行也会返回ID
|
* 获取选中的行-和 getSelectionData 区别在于对于新增的行也会返回ID
|
||||||
* 用于onlinePopForm
|
* 用于onlinePopForm
|
||||||
|
@@ -20,21 +20,34 @@ export function useToolbar(props: JVxeTableProps, data: JVxeDataProps, methods:
|
|||||||
// 保存事件
|
// 保存事件
|
||||||
onSave: () => methods.trigger('save'),
|
onSave: () => methods.trigger('save'),
|
||||||
onRemove() {
|
onRemove() {
|
||||||
let $table = methods.getXTable();
|
const $table = methods.getXTable();
|
||||||
let deleteRows = methods.filterNewRows(data.selectedRows.value);
|
// update-begin--author:liaozhiyang---date:20231018---for:【QQYUN-6805】修复asyncRemove字段不生效
|
||||||
// 触发删除事件
|
// 触发删除事件
|
||||||
if (deleteRows.length > 0) {
|
if (data.selectedRows.value.length > 0) {
|
||||||
let removeEvent: any = { deleteRows, $table};
|
const deleteOldRows = methods.filterNewRows(data.selectedRows.value);
|
||||||
if (props.asyncRemove) {
|
const removeEvent: any = { deleteRows: data.selectedRows.value, $table };
|
||||||
|
const insertRecords = $table.getInsertRecords();
|
||||||
|
if (props.asyncRemove && deleteOldRows.length) {
|
||||||
|
data.selectedRows.value.forEach((item) => {
|
||||||
|
// 删除新添加的数据id
|
||||||
|
if (insertRecords.includes(item)) {
|
||||||
|
delete item.id;
|
||||||
|
}
|
||||||
|
});
|
||||||
// 确认删除,只有调用这个方法才会真删除
|
// 确认删除,只有调用这个方法才会真删除
|
||||||
removeEvent.confirmRemove = () => methods.removeSelection();
|
removeEvent.confirmRemove = () => methods.removeSelection();
|
||||||
} else {
|
} else {
|
||||||
|
if (props.asyncRemove) {
|
||||||
|
// asyncRemove删除的只有新增的数据时,防止调用confirmRemove报错
|
||||||
|
removeEvent.confirmRemove = () => {};
|
||||||
|
}
|
||||||
methods.removeSelection();
|
methods.removeSelection();
|
||||||
}
|
}
|
||||||
methods.trigger('removed', removeEvent);
|
methods.trigger('removed', removeEvent);
|
||||||
} else {
|
} else {
|
||||||
methods.removeSelection();
|
methods.removeSelection();
|
||||||
}
|
}
|
||||||
|
// update-end--author:liaozhiyang---date:20231018---for:【QQYUN-6805】修复asyncRemove字段不生效
|
||||||
},
|
},
|
||||||
// 清除选择事件
|
// 清除选择事件
|
||||||
onClearSelection: () => methods.clearSelection(),
|
onClearSelection: () => methods.clearSelection(),
|
||||||
|
@@ -131,8 +131,7 @@
|
|||||||
<template #label>
|
<template #label>
|
||||||
<span :title="item.label" class="label-text">{{ item.label }}</span>
|
<span :title="item.label" class="label-text">{{ item.label }}</span>
|
||||||
</template>
|
</template>
|
||||||
<JOnlineSearchSelect v-model:value="queryParam[item.field]" :placeholder="'请选择' + item.label" :sql="item.sql">
|
<JOnlineSearchSelect v-model:value="queryParam[item.field]" :placeholder="'请选择'+item.label" :fieldId="item.fieldId"/>
|
||||||
</JOnlineSearchSelect>
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
|
||||||
<a-form-item v-else-if="item.view === CompTypeEnum.SelUser" :labelCol="labelCol" :class="'jeecg-online-search'">
|
<a-form-item v-else-if="item.view === CompTypeEnum.SelUser" :labelCol="labelCol" :class="'jeecg-online-search'">
|
||||||
|
@@ -18,7 +18,7 @@ export enum CompTypeEnum {
|
|||||||
CatTree = 'cat_tree',
|
CatTree = 'cat_tree',
|
||||||
//下拉搜索
|
//下拉搜索
|
||||||
SelSearch = 'search',
|
SelSearch = 'search',
|
||||||
//用户现在框
|
//用户选择框
|
||||||
SelUser = 'sel_user',
|
SelUser = 'sel_user',
|
||||||
//复选框
|
//复选框
|
||||||
Checkbox = 'checkbox',
|
Checkbox = 'checkbox',
|
||||||
|
@@ -9,7 +9,7 @@ export enum ResultEnum {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description: request method
|
* @description: Request method
|
||||||
*/
|
*/
|
||||||
export enum RequestEnum {
|
export enum RequestEnum {
|
||||||
GET = 'GET',
|
GET = 'GET',
|
||||||
@@ -19,7 +19,7 @@ export enum RequestEnum {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description: contentTyp
|
* @description: Content type
|
||||||
*/
|
*/
|
||||||
export enum ContentTypeEnum {
|
export enum ContentTypeEnum {
|
||||||
// json
|
// json
|
||||||
@@ -32,7 +32,7 @@ export enum ContentTypeEnum {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 请求header
|
* 请求header
|
||||||
* @description: contentTyp
|
* @description: Request header
|
||||||
*/
|
*/
|
||||||
export enum ConfigEnum {
|
export enum ConfigEnum {
|
||||||
// TOKEN
|
// TOKEN
|
||||||
|
@@ -1,10 +1,14 @@
|
|||||||
import { nextTick, onMounted, onActivated } from 'vue';
|
import { nextTick, onMounted, onActivated } from 'vue';
|
||||||
|
|
||||||
export function onMountedOrActivated(hook: Fn) {
|
type HookArgs = {
|
||||||
|
type: 'mounted' | 'activated';
|
||||||
|
}
|
||||||
|
|
||||||
|
export function onMountedOrActivated(hook: Fn<HookArgs, any>) {
|
||||||
let mounted: boolean;
|
let mounted: boolean;
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
hook();
|
hook({type: 'mounted'});
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
mounted = true;
|
mounted = true;
|
||||||
});
|
});
|
||||||
@@ -12,7 +16,7 @@ export function onMountedOrActivated(hook: Fn) {
|
|||||||
|
|
||||||
onActivated(() => {
|
onActivated(() => {
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
hook();
|
hook({type: 'activated'});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -7,6 +7,7 @@ import { unref } from 'vue';
|
|||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import { REDIRECT_NAME } from '/@/router/constant';
|
import { REDIRECT_NAME } from '/@/router/constant';
|
||||||
import { useUserStore } from '/@/store/modules/user';
|
import { useUserStore } from '/@/store/modules/user';
|
||||||
|
import { useMultipleTabStore } from '/@/store/modules/multipleTab';
|
||||||
|
|
||||||
export type RouteLocationRawEx = Omit<RouteLocationRaw, 'path'> & { path: PageEnum };
|
export type RouteLocationRawEx = Omit<RouteLocationRaw, 'path'> & { path: PageEnum };
|
||||||
|
|
||||||
@@ -51,40 +52,27 @@ export const useRedo = (_router?: Router) => {
|
|||||||
resolve(false);
|
resolve(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// update-begin--author:liaozhiyang---date:20231123---for:【QQYUN-7099】动态路由匹配右键重新加载404
|
||||||
|
const tabStore = useMultipleTabStore();
|
||||||
if (name && Object.keys(params).length > 0) {
|
if (name && Object.keys(params).length > 0) {
|
||||||
//update-begin-author:taoyan date:2022-10-19 for: VUEN-2356 【vue3】online表单、表单设计器 功能测试 右键刷新时 404
|
tabStore.setRedirectPageParam({
|
||||||
if(isDynamicRoute(params, name)){
|
redirect_type: 'name',
|
||||||
params['_redirect_type'] = 'path';
|
name: String(name),
|
||||||
params['path'] = fullPath;
|
params,
|
||||||
}else{
|
query,
|
||||||
params['_redirect_type'] = 'name';
|
});
|
||||||
params['path'] = String(name);
|
params['path'] = String(name);
|
||||||
}
|
|
||||||
//update-end-author:taoyan date:2022-10-19 for: VUEN-2356 【vue3】online表单、表单设计器 功能测试 右键刷新时 404
|
|
||||||
} else {
|
} else {
|
||||||
params['_redirect_type'] = 'path';
|
tabStore.setRedirectPageParam({
|
||||||
|
redirect_type: 'path',
|
||||||
|
path: fullPath,
|
||||||
|
query,
|
||||||
|
});
|
||||||
params['path'] = fullPath;
|
params['path'] = fullPath;
|
||||||
}
|
}
|
||||||
|
// update-end--author:liaozhiyang---date:20231123---for:【QQYUN-7099】动态路由匹配右键重新加载404
|
||||||
push({ name: REDIRECT_NAME, params, query }).then(() => resolve(true));
|
push({ name: REDIRECT_NAME, params, query }).then(() => resolve(true));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return redo;
|
return redo;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断是不是动态路由的跳转
|
|
||||||
* @param params
|
|
||||||
* @param name
|
|
||||||
*/
|
|
||||||
function isDynamicRoute(params, name){
|
|
||||||
let arr = Object.keys(params);
|
|
||||||
let flag = false;
|
|
||||||
for(let i=0;i<arr.length;i++){
|
|
||||||
let key = '@'+arr[i];
|
|
||||||
if((name as string).indexOf(key)>0){
|
|
||||||
flag = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return flag;
|
|
||||||
}
|
|
||||||
|
@@ -4,8 +4,8 @@ import { useTitle as usePageTitle } from '@vueuse/core';
|
|||||||
import { useGlobSetting } from '/@/hooks/setting';
|
import { useGlobSetting } from '/@/hooks/setting';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import { useLocaleStore } from '/@/store/modules/locale';
|
import { useLocaleStore } from '/@/store/modules/locale';
|
||||||
|
|
||||||
import { REDIRECT_NAME } from '/@/router/constant';
|
import { REDIRECT_NAME } from '/@/router/constant';
|
||||||
|
import { getMenus } from '/@/router/menus';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Listening to page changes and dynamically changing site titles
|
* Listening to page changes and dynamically changing site titles
|
||||||
@@ -26,10 +26,43 @@ export function useTitle() {
|
|||||||
if (route.name === REDIRECT_NAME) {
|
if (route.name === REDIRECT_NAME) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// update-begin--author:liaozhiyang---date:20231110---for:【QQYUN-6938】online菜单名字和页面title不一致
|
||||||
const tTitle = t(route?.meta?.title as string);
|
if (route.params && Object.keys(route.params).length) {
|
||||||
pageTitle.value = tTitle ? ` ${tTitle} - ${title} ` : `${title}`;
|
getMenus().then((menus) => {
|
||||||
|
const getTitle = getMatchingRouterName(menus, route.fullPath);
|
||||||
|
let tTitle = '';
|
||||||
|
if (getTitle) {
|
||||||
|
tTitle = t(getTitle);
|
||||||
|
} else {
|
||||||
|
tTitle = t(route?.meta?.title as string);
|
||||||
|
};
|
||||||
|
pageTitle.value = tTitle ? ` ${tTitle} - ${title} ` : `${title}`;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const tTitle = t(route?.meta?.title as string);
|
||||||
|
pageTitle.value = tTitle ? ` ${tTitle} - ${title} ` : `${title}`;
|
||||||
|
}
|
||||||
|
// update-end--author:liaozhiyang---date:20231110---for:【QQYUN-6938】online菜单名字和页面title不一致
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
2023-11-09
|
||||||
|
liaozhiyang
|
||||||
|
获取路由匹配模式的真实页面名字
|
||||||
|
*/
|
||||||
|
function 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 '';
|
||||||
|
}
|
||||||
|
@@ -14,11 +14,21 @@ import { MULTIPLE_TABS_KEY } from '/@/enums/cacheEnum';
|
|||||||
|
|
||||||
import projectSetting from '/@/settings/projectSetting';
|
import projectSetting from '/@/settings/projectSetting';
|
||||||
import { useUserStore } from '/@/store/modules/user';
|
import { useUserStore } from '/@/store/modules/user';
|
||||||
|
import type { LocationQueryRaw, RouteParamsRaw } from 'vue-router';
|
||||||
|
|
||||||
export interface MultipleTabState {
|
export interface MultipleTabState {
|
||||||
cacheTabList: Set<string>;
|
cacheTabList: Set<string>;
|
||||||
tabList: RouteLocationNormalized[];
|
tabList: RouteLocationNormalized[];
|
||||||
lastDragEndIndex: number;
|
lastDragEndIndex: number;
|
||||||
|
redirectPageParam: null | redirectPageParamType;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface redirectPageParamType {
|
||||||
|
redirect_type: string;
|
||||||
|
name?: string;
|
||||||
|
path?: string;
|
||||||
|
query: LocationQueryRaw;
|
||||||
|
params?: RouteParamsRaw;
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleGotoPage(router: Router) {
|
function handleGotoPage(router: Router) {
|
||||||
@@ -45,6 +55,8 @@ export const useMultipleTabStore = defineStore({
|
|||||||
tabList: cacheTab ? Persistent.getLocal(MULTIPLE_TABS_KEY) || [] : [],
|
tabList: cacheTab ? Persistent.getLocal(MULTIPLE_TABS_KEY) || [] : [],
|
||||||
// Index of the last moved tab
|
// Index of the last moved tab
|
||||||
lastDragEndIndex: 0,
|
lastDragEndIndex: 0,
|
||||||
|
// 重定向时存储的路由参数
|
||||||
|
redirectPageParam: null,
|
||||||
}),
|
}),
|
||||||
getters: {
|
getters: {
|
||||||
getTabList(): RouteLocationNormalized[] {
|
getTabList(): RouteLocationNormalized[] {
|
||||||
@@ -348,6 +360,9 @@ export const useMultipleTabStore = defineStore({
|
|||||||
await this.updateCacheTab();
|
await this.updateCacheTab();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
setRedirectPageParam(data) {
|
||||||
|
this.redirectPageParam = data;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -190,7 +190,7 @@ export const useUserStore = defineStore({
|
|||||||
//update-end---author:wangshuai ---date:20230424 for:【QQYUN-5195】登录之后直接刷新页面导致没有进入创建组织页面------------
|
//update-end---author:wangshuai ---date:20230424 for:【QQYUN-5195】登录之后直接刷新页面导致没有进入创建组织页面------------
|
||||||
// 当前页面打开
|
// 当前页面打开
|
||||||
window.open(redirect, '_self')
|
window.open(redirect, '_self')
|
||||||
return;
|
return data;
|
||||||
}
|
}
|
||||||
// update-end-author:sunjianlei date:20230306 for: 修复登录成功后,没有正确重定向的问题
|
// update-end-author:sunjianlei date:20230306 for: 修复登录成功后,没有正确重定向的问题
|
||||||
|
|
||||||
|
@@ -6,6 +6,9 @@ import { reactive } from "vue";
|
|||||||
import { getTenantId, getToken } from "/@/utils/auth";
|
import { getTenantId, getToken } from "/@/utils/auth";
|
||||||
import { useUserStoreWithOut } from "/@/store/modules/user";
|
import { useUserStoreWithOut } from "/@/store/modules/user";
|
||||||
|
|
||||||
|
import { Modal } from "ant-design-vue";
|
||||||
|
import { defHttp } from "@/utils/http/axios";
|
||||||
|
|
||||||
const globSetting = useGlobSetting();
|
const globSetting = useGlobSetting();
|
||||||
const baseApiUrl = globSetting.domainUrl;
|
const baseApiUrl = globSetting.domainUrl;
|
||||||
/**
|
/**
|
||||||
@@ -459,3 +462,52 @@ export function replaceUserInfoByExpression(expression: string | any[]) {
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return isString ? replace(expression) : expression.map(replace);
|
return isString ? replace(expression) : expression.map(replace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置租户缓存,当租户退出的时候
|
||||||
|
*
|
||||||
|
* @param tenantId
|
||||||
|
*/
|
||||||
|
export async function userExitChangeLoginTenantId(tenantId){
|
||||||
|
const userStore = useUserStoreWithOut();
|
||||||
|
//step 1 获取用户租户
|
||||||
|
const url = '/sys/tenant/getCurrentUserTenant'
|
||||||
|
let currentTenantId = null;
|
||||||
|
const data = await defHttp.get({ url });
|
||||||
|
if(data && data.list){
|
||||||
|
let arr = data.list;
|
||||||
|
if(arr.length>0){
|
||||||
|
//step 2.判断当前id是否存在用户租户中
|
||||||
|
let filterTenantId = arr.filter((item) => item.id == tenantId);
|
||||||
|
//存在说明不是退出的不是当前租户,还用用来的租户即可
|
||||||
|
if(filterTenantId && filterTenantId.length>0){
|
||||||
|
currentTenantId = tenantId;
|
||||||
|
}else{
|
||||||
|
//不存在默认第一个
|
||||||
|
currentTenantId = arr[0].id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
userStore.setTenant(currentTenantId);
|
||||||
|
//切换租户后要刷新首页
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 我的租户模块需要开启多租户提示
|
||||||
|
*
|
||||||
|
* @param title 标题
|
||||||
|
*/
|
||||||
|
export function tenantSaasMessage(title){
|
||||||
|
let tenantId = getTenantId();
|
||||||
|
if(!tenantId){
|
||||||
|
Modal.confirm({
|
||||||
|
title:title,
|
||||||
|
content: '此菜单需要在多租户模式下使用,否则数据会出现混乱',
|
||||||
|
okText: '确认',
|
||||||
|
okType: 'danger',
|
||||||
|
// @ts-ignore
|
||||||
|
cancelButtonProps: { style: { display: 'none' } },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@@ -216,7 +216,7 @@
|
|||||||
key: 'action',
|
key: 'action',
|
||||||
type: JVxeTypes.slot,
|
type: JVxeTypes.slot,
|
||||||
fixed: 'right',
|
fixed: 'right',
|
||||||
minWidth: 100,
|
minWidth: 120,
|
||||||
align: 'center',
|
align: 'center',
|
||||||
slotName: 'myAction',
|
slotName: 'myAction',
|
||||||
},
|
},
|
||||||
@@ -291,12 +291,18 @@
|
|||||||
console.log('查看: ', { props });
|
console.log('查看: ', { props });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// async function onDeleteRow(props) {
|
||||||
|
// // 同步调用删除方法
|
||||||
|
// const res = await tableRef.value?.removeRows(props.row);
|
||||||
|
// if (res && res.rows.length > 0) {
|
||||||
|
// createMessage.success('删除成功');
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
async function onDeleteRow(props) {
|
async function onDeleteRow(props) {
|
||||||
// 调用删除方法
|
// 异步调用删除方法
|
||||||
const res = await tableRef.value?.removeRows(props.row);
|
const res = await tableRef.value?.removeRows(props.row, true);
|
||||||
if (res && res.rows.length > 0) {
|
console.log('删除成功~', res);
|
||||||
createMessage.success('删除成功');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleValueChange(event) {
|
function handleValueChange(event) {
|
||||||
@@ -361,8 +367,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function doDelete(deleteRows) {
|
function doDelete(deleteRows) {
|
||||||
|
let rowId;
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
let rowId = deleteRows.filter((row) => row.id);
|
if (Array.isArray(deleteRows)) {
|
||||||
|
rowId = deleteRows.filter((row) => row.id);
|
||||||
|
} else {
|
||||||
|
rowId = deleteRows.id;
|
||||||
|
}
|
||||||
console.log('删除 rowId: ', rowId);
|
console.log('删除 rowId: ', rowId);
|
||||||
setTimeout(() => resolve(true), 1500);
|
setTimeout(() => resolve(true), 1500);
|
||||||
});
|
});
|
||||||
|
@@ -3,8 +3,7 @@
|
|||||||
<a-card class="daily-article">
|
<a-card class="daily-article">
|
||||||
<a-card-meta :title="content.titile" :description="'发布人:' + content.sender + ' 发布时间: ' + content.sendTime"> </a-card-meta>
|
<a-card-meta :title="content.titile" :description="'发布人:' + content.sender + ' 发布时间: ' + content.sendTime"> </a-card-meta>
|
||||||
<a-divider />
|
<a-divider />
|
||||||
<span v-html="content.msgContent" class="article-content"></span>
|
<div v-html="content.msgContent" class="article-content"></div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<a-button v-if="hasHref" @click="jumpToHandlePage">前往办理<ArrowRightOutlined /></a-button>
|
<a-button v-if="hasHref" @click="jumpToHandlePage">前往办理<ArrowRightOutlined /></a-button>
|
||||||
</div>
|
</div>
|
||||||
@@ -17,6 +16,8 @@
|
|||||||
import { ArrowRightOutlined } from '@ant-design/icons-vue';
|
import { ArrowRightOutlined } from '@ant-design/icons-vue';
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import xss from 'xss'
|
import xss from 'xss'
|
||||||
|
import { options } from './XssWhiteList'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
import { ref, unref } from 'vue';
|
import { ref, unref } from 'vue';
|
||||||
@@ -29,7 +30,9 @@
|
|||||||
//data.record.msgContent = '<p>2323</p><input onmouseover=alert(1)>xss test';
|
//data.record.msgContent = '<p>2323</p><input onmouseover=alert(1)>xss test';
|
||||||
//update-begin-author:taoyan date:2022-7-14 for: VUEN-1702 【禁止问题】sql注入漏洞
|
//update-begin-author:taoyan date:2022-7-14 for: VUEN-1702 【禁止问题】sql注入漏洞
|
||||||
if(data.record.msgContent){
|
if(data.record.msgContent){
|
||||||
data.record.msgContent = xss(data.record.msgContent)
|
//update-begin---author:wangshuai---date:2023-11-15---for:【QQYUN-7049】3.6.0版本 通知公告中发布的富文本消息,在我的消息中查看没有样式---
|
||||||
|
data.record.msgContent = xss(data.record.msgContent,options);
|
||||||
|
//update-end---author:wangshuai---date:2023-11-15---for:【QQYUN-7049】3.6.0版本 通知公告中发布的富文本消息,在我的消息中查看没有样式---
|
||||||
}
|
}
|
||||||
//update-end-author:taoyan date:2022-7-14 for: VUEN-1702 【禁止问题】sql注入漏洞
|
//update-end-author:taoyan date:2022-7-14 for: VUEN-1702 【禁止问题】sql注入漏洞
|
||||||
content.value = data.record;
|
content.value = data.record;
|
||||||
|
41
src/views/monitor/mynews/XssWhiteList.ts
Normal file
41
src/views/monitor/mynews/XssWhiteList.ts
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
//xss攻击白名单列表
|
||||||
|
export const options = {
|
||||||
|
whiteList: {
|
||||||
|
h1: ['style'],
|
||||||
|
h2: ['style'],
|
||||||
|
h3: ['style'],
|
||||||
|
h4: ['style'],
|
||||||
|
h5: ['style'],
|
||||||
|
h6: ['style'],
|
||||||
|
hr: ['style'],
|
||||||
|
span: ['style'],
|
||||||
|
strong: ['style'],
|
||||||
|
b: ['style'],
|
||||||
|
i: ['style'],
|
||||||
|
br: [],
|
||||||
|
p: ['style'],
|
||||||
|
pre: ['style'],
|
||||||
|
code: ['style'],
|
||||||
|
a: ['style', 'target', 'href', 'title', 'rel'],
|
||||||
|
img: ['style', 'src', 'title','width','height'],
|
||||||
|
div: ['style'],
|
||||||
|
table: ['style', 'width', 'border', 'height'],
|
||||||
|
tr: ['style'],
|
||||||
|
td: ['style', 'width', 'colspan'],
|
||||||
|
th: ['style', 'width', 'colspan'],
|
||||||
|
tbody: ['style'],
|
||||||
|
ul: ['style'],
|
||||||
|
li: ['style'],
|
||||||
|
ol: ['style'],
|
||||||
|
dl: ['style'],
|
||||||
|
dt: ['style'],
|
||||||
|
em: ['style'],
|
||||||
|
cite: ['style'],
|
||||||
|
section: ['style'],
|
||||||
|
header: ['style'],
|
||||||
|
footer: ['style'],
|
||||||
|
blockquote: ['style'],
|
||||||
|
audio: ['autoplay', 'controls', 'loop', 'preload', 'src'],
|
||||||
|
video: ['autoplay', 'controls', 'loop', 'preload', 'src', 'height', 'width'],
|
||||||
|
},
|
||||||
|
};
|
@@ -4,27 +4,27 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { unref } from 'vue';
|
import { unref } from 'vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
|
import { useMultipleTabStore } from '/@/store/modules/multipleTab';
|
||||||
|
// update-begin--author:liaozhiyang---date:20231123---for:【QQYUN-7099】动态路由匹配右键重新加载404
|
||||||
const { currentRoute, replace } = useRouter();
|
const { currentRoute, replace } = useRouter();
|
||||||
|
|
||||||
const { params, query } = unref(currentRoute);
|
const { params, query } = unref(currentRoute);
|
||||||
const { path, _redirect_type = 'path' } = params;
|
const { path } = params;
|
||||||
|
const tabStore = useMultipleTabStore();
|
||||||
Reflect.deleteProperty(params, '_redirect_type');
|
const redirectPageParam = tabStore.redirectPageParam;
|
||||||
Reflect.deleteProperty(params, 'path');
|
|
||||||
|
|
||||||
const _path = Array.isArray(path) ? path.join('/') : path;
|
const _path = Array.isArray(path) ? path.join('/') : path;
|
||||||
|
if (redirectPageParam) {
|
||||||
if (_redirect_type === 'name') {
|
if (redirectPageParam.redirect_type === 'name') {
|
||||||
replace({
|
replace({
|
||||||
name: _path,
|
name: redirectPageParam.name,
|
||||||
query,
|
query: redirectPageParam.query,
|
||||||
params,
|
params: redirectPageParam.params,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
replace({
|
replace({
|
||||||
path: _path.startsWith('/') ? _path : '/' + _path,
|
path: _path.startsWith('/') ? _path : '/' + _path,
|
||||||
query,
|
query,
|
||||||
});
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
// update-end--author:liaozhiyang---date:20231123---for:【QQYUN-7099】动态路由匹配右键重新加载404
|
||||||
</script>
|
</script>
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import { BasicColumn, FormSchema } from '/@/components/Table';
|
import { BasicColumn, FormSchema } from '/@/components/Table';
|
||||||
import { render } from '/@/utils/common/renderUtils';
|
import { render } from '/@/utils/common/renderUtils';
|
||||||
import { duplicateCheck } from '/@/views/system/user/user.api';
|
import { duplicateCheckDelay } from '/@/views/system/user/user.api';
|
||||||
import { validateCheckRule } from '/@/views/system/checkRule/check.rule.api';
|
import { validateCheckRule } from '/@/views/system/checkRule/check.rule.api';
|
||||||
import { array } from 'vue-types';
|
import { array } from 'vue-types';
|
||||||
|
|
||||||
@@ -80,7 +80,7 @@ export const formSchema: FormSchema[] = [
|
|||||||
fieldVal: value,
|
fieldVal: value,
|
||||||
dataId: model.id,
|
dataId: model.id,
|
||||||
};
|
};
|
||||||
duplicateCheck(params)
|
duplicateCheckDelay(params)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
res.success ? resolve() : reject('规则编码已存在!');
|
res.success ? resolve() : reject('规则编码已存在!');
|
||||||
})
|
})
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import { Ref } from 'vue';
|
import { Ref } from 'vue';
|
||||||
import { duplicateCheck } from '/@/views/system/user/user.api';
|
import { duplicateCheckDelay } from '/@/views/system/user/user.api';
|
||||||
import { BasicColumn, FormSchema } from '/@/components/Table';
|
import { BasicColumn, FormSchema } from '/@/components/Table';
|
||||||
import { DescItem } from '/@/components/Description';
|
import { DescItem } from '/@/components/Description';
|
||||||
import { findTree } from '/@/utils/common/compUtils';
|
import { findTree } from '/@/utils/common/compUtils';
|
||||||
@@ -115,7 +115,7 @@ export const departRoleModalFormSchema: FormSchema[] = [
|
|||||||
fieldVal: value,
|
fieldVal: value,
|
||||||
dataId: model.id,
|
dataId: model.id,
|
||||||
};
|
};
|
||||||
duplicateCheck(params)
|
duplicateCheckDelay(params)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
res.success ? resolve() : reject(res.message || '校验失败');
|
res.success ? resolve() : reject(res.message || '校验失败');
|
||||||
})
|
})
|
||||||
|
@@ -1,6 +1,22 @@
|
|||||||
<template>
|
<template>
|
||||||
<BasicModal v-bind="$attrs" @register="registerModal" :title="getTitle" @ok="handleSubmit" width="800px">
|
<BasicModal v-bind="$attrs" @register="registerModal" :title="getTitle" @ok="handleSubmit" width="800px">
|
||||||
<BasicForm @register="registerForm" />
|
<!-- update-begin---author:wangshuai---date:2023-10-23---for:【QQYUN-6804】后台模式字典没有颜色配置--- -->
|
||||||
|
<BasicForm @register="registerForm" >
|
||||||
|
<template #itemColor="{ model, field }">
|
||||||
|
<div class="item-tool">
|
||||||
|
<div
|
||||||
|
v-for="(item,index) in Colors"
|
||||||
|
:style="{ color: item[0] }"
|
||||||
|
:class="model.itemColor===item[0]?'item-active':''"
|
||||||
|
class="item-color"
|
||||||
|
@click="itemColorClick(item)">
|
||||||
|
<div class="item-color-border"></div>
|
||||||
|
<div class="item-back" :style="{ background: item[0] }"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</BasicForm>
|
||||||
|
<!-- update-end---author:wangshuai---date:2023-10-23---for:【QQYUN-6804】后台模式字典没有颜色配置--- -->
|
||||||
</BasicModal>
|
</BasicModal>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
@@ -9,6 +25,8 @@
|
|||||||
import { BasicForm, useForm } from '/src/components/Form';
|
import { BasicForm, useForm } from '/src/components/Form';
|
||||||
import { itemFormSchema } from '../dict.data';
|
import { itemFormSchema } from '../dict.data';
|
||||||
import { saveOrUpdateDictItem } from '../dict.api';
|
import { saveOrUpdateDictItem } from '../dict.api';
|
||||||
|
import { Colors } from '/@/utils/dict/DictColors.js'
|
||||||
|
|
||||||
// 声明Emits
|
// 声明Emits
|
||||||
const emit = defineEmits(['success', 'register']);
|
const emit = defineEmits(['success', 'register']);
|
||||||
const props = defineProps({ dictId: String });
|
const props = defineProps({ dictId: String });
|
||||||
@@ -60,4 +78,49 @@
|
|||||||
setModalProps({ confirmLoading: false });
|
setModalProps({ confirmLoading: false });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字典颜色点击事件
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* @param item
|
||||||
|
* @param model
|
||||||
|
*/
|
||||||
|
function itemColorClick(item) {
|
||||||
|
console.log(item)
|
||||||
|
setFieldsValue({ itemColor: item[0] })
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
<style lang="less" scoped>
|
||||||
|
/*begin 字典颜色配置样式*/
|
||||||
|
.item-tool{
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
.item-color{
|
||||||
|
width: 18px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
cursor: pointer;
|
||||||
|
align-items: center;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
.item-back{
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.item-color-border{
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
.item-active .item-color-border{
|
||||||
|
visibility: visible;
|
||||||
|
position: absolute;
|
||||||
|
border: 1px solid;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
/*end 字典颜色配置样式*/
|
||||||
|
</style>
|
||||||
|
@@ -2,6 +2,8 @@ import { BasicColumn } from '/@/components/Table';
|
|||||||
import { FormSchema } from '/@/components/Table';
|
import { FormSchema } from '/@/components/Table';
|
||||||
import { dictItemCheck } from './dict.api';
|
import { dictItemCheck } from './dict.api';
|
||||||
import { rules } from '/@/utils/helper/validator';
|
import { rules } from '/@/utils/helper/validator';
|
||||||
|
import { h } from "vue";
|
||||||
|
|
||||||
export const columns: BasicColumn[] = [
|
export const columns: BasicColumn[] = [
|
||||||
{
|
{
|
||||||
title: '字典名称',
|
title: '字典名称',
|
||||||
@@ -93,6 +95,17 @@ export const dictItemColumns: BasicColumn[] = [
|
|||||||
dataIndex: 'itemValue',
|
dataIndex: 'itemValue',
|
||||||
width: 80,
|
width: 80,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: '字典颜色',
|
||||||
|
dataIndex: 'itemColor',
|
||||||
|
width: 80,
|
||||||
|
align:'center',
|
||||||
|
customRender:({ text }) => {
|
||||||
|
return h('div', {
|
||||||
|
style: {"background": text, "width":"18px","height":"18px","border-radius":"50%","margin":"0 auto"}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export const dictItemSearchFormSchema: FormSchema[] = [
|
export const dictItemSearchFormSchema: FormSchema[] = [
|
||||||
@@ -159,6 +172,12 @@ export const itemFormSchema: FormSchema[] = [
|
|||||||
];
|
];
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: '颜色值',
|
||||||
|
field: 'itemColor',
|
||||||
|
component: 'Input',
|
||||||
|
slot:'itemColor'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: '描述',
|
label: '描述',
|
||||||
field: 'description',
|
field: 'description',
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import { BasicColumn, FormSchema } from '/@/components/Table';
|
import { BasicColumn, FormSchema } from '/@/components/Table';
|
||||||
import { duplicateCheck } from '/@/views/system/user/user.api';
|
import { duplicateCheckDelay } from '/@/views/system/user/user.api';
|
||||||
|
|
||||||
export const columns: BasicColumn[] = [
|
export const columns: BasicColumn[] = [
|
||||||
{
|
{
|
||||||
@@ -80,7 +80,7 @@ export const formSchema: FormSchema[] = [
|
|||||||
fieldVal: value,
|
fieldVal: value,
|
||||||
dataId: model.id,
|
dataId: model.id,
|
||||||
};
|
};
|
||||||
duplicateCheck(params)
|
duplicateCheckDelay(params)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
res.success ? resolve() : reject('规则编码已存在!');
|
res.success ? resolve() : reject('规则编码已存在!');
|
||||||
})
|
})
|
||||||
|
@@ -3,8 +3,8 @@
|
|||||||
<BasicTable @register="registerTable" :rowSelection="rowSelection">
|
<BasicTable @register="registerTable" :rowSelection="rowSelection">
|
||||||
<template #tableTitle>
|
<template #tableTitle>
|
||||||
<a-button preIcon="ant-design:plus-outlined" type="primary" @click="handleAdd">新增</a-button>
|
<a-button preIcon="ant-design:plus-outlined" type="primary" @click="handleAdd">新增</a-button>
|
||||||
<a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
|
<!-- <a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>-->
|
||||||
<j-upload-button type="primary" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
|
<!-- <j-upload-button type="primary" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>-->
|
||||||
<a-dropdown v-if="selectedRowKeys.length > 0">
|
<a-dropdown v-if="selectedRowKeys.length > 0">
|
||||||
<template #overlay>
|
<template #overlay>
|
||||||
<a-menu>
|
<a-menu>
|
||||||
|
@@ -30,7 +30,7 @@
|
|||||||
<RoleDesc @register="registerDesc"></RoleDesc>
|
<RoleDesc @register="registerDesc"></RoleDesc>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" name="system-role" setup>
|
<script lang="ts" name="system-role" setup>
|
||||||
import { ref } from 'vue';
|
import { onMounted, ref } from 'vue';
|
||||||
import { BasicTable, TableAction } from '/@/components/Table';
|
import { BasicTable, TableAction } from '/@/components/Table';
|
||||||
import { useDrawer } from '/@/components/Drawer';
|
import { useDrawer } from '/@/components/Drawer';
|
||||||
import { useModal } from '/@/components/Modal';
|
import { useModal } from '/@/components/Modal';
|
||||||
@@ -41,6 +41,8 @@
|
|||||||
import { listByTenant, deleteRole, batchDeleteRole, getExportUrl, getImportUrl } from './role.api';
|
import { listByTenant, deleteRole, batchDeleteRole, getExportUrl, getImportUrl } from './role.api';
|
||||||
import { useListPage } from '/@/hooks/system/useListPage';
|
import { useListPage } from '/@/hooks/system/useListPage';
|
||||||
import { getLoginTenantName } from "/@/views/system/tenant/tenant.api";
|
import { getLoginTenantName } from "/@/views/system/tenant/tenant.api";
|
||||||
|
import { tenantSaasMessage } from "@/utils/common/compUtils";
|
||||||
|
|
||||||
const showFooter = ref(true);
|
const showFooter = ref(true);
|
||||||
const [roleUserDrawer, { openDrawer: openRoleUserDrawer }] = useDrawer();
|
const [roleUserDrawer, { openDrawer: openRoleUserDrawer }] = useDrawer();
|
||||||
const [registerDrawer, { openDrawer }] = useDrawer();
|
const [registerDrawer, { openDrawer }] = useDrawer();
|
||||||
@@ -167,6 +169,10 @@
|
|||||||
async function getTenantName(){
|
async function getTenantName(){
|
||||||
loginTenantName.value = await getLoginTenantName();
|
loginTenantName.value = await getLoginTenantName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMounted(()=>{
|
||||||
|
tenantSaasMessage('租户角色')
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
|
@@ -27,7 +27,7 @@
|
|||||||
:selectedKeys="selectedKeys"
|
:selectedKeys="selectedKeys"
|
||||||
:checkStrictly="checkStrictly"
|
:checkStrictly="checkStrictly"
|
||||||
:clickRowToExpand="false"
|
:clickRowToExpand="false"
|
||||||
title="所拥有的的权限"
|
title="所拥有的权限"
|
||||||
@check="onCheck"
|
@check="onCheck"
|
||||||
@select="onTreeNodeSelect"
|
@select="onTreeNodeSelect"
|
||||||
>
|
>
|
||||||
|
@@ -82,7 +82,24 @@ export const saveOrUpdateRole = (params, isUpdate) => {
|
|||||||
* 编码校验
|
* 编码校验
|
||||||
* @param params
|
* @param params
|
||||||
*/
|
*/
|
||||||
export const isRoleExist = (params) => defHttp.get({ url: Api.isRoleExist, params }, { isTransformResponse: false });
|
// update-begin--author:liaozhiyang---date:20231215---for:【QQYUN-7415】表单调用接口进行校验的添加防抖
|
||||||
|
let timer;
|
||||||
|
export const isRoleExist = (params) => {
|
||||||
|
return new Promise((resolve, rejected) => {
|
||||||
|
clearTimeout(timer);
|
||||||
|
timer = setTimeout(() => {
|
||||||
|
defHttp
|
||||||
|
.get({ url: Api.isRoleExist, params }, { isTransformResponse: false })
|
||||||
|
.then((res) => {
|
||||||
|
resolve(res);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
rejected(error);
|
||||||
|
});
|
||||||
|
}, 500);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
// update-end--author:liaozhiyang---date:20231215---for:【QQYUN-7415】表单调用接口进行校验的添加防抖
|
||||||
/**
|
/**
|
||||||
* 根据角色查询树信息
|
* 根据角色查询树信息
|
||||||
*/
|
*/
|
||||||
|
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
<script lang="ts" name="tenant-system-user" setup>
|
<script lang="ts" name="tenant-system-user" setup>
|
||||||
//ts语法
|
//ts语法
|
||||||
import { ref, unref } from 'vue';
|
import { onMounted, ref, unref } from 'vue';
|
||||||
import { BasicTable, TableAction, ActionItem } from '/@/components/Table';
|
import { BasicTable, TableAction, ActionItem } from '/@/components/Table';
|
||||||
import UserDrawer from '../user/UserDrawer.vue';
|
import UserDrawer from '../user/UserDrawer.vue';
|
||||||
import JThirdAppButton from '/@/components/jeecg/thirdApp/JThirdAppButton.vue';
|
import JThirdAppButton from '/@/components/jeecg/thirdApp/JThirdAppButton.vue';
|
||||||
@@ -48,6 +48,7 @@
|
|||||||
import { changeOwenUserTenant } from "/@/views/system/usersetting/UserSetting.api";
|
import { changeOwenUserTenant } from "/@/views/system/usersetting/UserSetting.api";
|
||||||
import { getLoginTenantName } from "/@/views/system/tenant/tenant.api";
|
import { getLoginTenantName } from "/@/views/system/tenant/tenant.api";
|
||||||
import TenantUserDrawer from './components/TenantUserDrawer.vue';
|
import TenantUserDrawer from './components/TenantUserDrawer.vue';
|
||||||
|
import { tenantSaasMessage } from "@/utils/common/compUtils";
|
||||||
|
|
||||||
const { createMessage, createConfirm } = useMessage();
|
const { createMessage, createConfirm } = useMessage();
|
||||||
|
|
||||||
@@ -157,7 +158,9 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '离职',
|
label: '离职',
|
||||||
onClick: handleQuit.bind(null, record.username),
|
//update-begin---author:wangshuai---date:2023-10-25---for:【QQYUN-6822】9.离职交接人选的是自己,完成之后数据没了---
|
||||||
|
onClick: handleQuit.bind(null, record.id),
|
||||||
|
//update-end---author:wangshuai---date:2023-10-25---for:【QQYUN-6822】9.离职交接人选的是自己,完成之后数据没了---
|
||||||
//update-begin---author:wangshuai ---date:20230130 for:[QQYUN-3974]租户的创建人 不应该有离职按钮------------
|
//update-begin---author:wangshuai ---date:20230130 for:[QQYUN-3974]租户的创建人 不应该有离职按钮------------
|
||||||
ifShow: () =>{
|
ifShow: () =>{
|
||||||
return record.status === '1' && record.username!== record.createBy;
|
return record.status === '1' && record.username!== record.createBy;
|
||||||
@@ -278,6 +281,10 @@
|
|||||||
loginTenantName.value = await getLoginTenantName();
|
loginTenantName.value = await getLoginTenantName();
|
||||||
}
|
}
|
||||||
//update-end---author:wangshuai ---date:20230710 for:【QQYUN-5723】4、显示当前登录租户------------
|
//update-end---author:wangshuai ---date:20230710 for:【QQYUN-5723】4、显示当前登录租户------------
|
||||||
|
|
||||||
|
onMounted(()=>{
|
||||||
|
tenantSaasMessage('租户用户')
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
@@ -30,7 +30,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" name="my-tenant-list" setup>
|
<script lang="ts" name="my-tenant-list" setup>
|
||||||
import { ref, unref } from 'vue';
|
import { onMounted, ref, unref } from 'vue';
|
||||||
import { BasicTable, TableAction } from '/@/components/Table';
|
import { BasicTable, TableAction } from '/@/components/Table';
|
||||||
import { useModal } from '/@/components/Modal';
|
import { useModal } from '/@/components/Modal';
|
||||||
import { invitationUserJoin, getTenantPageListByUserId } from '../tenant.api';
|
import { invitationUserJoin, getTenantPageListByUserId } from '../tenant.api';
|
||||||
@@ -43,6 +43,7 @@
|
|||||||
import TenantPackList from '../pack/TenantPackList.vue';
|
import TenantPackList from '../pack/TenantPackList.vue';
|
||||||
import { getTenantId } from '/@/utils/auth';
|
import { getTenantId } from '/@/utils/auth';
|
||||||
import { useUserStore } from '/@/store/modules/user';
|
import { useUserStore } from '/@/store/modules/user';
|
||||||
|
import { tenantSaasMessage } from "@/utils/common/compUtils";
|
||||||
|
|
||||||
const { createMessage } = useMessage();
|
const { createMessage } = useMessage();
|
||||||
const [registerModal, { openModal }] = useModal();
|
const [registerModal, { openModal }] = useModal();
|
||||||
@@ -137,4 +138,9 @@
|
|||||||
function handleSuccess() {
|
function handleSuccess() {
|
||||||
(selectedRowKeys.value = []) && reload();
|
(selectedRowKeys.value = []) && reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMounted(()=>{
|
||||||
|
//提示信息
|
||||||
|
tenantSaasMessage('我的租户')
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
@@ -96,6 +96,29 @@ export const saveOrUpdateUser = (params, isUpdate) => {
|
|||||||
* @param params
|
* @param params
|
||||||
*/
|
*/
|
||||||
export const duplicateCheck = (params) => defHttp.get({ url: Api.duplicateCheck, params }, { isTransformResponse: false });
|
export const duplicateCheck = (params) => defHttp.get({ url: Api.duplicateCheck, params }, { isTransformResponse: false });
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 20231215
|
||||||
|
* liaozhiyang
|
||||||
|
* 唯一校验( 延迟【防抖】)
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
let timer;
|
||||||
|
export const duplicateCheckDelay = (params) => {
|
||||||
|
return new Promise((resove, rejected) => {
|
||||||
|
clearTimeout(timer);
|
||||||
|
timer = setTimeout(() => {
|
||||||
|
defHttp
|
||||||
|
.get({ url: Api.duplicateCheck, params }, { isTransformResponse: false })
|
||||||
|
.then((res: any) => {
|
||||||
|
resove(res as any);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
rejected(error);
|
||||||
|
});
|
||||||
|
}, 500);
|
||||||
|
});
|
||||||
|
};
|
||||||
/**
|
/**
|
||||||
* 获取全部角色(租户隔离)
|
* 获取全部角色(租户隔离)
|
||||||
* @param params
|
* @param params
|
||||||
|
@@ -191,6 +191,7 @@ export const formSchema: FormSchema[] = [
|
|||||||
api: getAllRolesListNoByTenant,
|
api: getAllRolesListNoByTenant,
|
||||||
labelField: 'roleName',
|
labelField: 'roleName',
|
||||||
valueField: 'id',
|
valueField: 'id',
|
||||||
|
immediate: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -228,6 +229,7 @@ export const formSchema: FormSchema[] = [
|
|||||||
numberToString: true,
|
numberToString: true,
|
||||||
labelField: 'name',
|
labelField: 'name',
|
||||||
valueField: 'id',
|
valueField: 'id',
|
||||||
|
immediate: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@@ -69,42 +69,6 @@
|
|||||||
<Icon icon="ant-design:edit-outlined" class="footer-icon" />
|
<Icon icon="ant-design:edit-outlined" class="footer-icon" />
|
||||||
<span>查看租户名片</span>
|
<span>查看租户名片</span>
|
||||||
</span>
|
</span>
|
||||||
<span
|
|
||||||
v-if="item.userTenantStatus !== '3' && item.auth"
|
|
||||||
@click.stop="footerClick('tenantSetting', item)"
|
|
||||||
class="font-color333 flex-flow margin-right40 font-size13 pointer"
|
|
||||||
>
|
|
||||||
<Icon icon="ant-design:tool-outlined" class="footer-icon" />
|
|
||||||
<span>租户管理?</span>
|
|
||||||
</span>
|
|
||||||
<span v-else-if="item.userTenantStatus === '3' && item.auth" class="font-color9e flex-flow margin-right40 font-size13">
|
|
||||||
<Icon icon="ant-design:tool-outlined" class="footer-icon" />
|
|
||||||
<span>租户管理?</span>
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
v-if="item.userTenantStatus !== '3' && !item.auth"
|
|
||||||
@click.stop="footerClick('tenantSetting', item)"
|
|
||||||
class="font-color333 flex-flow margin-right40 font-size13 pointer"
|
|
||||||
>
|
|
||||||
<Icon icon="ant-design:tool-outlined" class="footer-icon" />
|
|
||||||
<span>申请角色权限?</span>
|
|
||||||
</span>
|
|
||||||
<span v-else-if="item.userTenantStatus === '3' && !item.auth" class="font-color9e flex-flow margin-right40 font-size13">
|
|
||||||
<Icon icon="ant-design:tool-outlined" class="footer-icon" />
|
|
||||||
<span>申请角色权限?</span>
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
v-if="item.userTenantStatus !== '3'"
|
|
||||||
@click.stop="footerClick('tenantSetting', item)"
|
|
||||||
class="font-color333 flex-flow margin-right40 font-size13 pointer"
|
|
||||||
>
|
|
||||||
<Icon icon="ant-design:gold-outlined" class="footer-icon" />
|
|
||||||
<span>我的汇报关系?</span>
|
|
||||||
</span>
|
|
||||||
<span v-else class="font-color9e flex-flow margin-right40 font-size13">
|
|
||||||
<Icon icon="ant-design:gold-outlined" class="footer-icon" />
|
|
||||||
<span>我的汇报关系?</span>
|
|
||||||
</span>
|
|
||||||
<span
|
<span
|
||||||
v-if="item.userTenantStatus !== '3'"
|
v-if="item.userTenantStatus !== '3'"
|
||||||
@click.stop="footerClick('exitTenant', item)"
|
@click.stop="footerClick('exitTenant', item)"
|
||||||
@@ -226,7 +190,7 @@ import { onMounted, ref, unref } from "vue";
|
|||||||
import { getTenantListByUserId, cancelApplyTenant, exitUserTenant, changeOwenUserTenant, agreeOrRefuseJoinTenant } from "./UserSetting.api";
|
import { getTenantListByUserId, cancelApplyTenant, exitUserTenant, changeOwenUserTenant, agreeOrRefuseJoinTenant } from "./UserSetting.api";
|
||||||
import { useUserStore } from "/@/store/modules/user";
|
import { useUserStore } from "/@/store/modules/user";
|
||||||
import { CollapseContainer } from "/@/components/Container";
|
import { CollapseContainer } from "/@/components/Container";
|
||||||
import { getFileAccessHttpUrl } from "/@/utils/common/compUtils";
|
import { getFileAccessHttpUrl, userExitChangeLoginTenantId } from "/@/utils/common/compUtils";
|
||||||
import headerImg from "/@/assets/images/header.jpg";
|
import headerImg from "/@/assets/images/header.jpg";
|
||||||
import {useMessage} from "/@/hooks/web/useMessage";
|
import {useMessage} from "/@/hooks/web/useMessage";
|
||||||
import { initDictOptions } from '/@/utils/dict';
|
import { initDictOptions } from '/@/utils/dict';
|
||||||
@@ -424,11 +388,7 @@ const userDetail = ref({
|
|||||||
if (res.success) {
|
if (res.success) {
|
||||||
createMessage.success(res.message);
|
createMessage.success(res.message);
|
||||||
cancelVisible.value = false;
|
cancelVisible.value = false;
|
||||||
//update-begin---author:wangshuai ---date:20230703 for:【QQYUN-5632】退出租户后 再点击主页 已退出的租户应用还可以操作------------
|
userExitChangeLoginTenantId(unref(myTenantInfo).tenantUserId);
|
||||||
userStore.setTenant(null);
|
|
||||||
//update-end---author:wangshuai ---date:20230703 for:【QQYUN-5632】退出租户后 再点击主页 已退出的租户应用还可以操作------------
|
|
||||||
//切换租户后要刷新首页
|
|
||||||
window.location.reload();
|
|
||||||
} else {
|
} else {
|
||||||
if (res.message === 'assignedOwen') {
|
if (res.message === 'assignedOwen') {
|
||||||
//需要指定变更者
|
//需要指定变更者
|
||||||
@@ -480,9 +440,9 @@ const userDetail = ref({
|
|||||||
changeOwenUserTenant({ userId:unref(tenantOwen), tenantId:unref(myTenantInfo).tenantUserId }).then((res) =>{
|
changeOwenUserTenant({ userId:unref(tenantOwen), tenantId:unref(myTenantInfo).tenantUserId }).then((res) =>{
|
||||||
if(res.success){
|
if(res.success){
|
||||||
createMessage.success(res.message);
|
createMessage.success(res.message);
|
||||||
userStore.setTenant(null);
|
//update-begin---author:wangshuai---date:2023-10-23---for:【QQYUN-6822】7、登录拥有多个租户身份的用户,退出租户,只剩下一个租户后显示为空---
|
||||||
//切换租户后要刷新首页
|
userExitChangeLoginTenantId(unref(myTenantInfo).tenantUserId);
|
||||||
window.location.reload();
|
//update-end---author:wangshuai---date:2023-10-23---for:【QQYUN-6822】7、登录拥有多个租户身份的用户,退出租户,只剩下一个租户后显示为空---
|
||||||
} else {
|
} else {
|
||||||
createMessage.warning(res.message);
|
createMessage.warning(res.message);
|
||||||
}
|
}
|
||||||
|
@@ -18,7 +18,7 @@
|
|||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
"lib": ["dom", "esnext"],
|
"lib": ["dom", "esnext"],
|
||||||
"types": ["vite/client", "jest"],
|
"types": ["vite/client", "jest"],
|
||||||
"typeRoots": ["./node_modules/@types/", "./types"],
|
"typeRoots": ["./node_modules/@types/", "./types","./node_modules"],
|
||||||
"noImplicitAny": false,
|
"noImplicitAny": false,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"paths": {
|
"paths": {
|
||||||
|
@@ -75,6 +75,8 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
|
|||||||
cssTarget: 'chrome80',
|
cssTarget: 'chrome80',
|
||||||
outDir: OUTPUT_DIR,
|
outDir: OUTPUT_DIR,
|
||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
|
// 关闭除屑优化,防止删除重要代码,导致打包后功能出现异常
|
||||||
|
treeshake: false,
|
||||||
output: {
|
output: {
|
||||||
chunkFileNames: 'js/[name]-[hash].js', // 引入文件名的名称
|
chunkFileNames: 'js/[name]-[hash].js', // 引入文件名的名称
|
||||||
entryFileNames: 'js/[name]-[hash].js', // 包的入口文件名称
|
entryFileNames: 'js/[name]-[hash].js', // 包的入口文件名称
|
||||||
|
Reference in New Issue
Block a user