v3.7.2 版本代码合并

This commit is contained in:
JEECG
2024-12-09 15:10:46 +08:00
parent 64b29f47e0
commit b0c4194602
118 changed files with 12729 additions and 1596 deletions

View File

@ -84,11 +84,14 @@ export default function ({ advanceState, emit, getProps, getSchema, formModel, d
advanceState.isAdvanced = true;
} else */
// update-end--author:sunjianlei---date:20211108---for: 注释掉该逻辑使小于等于2行时也显示展开收起按钮
if (itemColSum > BASIC_COL_LEN * 2 && itemColSum <= BASIC_COL_LEN * (unref(getProps).autoAdvancedLine || 3)) {
// update-begin--author:liaozhiyang---date:202401009---for【issues/7261】表格上方查询项autoAdvancedLine配置没有效果删除autoAdvancedLine
/*if (itemColSum > BASIC_COL_LEN * 2 && itemColSum <= BASIC_COL_LEN * (unref(getProps).autoAdvancedLine || 3)) {
advanceState.hideAdvanceBtn = false;
// 默认超过 3 行折叠
} else if (!advanceState.isLoad) {
} else*/
// update-end--author:liaozhiyang---date:202401009---for【issues/7261】表格上方查询项autoAdvancedLine配置没有效果删除autoAdvancedLine
if (!advanceState.isLoad) {
advanceState.isLoad = true;
advanceState.isAdvanced = !advanceState.isAdvanced;
// update-begin--author:sunjianlei---date:20211108---for: 如果总列数大于 autoAdvancedCol就默认折叠

View File

@ -79,13 +79,8 @@
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];
}
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];

View File

@ -26,72 +26,74 @@
</a-tabs>
<a-divider />
<!-- 执行时间预览 -->
<a-row :gutter="8">
<a-col :span="18" style="margin-top: 22px">
<a-row :gutter="8">
<a-col :span="8" style="margin-bottom: 12px">
<a-input v-model:value="inputValues.second" @blur="onInputBlur">
<template #addonBefore>
<span class="allow-click" @click="activeKey = 'second'"></span>
</template>
</a-input>
</a-col>
<a-col :span="8" style="margin-bottom: 12px">
<a-input v-model:value="inputValues.minute" @blur="onInputBlur">
<template #addonBefore>
<span class="allow-click" @click="activeKey = 'minute'"></span>
</template>
</a-input>
</a-col>
<a-col :span="8" style="margin-bottom: 12px">
<a-input v-model:value="inputValues.hour" @blur="onInputBlur">
<template #addonBefore>
<span class="allow-click" @click="activeKey = 'hour'"></span>
</template>
</a-input>
</a-col>
<a-col :span="8" style="margin-bottom: 12px">
<a-input v-model:value="inputValues.day" @blur="onInputBlur">
<template #addonBefore>
<span class="allow-click" @click="activeKey = 'day'"></span>
</template>
</a-input>
</a-col>
<a-col :span="8" style="margin-bottom: 12px">
<a-input v-model:value="inputValues.month" @blur="onInputBlur">
<template #addonBefore>
<span class="allow-click" @click="activeKey = 'month'"></span>
</template>
</a-input>
</a-col>
<a-col :span="8" style="margin-bottom: 12px">
<a-input v-model:value="inputValues.week" @blur="onInputBlur">
<template #addonBefore>
<span class="allow-click" @click="activeKey = 'week'"></span>
</template>
</a-input>
</a-col>
<a-col :span="8">
<a-input v-model:value="inputValues.year" @blur="onInputBlur">
<template #addonBefore>
<span class="allow-click" @click="activeKey = 'year'"></span>
</template>
</a-input>
</a-col>
<a-col :span="16">
<a-input v-model:value="inputValues.cron" @blur="onInputCronBlur">
<template #addonBefore>
<a-tooltip title="Cron表达式"></a-tooltip>
</template>
</a-input>
</a-col>
</a-row>
</a-col>
<a-col :span="6">
<div>近十次执行时间不含年</div>
<a-textarea type="textarea" :value="preTimeList" :rows="5" />
</a-col>
</a-row>
<div style="overflow: hidden">
<a-row :gutter="8">
<a-col :span="18" style="margin-top: 22px">
<a-row :gutter="8">
<a-col :span="8" style="margin-bottom: 12px">
<a-input v-model:value="inputValues.second" @blur="onInputBlur">
<template #addonBefore>
<span class="allow-click" @click="activeKey = 'second'"></span>
</template>
</a-input>
</a-col>
<a-col :span="8" style="margin-bottom: 12px">
<a-input v-model:value="inputValues.minute" @blur="onInputBlur">
<template #addonBefore>
<span class="allow-click" @click="activeKey = 'minute'"></span>
</template>
</a-input>
</a-col>
<a-col :span="8" style="margin-bottom: 12px">
<a-input v-model:value="inputValues.hour" @blur="onInputBlur">
<template #addonBefore>
<span class="allow-click" @click="activeKey = 'hour'"></span>
</template>
</a-input>
</a-col>
<a-col :span="8" style="margin-bottom: 12px">
<a-input v-model:value="inputValues.day" @blur="onInputBlur">
<template #addonBefore>
<span class="allow-click" @click="activeKey = 'day'"></span>
</template>
</a-input>
</a-col>
<a-col :span="8" style="margin-bottom: 12px">
<a-input v-model:value="inputValues.month" @blur="onInputBlur">
<template #addonBefore>
<span class="allow-click" @click="activeKey = 'month'"></span>
</template>
</a-input>
</a-col>
<a-col :span="8" style="margin-bottom: 12px">
<a-input v-model:value="inputValues.week" @blur="onInputBlur">
<template #addonBefore>
<span class="allow-click" @click="activeKey = 'week'"></span>
</template>
</a-input>
</a-col>
<a-col :span="8">
<a-input v-model:value="inputValues.year" @blur="onInputBlur">
<template #addonBefore>
<span class="allow-click" @click="activeKey = 'year'"></span>
</template>
</a-input>
</a-col>
<a-col :span="16">
<a-input v-model:value="inputValues.cron" @blur="onInputCronBlur">
<template #addonBefore>
<a-tooltip title="Cron表达式"></a-tooltip>
</template>
</a-input>
</a-col>
</a-row>
</a-col>
<a-col :span="6">
<div>近十次执行时间不含年</div>
<a-textarea type="textarea" :value="preTimeList" :rows="5" />
</a-col>
</a-row>
</div>
</div>
</div>
</template>

View File

@ -1,5 +1,5 @@
<template>
<BasicModal @register="registerModal" title="Cron表达式" width="800px" @ok="onOk">
<BasicModal @register="registerModal" title="Cron表达式" width="1000px" @ok="onOk">
<EasyCron v-bind="attrs" />
</BasicModal>
</template>

View File

@ -395,7 +395,14 @@
// update-end--author:liaozhiyang---date:20240809---for【TV360X-2062】下拉搜索选择第二页数据后第一次点击时(得到焦点)滚动条没复原到初始位置且数据会加载第二页数据(应该只加载第一页数据)
initDictTableData();
}
// update-end--author:liaozhiyang---date:20240709---forissues/6681】异步查询不生效
// update-begin--author:liaozhiyang---date:20240919---forTV360X-2348】得到焦点时options选项显示第一页内容解决新增时显示非第一页内容
if (Array.isArray(selectedAsyncValue.value) && selectedAsyncValue.value.length === 0 && isDictTable.value && props.async) {
if (pageNo > 2) {
options.value = [];
initDictTableData();
}
}
// update-end--author:liaozhiyang---date:20240919---for【TV360X-2348】得到焦点时options选项显示第一页内容解决新增时显示非第一页内容
attrs.onFocus?.();
};
// update-end--author:liaozhiyang---date:20240523---for【TV360X-26】下拉搜索控件选中选项后再次点击下拉应该显示初始的下拉选项而不是只展示选中结果

View File

@ -67,8 +67,10 @@ export const basicProps = {
rulesMessageJoinLabel: propTypes.bool.def(true),
// 【jeecg】超过3列自动折叠
autoAdvancedCol: propTypes.number.def(3),
// update-begin--author:liaozhiyang---date:202401009---for【issues/7261】表格上方查询项autoAdvancedLine配置没有效果删除autoAdvancedLine
// 超过3行自动折叠
autoAdvancedLine: propTypes.number.def(3),
// autoAdvancedLine: propTypes.number.def(3),
// update-end--author:liaozhiyang---date:202401009---for【issues/7261】表格上方查询项autoAdvancedLine配置没有效果删除autoAdvancedLine
// 不受折叠影响的行数
alwaysShowLines: propTypes.number.def(1),

View File

@ -99,7 +99,9 @@ export interface FormProps {
// 【jeecg】如果 showAdvancedButton 为 true超过指定列数默认折叠默认为3
autoAdvancedCol?: number;
// 如果 showAdvancedButton 为 true超过指定行数行默认折叠
autoAdvancedLine?: number;
// update-begin--author:liaozhiyang---date:202401009---for【issues/7261】表格上方查询项autoAdvancedLine配置没有效果删除autoAdvancedLine
// autoAdvancedLine?: number;
// update-end--author:liaozhiyang---date:202401009---for【issues/7261】表格上方查询项autoAdvancedLine配置没有效果删除autoAdvancedLine
// 折叠时始终保持显示的行数
alwaysShowLines?: number;
// Whether to show the operation button

View File

@ -101,11 +101,6 @@ const jeecgAreaData = new Area();
// 根据code找文本
const getAreaTextByCode = function (code) {
let index = 3;
// update-begin--author:liaozhiyang---date:20240617---for【TV360X-1210】online列表香港、澳门没翻译香港、澳门只有两级其它省份是三级
if (code && ['82', '81'].includes(code.substring(0, 2))) {
index = 2;
}
// update-end--author:liaozhiyang---date:20240617---for【TV360X-1210】online列表香港、澳门没翻译香港、澳门只有两级其它省份是三级
//update-begin-author:liusq---date:20220531--for: 判断code是否是多code逗号分割的字符串是的话获取最后一位的code ---
if (code && code.includes(',')) {
index = code.split(",").length;

View File

@ -36,8 +36,10 @@ export function handleRangeTimeValue(props, values) {
timeValue = timeValue.split(',');
}
const [startTime, endTime]: string[] = timeValue;
values[startTimeKey] = dateUtil(startTime).format(format);
values[endTimeKey] = dateUtil(endTime).format(format);
//update-begin---author:wangshuai---date:2024-10-08---for:【issues/7216】当RangePicker组件值允许开始/结束为空时,表单的fieldMapToTime处理异常---
startTime && (values[startTimeKey] = dateUtil(startTime).format(format));
endTime && (values[endTimeKey] = dateUtil(endTime).format(format));
//update-end---author:wangshuai---date:2024-10-08---for:【issues/7216】当RangePicker组件值允许开始/结束为空时,表单的fieldMapToTime处理异常---
Reflect.deleteProperty(values, field);
}
return values;

View File

@ -1,10 +1,23 @@
<template>
<a-input :disabled="disabled" :style="{ width }" readOnly :placeholder="t('component.icon.placeholder')" :class="prefixCls" v-model:value="currentSelect">
<a-input
:class="prefixCls"
:value="currentSelect"
readOnly
:disabled="disabled"
:placeholder="t('component.icon.placeholder')"
:style="{ width }"
@click="currentSelectClick"
>
<template #addonAfter>
<span class="cursor-pointer px-2 py-1 flex items-center" v-if="isSvgMode && currentSelect">
<SvgIcon :name="currentSelect" @click="currentSelectClick"/>
</span>
<Icon :icon="currentSelect || 'ion:apps-outline'" class="cursor-pointer px-2 py-1" v-else @click="currentSelectClick"/>
<Icon v-else :icon="currentSelect || 'ion:apps-outline'" :class="['px-2 py-1', {
'cursor-pointer': !disabled,
'cursor-not-allowed': disabled,
}]"
@click="currentSelectClick"
/>
</template>
</a-input>
<a-modal :bodyStyle="{ padding: '24px'}" v-bind="$attrs" v-model:open="iconOpen" :keyboard="false" :width="800" @ok="handleOk" :ok-text="t('common.okText')" :cancel-text="t('common.cancelText')">
@ -84,7 +97,7 @@
width: propTypes.string.def('100%'),
copy: propTypes.bool.def(false),
mode: propTypes.oneOf<('svg' | 'iconify')[]>(['svg', 'iconify']).def('iconify'),
disabled: propTypes.bool.def(true),
disabled: propTypes.bool.def(false),
clearSelect: propTypes.bool.def(false),
iconPrefixSave: propTypes.bool.def(true),
});
@ -149,6 +162,9 @@
* 图标点击重置页数
*/
function currentSelectClick() {
if (props.disabled) {
return
}
iconOpen.value = true;
setTimeout(()=>{
iconListRef.value.currentSelectClick();
@ -185,6 +201,12 @@
@prefix-cls: ~'@{namespace}-icon-picker';
.@{prefix-cls} {
// 输入框手势图标
.ant-input:not([disabled]) {
cursor: pointer;
}
.ant-input-group-addon {
padding: 0;
}

View File

@ -0,0 +1,76 @@
<template>
<div>
<keep-alive>
<component
v-if="currentModal"
v-bind="bindParams"
:key="currentModal"
:is="currentModal"
@register="modalRegCache[currentModal].register"
@reply="handReply"
@selected="reloadPage"
/>
</keep-alive>
<!-- 历史弹出框 -->
<HisTaskDealModal ref="taskDealRef" v-bind="bindParams" />
<!-- 系统公告弹窗 -->
<DynamicNotice ref="showDynamNotice" v-bind="bindParams" />
<!-- eoa查看详情 -->
<EoaDetailModal ref="detailRef" />
<!-- 表单设计器弹窗 -->
<DesformDataModal ref="desformRef" v-bind="bindParams" @added="handleDesformDataAdded" />
<!-- 我的计划弹窗 -->
<PlanModal ref="planRef" v-bind="bindParams" @success="reloadPage" />
</div>
</template>
<script lang="ts">
import { defineComponent, onMounted } from 'vue';
import { useDragNotice } from '/@/hooks/web/useDragNotice';
import EoaMailBoxInModal from '/@/views/super/eoa/email/components/EoaMailBoxInModal.vue';
import DynamicNotice from '@/views/monitor/mynews/DynamicNotice.vue';
import EoaDetailModal from '@/views/super/eoa/cmsoa/modules/EoaDetailModal.vue';
import PlanModal from '/@/views/super/eoa/plan/components/PlanModal.vue';
export default defineComponent({
name: 'JDragNotice',
components: {
EoaDetailModal,
DynamicNotice,
EoaMailBoxInModal,
PlanModal,
},
setup() {
const {
initDragWebSocket,
currentModal,
modalParams,
modalRegCache,
bindParams,
taskDealRef,
desformRef,
handleDesformDataAdded,
handReply,
reloadPage,
} = useDragNotice();
onMounted(() => {
initDragWebSocket();
});
return {
currentModal,
modalParams,
modalRegCache,
bindParams,
taskDealRef,
desformRef,
handleDesformDataAdded,
handReply,
reloadPage,
};
},
});
</script>
<style scoped lang="less"></style>

View File

@ -112,7 +112,10 @@
//整合warpClassName
const getWrapClassName = computed(() => {
const clsName = toRef(getMergeProps.value, 'wrapClassName').value || '';
let clsName = toRef(getMergeProps.value, 'wrapClassName').value || '';
// update-begin--author:liaozhiyang---date:20241010---for【issues/7260】原生a-modal关闭按钮位置偏移
clsName = `${clsName} jeecg-modal-code-generate`;
// update-end--author:liaozhiyang---date:20241010---for【issues/7260】原生a-modal关闭按钮位置偏移
return unref(fullScreenRef) ? `jeecg-full-screen-modal-code-generate ${clsName} ` : unref(clsName);
});
@ -324,4 +327,13 @@
}
}
/*end 全屏弹窗modal样式*/
// update-begin--author:liaozhiyang---date:20241010---for【issues/7260】原生a-modal关闭按钮位置偏移
.jeecg-modal-code-generate {
.ant-modal {
.ant-modal-close {
top: 8px;
}
}
}
// update-end--author:liaozhiyang---date:20241010---for【issues/7260】原生a-modal关闭按钮位置偏移
</style>

View File

@ -120,7 +120,9 @@
display: flex;
height: 95%;
align-items: center;
// update-begin--author:liaozhiyang---date:20241010---for【issues/7260】原生a-modal关闭按钮位置偏移
margin-top: -2px;
// update-end--author:liaozhiyang---date:20241010---for【issues/7260】原生a-modal关闭按钮位置偏移
> span {
margin-left: 48px;
font-size: 16px;

View File

@ -76,10 +76,12 @@
}
.ant-modal-close-x {
display: inline-block;
width: 96px;
height: 56px;
line-height: 56px;
// update-begin--author:liaozhiyang---date:20241010---for【issues/7260】原生a-modal关闭按钮位置偏移
// display: inline-block;
// width: 96px;
// height: 56px;
// line-height: 56px;
// update-end--author:liaozhiyang---date:20241010---for【issues/7260】原生a-modal关闭按钮位置偏移
}
.ant-modal-confirm-body {

View File

@ -48,6 +48,11 @@
const renderValue = String(value);
const wrapEl = unref(wrapRef);
// 无值不生成
if (renderValue == null || renderValue === '') {
return;
}
if (!wrapEl) return;
if (tag === 'canvas') {

View File

@ -161,11 +161,8 @@ export function useColumns(
const viewColumns = sortFixedColumn(unref(getColumnsRef));
const columns = cloneDeep(viewColumns);
const result = columns
.filter((column) => {
return hasPermission(column.auth) && isIfShow(column);
})
.map((column) => {
const formatEditColumn = (columns) => {
return columns.map((column) => {
// update-begin--author:liaozhiyang---date:20230718---for: 【issues-179】antd3 一些警告以及报错(针对表格)
if(column.slots?.customRender) {
// slots的备份兼容老的写法转成新写法避免控制台警告
@ -198,8 +195,17 @@ export function useColumns(
if ((edit || editRow) && !isDefaultAction) {
column.customRender = renderEditCell(column);
}
// update-begin--author:liaozhiyang---date:20241021---for【pull/7333】修复分组表头可编辑表格失效问题
if (column.children?.length) {
formatEditColumn(column.children.filter((item) => hasPermission(column.auth) && isIfShow(column)));
}
// update-end--author:liaozhiyang---date:20241021---for【pull/7333】修复分组表头可编辑表格失效问题
return reactive(column);
});
};
// update-begin--author:liaozhiyang---date:20241021---for【pull/7333】修复分组表头可编辑表格失效问题
const result = formatEditColumn(columns.filter((item) => hasPermission(item.auth) && isIfShow(item)));
// update-end--author:liaozhiyang---date:20241021---for【pull/7333】修复分组表头可编辑表格失效问题
// update-begin--author:liaozhiyang---date:20230919---for【QQYUN-6387】展开写法去掉报错
if (propsRef.value.expandedRowKeys && !propsRef.value.isTreeTable) {
let index = 0;

View File

@ -198,17 +198,9 @@ export function useCustomSelection(
bodyHeight.value = Math.ceil(height);
}
}
updateRowHeight();
});
bodyResizeObserver.observe(bodyEl.value);
const el = bodyEl.value?.querySelector('tbody.ant-table-tbody tr.ant-table-row') as HTMLDivElement;
if (el) {
// update-begin--author:liaozhiyang---date:20241111---for【issues/7442】basicTable从默认切换到宽松紧凑时多选框显示异常
nextTick(() => {
rowHeight.value = el.offsetHeight;
});
// update-end--author:liaozhiyang---date:20241111---for【issues/7442】basicTable从默认切换到宽松紧凑时多选框显示异常
return;
}
}
rowHeight.value = 50;
});
@ -226,6 +218,16 @@ export function useCustomSelection(
}
});
// 更新首行行高
function updateRowHeight() {
const el = bodyEl.value?.querySelector('tbody.ant-table-tbody tr.ant-table-row') as HTMLDivElement;
if (el) {
// update-begin--author:liaozhiyang---date:20241111---for【issues/7442】basicTable从默认切换到宽松紧凑时多选框显示异常
nextTick(() => rowHeight.value = el.offsetHeight);
// update-end--author:liaozhiyang---date:20241111---for【issues/7442】basicTable从默认切换到宽松紧凑时多选框显示异常
}
}
// 选择全部
function onSelectAll(checked: boolean, flag = 'currentPage') {
// update-begin--author:liaozhiyang---date:20231122---for【issues/5577】BasicTable组件全选和取消全选时不触发onSelectAll事件

View File

@ -1,5 +1,5 @@
import type { BasicTableProps, TableRowSelection, BasicColumn } from '../types/table';
import type { Ref, ComputedRef } from 'vue';
import type { Ref, ComputedRef, Slots } from 'vue';
import { computed, unref, ref, nextTick, watch } from 'vue';
import { getViewportOffset } from '/@/utils/domUtils';
import { isBoolean } from '/@/utils/is';
@ -14,7 +14,8 @@ export function useTableScroll(
tableElRef: Ref<ComponentRef>,
columnsRef: ComputedRef<BasicColumn[]>,
rowSelectionRef: ComputedRef<TableRowSelection<any> | null>,
getDataSourceRef: ComputedRef<Recordable[]>
getDataSourceRef: ComputedRef<Recordable[]>,
slots: Slots
) {
const tableHeightRef: Ref<Nullable<number>> = ref(null);
@ -175,7 +176,11 @@ export function useTableScroll(
if (len !== 0) {
width += len * NORMAL_WIDTH;
}
// update-begin--author:liaozhiyang---date:202401009---for【TV360X-116】内嵌风格字段较多时表格错位
if (slots.expandedRowRender) {
width += propsRef.value.expandColumnWidth;
}
// update-end--author:liaozhiyang---date:202401009---for【TV360X-116】内嵌风格字段较多时表格错位
const table = unref(tableElRef);
const tableWidth = table?.$el?.offsetWidth ?? 0;
return tableWidth > width ? '100%' : width;

View File

@ -108,6 +108,9 @@ export const basicProps = {
},
minHeight: propTypes.number,
maxHeight: propTypes.number,
// update-begin--author:liaozhiyang---date:202401009---for【TV360X-116】内嵌风格字段较多时表格错位
expandColumnWidth: propTypes.number.def(48),
// update-end--author:liaozhiyang---date:202401009---for【TV360X-116】内嵌风格字段较多时表格错位
// 统一设置列最大宽度
maxColumnWidth: propTypes.number,
dataSource: {

View File

@ -199,7 +199,7 @@ export interface BasicTableProps<T = any> {
// 是否显示操作列
showActionColumn?: boolean;
// 操作列配置
actionColumn?: BasicColumn;
actionColumn?: Partial<BasicColumn>;
// 文本超过宽度是否显示。。。
ellipsis?: boolean;
// 是否可以自适应高度
@ -220,6 +220,10 @@ export interface BasicTableProps<T = any> {
maxHeight?: number;
// 是否显示边框
bordered?: boolean;
// update-begin--author:liaozhiyang---date:202401009---for【TV360X-116】内嵌风格字段较多时表格错位
// 展开列宽度
expandColumnWidth: number;
// update-end--author:liaozhiyang---date:202401009---for【TV360X-116】内嵌风格字段较多时表格错位
// 分页配置
pagination?: PaginationProps | boolean;
// loading加载

View File

@ -29,5 +29,5 @@ export interface PopConfirm {
icon?: string;
placement?: string;
overlayClassName?: string;
getPopupContainer: Fn;
getPopupContainer?: Fn;
}

View File

@ -5,6 +5,7 @@
<ImgUpload
:fullscreen="fullscreen"
@uploading="handleImageUploading"
@loading="handleLoading"
@done="handleDone"
v-show="editorRef"
:disabled="disabled"
@ -13,6 +14,7 @@
<!-- update-end--author:liaozhiyang---date:20240517---forTV360X-35富文本图片上传遮挡其他按钮 -->
<Editor :id="tinymceId" ref="elRef" :disabled="disabled" :init="initOptions" :style="{ visibility: 'hidden' }" v-if="!initOptions.inline"></Editor>
<slot v-else></slot>
<ProcessMask ref="processMaskRef" :show="showUploadMask"/>
</div>
</template>
@ -33,6 +35,7 @@
import 'tinymce/plugins/image';
import { defineComponent, computed, nextTick, ref, unref, watch, onDeactivated, onBeforeUnmount, onMounted } from 'vue';
import ImgUpload from './ImgUpload.vue';
import ProcessMask from './ProcessMask.vue';
import {simpleToolbar, menubar, simplePlugins} from './tinymce';
import { buildShortUUID } from '/@/utils/uuid';
import { bindHandlers } from './helper';
@ -82,6 +85,10 @@
type: Boolean,
default: true,
},
showUploadMask: {
type: Boolean,
default: false,
},
//是否聚焦
autoFocus:{
type: Boolean,
@ -91,9 +98,9 @@
export default defineComponent({
name: 'Tinymce',
components: { ImgUpload,Editor },
components: { ImgUpload,Editor,ProcessMask },
inheritAttrs: false,
props: tinymceProps,
props: tinymceProps as any,
emits: ['change', 'update:modelValue', 'inited', 'init-error'],
setup(props, { emit, attrs }) {
console.log("---Tinymce---初始化---")
@ -103,6 +110,7 @@
const tinymceId = ref<string>(buildShortUUID('tiny-vue'));
const elRef = ref<Nullable<HTMLElement>>(null);
const editorRootRef = ref<Nullable<HTMLElement>>(null);
const processMaskRef = ref<any>(null);
const imgUploadShow = ref(false);
const targetElem = ref<null | HTMLDivElement>(null);
@ -325,6 +333,20 @@
setValue(editor, val);
}
/**
* 上传进度计算
* @param file
* @param fileList
*/
function handleLoading(fileLength,showMask){
if(fileLength && fileLength > 0){
setTimeout(() => {
props?.showUploadMask && processMaskRef.value.calcProcess(fileLength)
},100)
}else{
props?.showUploadMask && (processMaskRef.value.showMask = showMask);
}
}
function getUploadingImgName(name: string) {
return `[uploading:${name}]`;
}
@ -397,6 +419,9 @@
editorRootRef,
imgUploadShow,
targetElem,
handleLoading,
processMaskRef
};
},
});
@ -428,6 +453,7 @@
}
// update-end--author:liaozhiyang---date:20240527---for【TV360X-329】富文本禁用状态下工具栏划过边框丢失
}
html[data-theme='dark'] {
.@{prefix-cls} {
.tox .tox-edit-area__iframe {background-color: #141414;}

View File

@ -8,6 +8,7 @@
:showUploadList="false"
:data="getBizData()"
:headers="getheader()"
:before-upload="beforeUpload"
accept=".jpg,.jpeg,.gif,.png,.webp"
>
<a-button type="primary" v-bind="{ ...getButtonProps }">
@ -37,10 +38,8 @@
default: false,
},
},
emits: ['uploading', 'done', 'error'],
emits: ['uploading', 'done', 'error', 'loading'],
setup(props, { emit }) {
let uploading = false;
//update-begin-author:taoyan date:2022-5-13 for: 富文本上传图片不支持
function getheader() {
return getHeaders();
@ -67,33 +66,37 @@
};
});
let uploadLength = 0;
function handleChange({ file, fileList }) {
if (file.status === 'error') {
emit('error');
uploading = false;
// 过滤掉已经存在的文件
fileList = fileList.filter((file) => {
const existFile = uploadFileList.value.find(({ uid }) => uid === file.uid);
return existFile ? false : true;
});
uploadLength == 0 && (uploadLength = fileList.length);
if (file.status != 'uploading') {
emit('loading', uploadLength, true);
}
let files = [] as any;
let noUploadingFileCount = 0;
// 处理上传好的文件
if (file.status != 'uploading') {
fileList.forEach((file) => {
if (file.status === 'done' && file.response.success) {
files.push(file);
const name = file?.name;
let realUrl = getFileAccessHttpUrl(file.response.message);
uploadFileList.value.push(file);
emit('done', name, realUrl);
}
if (file.status != 'uploading') {
noUploadingFileCount++;
}
});
}
if (noUploadingFileCount == fileList.length) {
fileList.forEach((file) => {
const name = file?.name;
let realUrl = getFileAccessHttpUrl(file.response.message);
emit('done', name, realUrl);
});
}
}
//上传之前
function beforeUpload() {
uploadLength = 0;
emit('loading', null, true);
setTimeout(() => {
emit('loading', null, false);
}, 10000);
}
return {
prefixCls,
handleChange,
@ -102,7 +105,8 @@
getBizData,
t,
getButtonProps,
uploadFileList
uploadFileList,
beforeUpload,
};
},
});

View File

@ -0,0 +1,110 @@
<template>
<div :class="[prefixCls]" v-if="showMask && show">
<div class="progress-bar-rear">
<div class="progress-bar-front" :style="{ width: progressBarWidth }"></div>
</div>
<div class="value">{{ percentage }}</div>
</div>
</template>
<script lang="ts" setup>
import { computed, ref } from 'vue';
import {useDesign} from "@/hooks/web/useDesign";
const props = defineProps({
backColor: {
type: [String],
default: 'white',
},
processColor: {
type: String,
default: '#018FFB',
},
show: {
type: Boolean,
default: false,
},
});
const { prefixCls } = useDesign('tinymce-process-mask');
//显示遮罩
const showMask = ref(false);
//进度值占比
const progressValue = ref<any>(0);
//当前数量
const currentNum = ref(0);
// 计算进度条宽度的计算属性
const progressBarWidth = computed(() => {
return progressValue.value > 0 ? `${progressValue.value}px` : '0px';
});
// 计算进度条百分比
const percentage = computed(() => {
return `${progressValue.value}%`;
});
// 进度色
const frontColor = computed(() => {
return props.processColor;
});
// 后置背景色
const rearColor = computed(() => {
return props.backColor;
});
function calcProcess(totalNum) {
!showMask.value && (showMask.value = true);
currentNum.value += 1;
progressValue.value = ((currentNum.value / totalNum) * 100).toFixed(2);
console.log('currentNum.value', currentNum.value);
console.log('totalNum.value', totalNum);
if (currentNum.value == totalNum) {
showMask.value = false;
currentNum.value = 0;
progressValue.value = 0;
}
}
defineExpose({
calcProcess,
showMask,
});
</script>
<style lang="less">
//noinspection LessUnresolvedVariable
@prefix-cls: ~'@{namespace}-tinymce-process-mask';
.@{prefix-cls} {
& {
position: absolute; /* 或者使用固定定位等其他方式 */
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5); /* 半透明遮罩 */
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
z-index: 99;
}
.progress-bar-rear {
width: 100px; /* 进度条宽度 */
height: 10px; /* 进度条高度 */
background-color: v-bind(rearColor); /* 进度条颜色 */
border-radius: 4px;
}
.progress-bar-front {
height: 10px; /* 进度条高度 */
background-color: v-bind(frontColor); /* 进度条颜色 */
border-radius: 4px;
}
.value {
color: #fff;
margin-left: 5px;
font-size: 16px;
font-weight: 600;
}
}
</style>

View File

@ -94,4 +94,15 @@ export function definedComponent() {
// addComponent(JVxeTypes.userSelect, JVxeUserSelectCell)
}
/**
* 清空注册的组件
*/
export function clearComponent() {
componentMap.clear();
// 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 { componentMap };

View File

@ -5,15 +5,17 @@
<template #buttons>
<div :class="`${prefixCls}-button div`" :size="btnSize">
<slot v-if="showPrefix" name="toolbarPrefix" :size="btnSize" />
<a-button v-if="showAdd" type="primary" preIcon="ant-design:plus-outlined" :disabled="disabled" :loading="deleting" @click="trigger('add')">
<span>新增</span>
<a-button v-if="addBtnCfg.enabled && showAdd" type="primary" :preIcon="addBtnCfg.buttonIcon" :disabled="disabled" :loading="deleting" @click="trigger('add')">
<span>{{ addBtnCfg.buttonName }}</span>
</a-button>
<a-button v-if="showSave" preIcon="ant-design:save-outlined" :disabled="disabled" @click="trigger('save')">
<span>保存</span>
</a-button>
<template v-if="deleting || selectedRowIds.length > 0">
<Popconfirm v-if="showRemove" :title="`确定要删除这 ${selectedRowIds.length} 项吗?`" :disabled="deleting" @confirm="onRemove">
<a-button preIcon="ant-design:minus-outlined" :disabled="disabled" :loading="deleting">删除</a-button>
<Popconfirm v-if="removeBtnCfg.enabled && showRemove" :title="`确定要删除这 ${selectedRowIds.length} 项吗?`" :disabled="deleting" @confirm="onRemove">
<a-button :preIcon="removeBtnCfg.buttonIcon" :disabled="disabled" :loading="deleting">
<span>{{ removeBtnCfg.buttonName }}</span>
</a-button>
</Popconfirm>
<template v-if="showClearSelection">
<a-button preIcon="ant-design:delete-outlined" @click="trigger('clearSelection')">清空选择</a-button>
@ -46,6 +48,16 @@
disabledRows: propTypes.object,
hasBtnAuth: propTypes.func,
selectedRowIds: propTypes.array.def(() => []),
addBtnCfg: propTypes.object.def(() => ({
enabled: true,
buttonIcon: 'ant-design:plus-outlined',
buttonName: '新增',
})),
removeBtnCfg: propTypes.object.def(() => ({
enabled: true,
buttonIcon: 'ant-design:minus-outlined',
buttonName: '删除',
})),
});
const emit = defineEmits(['save', 'add', 'remove', 'clearSelection', 'register']);
const xToolbarRef = ref({} as VxeToolbarInstance);

View File

@ -10,8 +10,10 @@
<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>
<a-menu-divider />
<a-menu-item key="3" @click="handleRowInsertDown">插入一行</a-menu-item>
<template v-if="allowInsertRow">
<a-menu-divider />
<a-menu-item key="3" @click="handleRowInsertDown">插入一行</a-menu-item>
</template>
</a-menu>
</template>
</a-dropdown>
@ -48,6 +50,9 @@
const disabledMoveUp = computed(() => rowIndex.value === 0);
const disabledMoveDown = computed(() => rowIndex.value === fullDataLength.value - 1);
// 是否允许插入行
const allowInsertRow = computed(() => originColumn.value.insertRow);
/** 向上移 */
function handleRowMoveUp() {
if (!disabledMoveUp.value) {
@ -79,7 +84,8 @@
handleRowMoveUp,
handleRowMoveDown,
handleRowInsertDown,
isAllowDrag
isAllowDrag,
allowInsertRow,
};
},
// 【组件增强】注释详见JVxeComponent.Enhanced

View File

@ -30,7 +30,8 @@ export function useColumns(props: JVxeTableProps, data: JVxeDataProps, methods:
// handle 方法参数
const args: HandleArgs = { props, slots, data, methods, columns };
let seqColumn, selectionColumn, expandColumn, dragSortColumn;
props.columns.forEach((column: JVxeColumn) => {
const handleColumn = (column: JVxeColumn, container: JVxeColumn[]) => {
// 排除未授权的列 1 = 显示/隐藏; 2 = 禁用
let auth = methods.getColAuth(column.key);
if (auth?.type == '1' && !auth.isAuth) {
@ -47,6 +48,15 @@ export function useColumns(props: JVxeTableProps, data: JVxeDataProps, methods:
if (col.type === JVxeTypes.hidden) {
return handleInnerColumn(args, col, handleHiddenColumn);
}
// 处理子级列
// 判断是否是分组列,如果当前是父级,则无需处理 render
if (Array.isArray(col.children) && col.children.length > 0) {
const children: JVxeColumn[] = [];
col.children.forEach((child: JVxeColumn) => handleColumn(child, children));
col.children = children;
container.push(col);
return;
}
// 组件未注册,自动设置为 normal
if (!isRegistered(col.type)) {
col.type = JVxeTypes.normal;
@ -72,21 +82,25 @@ export function useColumns(props: JVxeTableProps, data: JVxeDataProps, methods:
};
if (col.type === JVxeTypes.rowNumber) {
seqColumn = col;
columns.push(col);
container.push(col);
} else if (col.type === JVxeTypes.rowRadio || col.type === JVxeTypes.rowCheckbox) {
selectionColumn = col;
columns.push(col);
container.push(col);
} else if (col.type === JVxeTypes.rowExpand) {
expandColumn = col;
columns.push(col);
container.push(col);
} else if (col.type === JVxeTypes.rowDragSort) {
dragSortColumn = col;
columns.push(col);
container.push(col);
} else {
col.params = column;
args.columns = container;
handlerCol(args);
}
});
}
props.columns.forEach((column: JVxeColumn) => handleColumn(column, columns));
handleInnerColumn(args, seqColumn, handleSeqColumn);
handleInnerColumn(args, selectionColumn, handleSelectionColumn);
handleInnerColumn(args, expandColumn, handleExpandColumn);
@ -250,6 +264,7 @@ function handleDragSortColumn({ props, data, col, columns, renderOptions }: Hand
align: 'center',
// update-begin--author:liaozhiyang---date:20240417---for:【QQYUN-8785】online表单列位置的id未做限制拖动其他列到id列上面同步数据库时报错
params: {
insertRow: props.insertRow,
notAllowDrag: props.notAllowDrag,
...col?.params,
},

View File

@ -16,6 +16,8 @@ export function useToolbar(props: JVxeTableProps, data: JVxeDataProps, methods:
hasBtnAuth: methods.hasBtnAuth,
selectedRowIds: data.selectedRowIds.value,
custom: props.custom,
addBtnCfg: props.addBtnCfg,
removeBtnCfg: props.removeBtnCfg,
// 新增事件
onAdd: () => {
// update-begin--author:liaozhiyang---date:20240521---for【TV360X-212】online新增字段就出校验提示

View File

@ -1,13 +1,12 @@
/* JVxeTable 行编辑 权限 */
import { usePermissionStoreWithOut } from '/@/store/modules/permission';
const permissionStore = usePermissionStoreWithOut();
/**
* JVxe 专用,获取权限
* @param prefix
*/
export function getJVxeAuths(prefix) {
const permissionStore = usePermissionStoreWithOut();
prefix = getPrefix(prefix);
let { authList, allAuthList } = permissionStore;
let authsMap = new Map<string, typeof allAuthList[0]>();

View File

@ -42,6 +42,8 @@ export const vxeProps = () => ({
rowExpand: propTypes.bool.def(false),
// 展开行配置
expandConfig: propTypes.object.def(() => ({})),
// 是否可插入行
insertRow: propTypes.bool.def(true),
// 页面是否在加载中
loading: propTypes.bool.def(false),
// 表格高度
@ -113,6 +115,11 @@ export const vxeProps = () => ({
// 不允许拖拽的行 [{'key':field,'value':value}]
notAllowDrag: propTypes.array.def(() => []),
// update-end--author:liaozhiyang---date:20240417---for:【QQYUN-8785】online表单列位置的id未做限制拖动其他列到id列上面同步数据库时报错
// 新增按钮配置
addBtnCfg: propTypes.object,
// 删除按钮配置
removeBtnCfg: propTypes.object,
});
export const vxeEmits = ['save', 'added', 'removed', 'inserted', 'dragged', 'selectRowChange', 'pageChange', 'valueChange', 'blur'];