mirror of
https://github.com/jeecgboot/JeecgBoot.git
synced 2026-05-01 14:18:07 +00:00
3.9.2 VUE打包报错 #9595
This commit is contained in:
parent
0941ed6fa1
commit
6f00250239
@ -53,7 +53,7 @@
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { useTableColumns } from '../hooks/useTableColumns';
|
||||
import { useTableColumns } from '@/views/super/online/cgform/hooks/auto/useTableColumns';
|
||||
import { createAsyncComponent } from '@/utils/factory/createAsyncComponent';
|
||||
import { useFixedHeightModal } from '../hooks/useLinkTable';
|
||||
|
||||
|
||||
@ -1,648 +0,0 @@
|
||||
import type { Ref } from 'vue';
|
||||
import type { ExtConfigType } from '../../types';
|
||||
import { HrefSlots, OnlineColumn } from '/@/components/jeecg/OnLine/types/onlineConfig';
|
||||
import { filterMultiDictObjs } from '/@/utils/dict/JDictSelectUtil';
|
||||
import { computed, defineAsyncComponent, h, reactive, ref, toRaw, unref, watch, markRaw } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { Tag as ATag } from 'ant-design-vue';
|
||||
import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
|
||||
import { getAreaTextByCodeAnyLevel } from '/@/components/Form/src/utils/Area';
|
||||
import { createImgPreview } from '@/components/Preview';
|
||||
import { importViewsFile, _eval } from '/@/utils';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import LinkTableListPiece from '../../extend/linkTable/LinkTableListPiece.vue'
|
||||
import { getToken } from "/@/utils/auth";
|
||||
import { downloadFile } from '/@/api/common/api';
|
||||
import { getWeekMonthQuarterYear, split } from '/@/utils';
|
||||
import { getItemColor } from "@/utils/dict/DictColors";
|
||||
|
||||
/**
|
||||
* 获取实际列表需要的column配置
|
||||
* @param onlineTableContext 从数据库中查出来的数据
|
||||
* @param extConfigJson 扩展配置JSON
|
||||
*/
|
||||
export function useTableColumns(onlineTableContext, extConfigJson: Ref<ExtConfigType | undefined>) {
|
||||
// 获取路由器对象 href跳转用到
|
||||
let router = useRouter();
|
||||
|
||||
// 列信息
|
||||
const columns = ref<Array<OnlineColumn>>([]);
|
||||
/**
|
||||
* 20260309
|
||||
* liaozhiyang
|
||||
* 【issues/9336】列宽拖动不了
|
||||
* */
|
||||
function applyResizableColumns(cols: OnlineColumn[]) {
|
||||
cols.forEach((column) => {
|
||||
if (!column.width) {
|
||||
if (column.fieldType === 'date' || column.fieldType === 'Date') {
|
||||
column.width = 120;
|
||||
} else if (column.fieldType === 'link_table') {
|
||||
column.width = 180;
|
||||
} else {
|
||||
column.width = 150;
|
||||
}
|
||||
}
|
||||
column.resizable = true;
|
||||
});
|
||||
}
|
||||
|
||||
// 是否有bpm_status
|
||||
//const hasBpmStatus = ref<boolean>(false)
|
||||
// 字典信息
|
||||
const dictOptionInfo = ref<any>({});
|
||||
//已选择的值
|
||||
const selectedKeys = ref<any[]>([]);
|
||||
//选择的行记录
|
||||
//const selectRows = ref<Array<any>>([]);
|
||||
// 选择列配置 --computed有问题
|
||||
const rowSelection = ref<any>(null);
|
||||
// 是否有滚动条
|
||||
let enableScrollBar = ref(true);
|
||||
// table属性scroll
|
||||
let tableScroll = computed(() => {
|
||||
if (enableScrollBar.value == true) {
|
||||
return undefined;
|
||||
} else {
|
||||
// X轴没有滚动条
|
||||
return { x: false };
|
||||
}
|
||||
});
|
||||
|
||||
//用于 online列表的 某列的点击弹窗事件-弹窗显示其他表单
|
||||
const [registerOnlineHrefModal, { openModal: openOnlineHrefModal }] = useModal();
|
||||
const hrefMainTableId = ref('')
|
||||
// 用于 online表单中 弹出别的表单
|
||||
const [registerPopModal, { openModal: openPopModal }] = useModal();
|
||||
const popTableId = ref('')
|
||||
|
||||
// 对查询列信息的请求结果 处理方法
|
||||
function handleColumnResult(result, type = 'checkbox') {
|
||||
// 字典设置
|
||||
dictOptionInfo.value = result.dictOptions;
|
||||
// rowSelection设置
|
||||
if (result.checkboxFlag == 'Y') {
|
||||
rowSelection.value = {
|
||||
selectedRowKeys: selectedKeys,
|
||||
onChange: onSelectChange,
|
||||
type,
|
||||
};
|
||||
} else {
|
||||
rowSelection.value = null;
|
||||
}
|
||||
// 是否允许滚动条
|
||||
enableScrollBar.value = result.scrollFlag == 1;
|
||||
|
||||
let dataColumns = result.columns;
|
||||
dataColumns.forEach((column) => {
|
||||
if (extConfigJson?.value?.canResizeColumn === 1) {
|
||||
// update-begin--author:liaozhiyang---date:20260309---for:【issues/9336】列宽拖动不了
|
||||
applyResizableColumns([column]);
|
||||
// update-end--author:liaozhiyang---date:20260309---for:【issues/9336】列宽拖动不了
|
||||
}
|
||||
|
||||
// update-begin--author:liaozhiyang---date:20230818---for:【QQYUN-4161】列支持固定功能
|
||||
if (column.fieldExtendJson) {
|
||||
const json = JSON.parse(column.fieldExtendJson);
|
||||
if (!!json.isFixed) {
|
||||
column.fixed = 'left';
|
||||
}
|
||||
}
|
||||
// update-end--author:liaozhiyang---date:20230818---for:【QQYUN-4161】列支持固定功能
|
||||
// update-begin--author:liaozhiyang---date:20240517---for:【TV360X-129】增加富文本控件配置href跳转
|
||||
if (column.hrefSlotName && column.scopedSlots) {
|
||||
const obj = result.fieldHrefSlots?.find((item) => item.slotName === column.hrefSlotName);
|
||||
if (obj) {
|
||||
column.fieldHref = obj;
|
||||
}
|
||||
}
|
||||
// update-end--author:liaozhiyang---date:20240517---for:【TV360X-129】增加富文本控件配置href跳转
|
||||
Object.keys(column).map((key) => {
|
||||
// 删掉空值的字段(不删除 空字符串('') 或 数字 0 )
|
||||
if (column[key] == null) {
|
||||
delete column[key];
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// href 跳转
|
||||
let fieldHrefSlots: HrefSlots[] = result.fieldHrefSlots;
|
||||
const fieldHrefSlotKeysMap = {};
|
||||
fieldHrefSlots.forEach((item) => (fieldHrefSlotKeysMap[item.slotName] = item));
|
||||
|
||||
let tableColumns: OnlineColumn[] = [];
|
||||
// 处理列中的 href 跳转和 dict 字典,使两者可以兼容存在
|
||||
tableColumns = handleColumnHrefAndDict(dataColumns, fieldHrefSlotKeysMap);
|
||||
// 是否有 bpm_status字段 如果有,列表操作按钮需要增加提交流程按钮
|
||||
bpmStatusFilter(tableColumns);
|
||||
|
||||
console.log('-----列表列配置----', tableColumns);
|
||||
// 如果是树列表 需要设置第一列字段 及 第一列align
|
||||
if (onlineTableContext.isTree() === true) {
|
||||
// 找到第一列的配置
|
||||
let firstField = result.textField;
|
||||
let index = -1;
|
||||
for (let i = 0; i < tableColumns.length; i++) {
|
||||
if (tableColumns[i].dataIndex == firstField) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (index > 0) {
|
||||
//如果是0或是-1不需要处理
|
||||
let deleteColumns = tableColumns.splice(index, 1);
|
||||
tableColumns.unshift(deleteColumns[0]);
|
||||
}
|
||||
//第一列居左
|
||||
if (tableColumns.length > 0) {
|
||||
tableColumns[0].align = 'left';
|
||||
}
|
||||
}
|
||||
columns.value = tableColumns;
|
||||
// 列发生了变化,需要重新渲染表格
|
||||
onlineTableContext.reloadTable();
|
||||
}
|
||||
|
||||
/**
|
||||
* 表格选择事件 [expose]
|
||||
* @param selectedRowKeys
|
||||
* @param selectRow
|
||||
*/
|
||||
function onSelectChange(selectedRowKeys, selectedRows) {
|
||||
selectedKeys.value = selectedRowKeys;
|
||||
onlineTableContext['selectedRows'] = toRaw(selectedRows);
|
||||
onlineTableContext['selectedRowKeys'] = toRaw(selectedRowKeys);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理列的href和字典翻译
|
||||
*/
|
||||
function handleColumnHrefAndDict(columns: OnlineColumn[], fieldHrefSlotKeysMap: {}): OnlineColumn[] {
|
||||
for (let column of columns) {
|
||||
let { customRender, hrefSlotName, fieldType } = column;
|
||||
// online 报表中类型配置为日期(yyyy-MM-dd ),但是实际展示为日期时间格式(yyyy-MM-dd HH:mm:ss) issues/3042
|
||||
if (fieldType == 'date' || fieldType == 'Date') {
|
||||
column.customRender = ({ text }) => {
|
||||
if (!text) {
|
||||
return '';
|
||||
}
|
||||
if (text.length > 10) {
|
||||
return text.substring(0, 10);
|
||||
}
|
||||
return text;
|
||||
};
|
||||
} else if (fieldType == 'link_table') {
|
||||
// 关联记录列表展示
|
||||
// update-begin--author:liaozhiyang---date:20250318---for:【issues/7930】表格列表中支持关联记录配置是否只读
|
||||
const fieldExtendJson = column.fieldExtendJson ?? '{}';
|
||||
const json = JSON.parse(fieldExtendJson);
|
||||
// update-end--author:liaozhiyang---date:20250318---for:【issues/7930】表格列表中支持关联记录配置是否只读
|
||||
column.customRender = ({ text, record }) => {
|
||||
if (!text) {
|
||||
return '';
|
||||
}
|
||||
if(onlineTableContext.isPopList===true){
|
||||
// 如果是弹窗的列表,关联记录的列只支持数据翻译,不需要跳转逻辑
|
||||
return record[column.dataIndex+"_dictText"]
|
||||
}else{
|
||||
let tempIdArray = (text+'').split(',');
|
||||
//update-begin-author:taoyan date:2023-2-15 for: QQYUN-4286【online表单】主子表开启联合查询 功能测试报错打不开
|
||||
let tempLabelArray = [];
|
||||
if(record[column.dataIndex+"_dictText"]){
|
||||
tempLabelArray = record[column.dataIndex+"_dictText"].split(',');
|
||||
}
|
||||
//update-end-author:taoyan date:2023-2-15 for: QQYUN-4286【online表单】主子表开启联合查询 功能测试报错打不开
|
||||
let renderResult:any = []
|
||||
for(let i=0;i<tempIdArray.length;i++){
|
||||
let renderObj = h(
|
||||
LinkTableListPiece,
|
||||
{
|
||||
id: tempIdArray[i],
|
||||
text: tempLabelArray[i],
|
||||
onTab:(id)=>handleClickLinkTable(id, hrefSlotName, json.isListReadOnly)
|
||||
}
|
||||
);
|
||||
renderResult.push(renderObj)
|
||||
}
|
||||
if(renderResult.length==0){
|
||||
return ''
|
||||
}
|
||||
//如果需要显示全,但是会换行:display: flex;width: 100%;flex-wrap: wrap;flex-direction: row;
|
||||
return h('div',{style:{'overflow':'hidden'}}, renderResult);
|
||||
}
|
||||
};
|
||||
} else if (fieldType === 'popup_dict') {
|
||||
// update-begin--author:liaozhiyang---date:20240402---for:【QQYUN-8833】JPopupDict的列表翻译
|
||||
column.customRender = ({ text, record }) => {
|
||||
const dict = record[column.dataIndex + '_dictText'];
|
||||
if (dict != undefined) {
|
||||
return record[column.dataIndex + '_dictText'];
|
||||
}
|
||||
return text;
|
||||
};
|
||||
// update-end--author:liaozhiyang---date:20240402---for:【QQYUN-8833】JPopupDict的列表翻译
|
||||
} else {
|
||||
if (!hrefSlotName && column.scopedSlots && column.scopedSlots.customRender) {
|
||||
//【Online报表】字典和href互斥 这里通过fieldHrefSlotKeysMap 先找到是href的列
|
||||
if (fieldHrefSlotKeysMap.hasOwnProperty(column.scopedSlots.customRender)) {
|
||||
hrefSlotName = column.scopedSlots.customRender;
|
||||
}
|
||||
}
|
||||
// 如果 customRender 有值则代表使用了字典
|
||||
// 如果 hrefSlotName 有值则代表使用了href跳转
|
||||
// 两者可以兼容。兼容的具体思路为:先获取到字典替换的值,再添加href链接跳转
|
||||
if (customRender || hrefSlotName) {
|
||||
let dictCode = customRender as string;
|
||||
let replaceFlag = '_replace_text_';
|
||||
// 自定义渲染函数的列 需要手动配置ellipsis
|
||||
column.ellipsis = true;
|
||||
column.customRender = ({ text, record }) => {
|
||||
let value = text;
|
||||
const valueSpan: any[] = [];
|
||||
const getValue = () => valueSpan.length ? valueSpan : value;
|
||||
// 如果 dictCode 有值,就进行字典转换
|
||||
if (dictCode) {
|
||||
if (dictCode.startsWith(replaceFlag)) {
|
||||
let textFieldName = dictCode.replace(replaceFlag, '');
|
||||
value = record[textFieldName];
|
||||
} else {
|
||||
const dictItems = filterMultiDictObjs(unref(dictOptionInfo)[dictCode], text);
|
||||
value = dictItems.map((item) => {
|
||||
if (item.hasColor) {
|
||||
//获取字体颜色
|
||||
const fontColor = getItemColor(item.color);
|
||||
valueSpan.push(h(ATag, {
|
||||
color: item.color,
|
||||
style: {
|
||||
'color': fontColor,
|
||||
'margin-left': '5px',
|
||||
},
|
||||
}, () => item.text))
|
||||
}
|
||||
return item.text;
|
||||
}).join(',');
|
||||
}
|
||||
}
|
||||
// 扩展参数设置列的内容长度
|
||||
if (column.showLength) {
|
||||
if (value && value.length > column.showLength) {
|
||||
value = value.substr(0, column.showLength) + '...';
|
||||
}
|
||||
}
|
||||
// 如果 hrefSlotName 有值,就生成一个 a 标签,包裹住字典替换后(或原生)的值
|
||||
if (hrefSlotName) {
|
||||
let field = fieldHrefSlotKeysMap[hrefSlotName];
|
||||
if (field) {
|
||||
return h(
|
||||
'a',
|
||||
{
|
||||
onClick: () => handleClickFieldHref(field, record),
|
||||
},
|
||||
getValue(),
|
||||
);
|
||||
}
|
||||
}
|
||||
return h('span', {}, getValue());
|
||||
};
|
||||
}
|
||||
|
||||
// 老版本叫scopedSlots 新版叫slots
|
||||
if (column.scopedSlots) {
|
||||
// slot的列 需要手动配置ellipsis
|
||||
column.ellipsis = true;
|
||||
let slots = column.scopedSlots;
|
||||
column['slots'] = slots;
|
||||
delete column.scopedSlots;
|
||||
}
|
||||
}
|
||||
}
|
||||
return columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* href 点击事件
|
||||
* @param field
|
||||
* @param record
|
||||
*/
|
||||
function handleClickFieldHref(field, record) {
|
||||
let href = field.href;
|
||||
let urlPattern = /(ht|f)tp(s?)\:\/\/[0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*(:(0-9)*)*(\/?)([a-zA-Z0-9\-\.\?\,\'\/\\\+&%\$#_]*)?/;
|
||||
let compPattern = /\.vue(\?.*)?$/;
|
||||
let jsPattern = /{{([^}]+)}}/g; // {{ xxx }}
|
||||
if (typeof href === 'string') {
|
||||
if(href.startsWith('ONLINE:')){
|
||||
// ONLINE:tableId:fieldName
|
||||
let arr = href.split(':')
|
||||
hrefMainTableId.value = arr[1];
|
||||
let fieldName = arr[2];
|
||||
openOnlineHrefModal(true, {
|
||||
isUpdate: true,
|
||||
disableSubmit: true,
|
||||
hideSub: true,
|
||||
record:{id: record[fieldName]},
|
||||
})
|
||||
}else{
|
||||
href = href.trim().replace(/\${([^}]+)?}/g, (_s1, s2) => record[s2]);
|
||||
// 执行 {{...}} JS增强语句
|
||||
if (jsPattern.test(href)) {
|
||||
href = href.replace(jsPattern, function (text, s0) {
|
||||
try {
|
||||
// 支持 {{ ACCESS_TOKEN }} 占位符
|
||||
if (s0.trim() === 'ACCESS_TOKEN') {
|
||||
return getToken()
|
||||
}
|
||||
|
||||
// update-begin--author:liaozhiyang---date:20230904---for:【QQYUN-6390】eval替换成new Function,解决build警告
|
||||
return _eval(s0);
|
||||
// update-end--author:liaozhiyang---date:20230904---for:【QQYUN-6390】eval替换成new Function,解决build警告
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
return text;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (urlPattern.test(href)) {
|
||||
window.open(href, '_blank');
|
||||
} else if (compPattern.test(href)) {
|
||||
// 处理弹框
|
||||
openHrefCompModal(href);
|
||||
} else {
|
||||
router.push(href);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 样式
|
||||
const dialogStyle = {
|
||||
top: 0,
|
||||
left: 0,
|
||||
height: '100%',
|
||||
margin: 0,
|
||||
padding: 0,
|
||||
};
|
||||
|
||||
// update-begin--author:liaozhiyang---date:20231218---for:【QQYUN-6366】升级到antd4.x
|
||||
// 弹窗属性配置
|
||||
const hrefComponent = reactive({
|
||||
model: {
|
||||
title: '',
|
||||
okText: '关闭',
|
||||
width: '100%',
|
||||
open: false,
|
||||
destroyOnClose: true,
|
||||
style: dialogStyle,
|
||||
// dialogStyle: dialogStyle,
|
||||
bodyStyle: { padding: '8px', height: 'calc(100vh - 108px)', overflow: 'auto', overflowX: 'hidden' },
|
||||
// 隐藏掉取消按钮
|
||||
cancelButtonProps: { style: { display: 'none' } },
|
||||
},
|
||||
on: {
|
||||
ok: () => (hrefComponent.model.open = false),
|
||||
cancel: () => (hrefComponent.model.open = false),
|
||||
},
|
||||
is: <any>null,
|
||||
params: {},
|
||||
});
|
||||
// update-end--author:liaozhiyang---date:20231218---for:【QQYUN-6366】升级到antd4.x
|
||||
|
||||
// 超链点击事件--> 打开一个modal窗口
|
||||
function openHrefCompModal(href) {
|
||||
// 解析 href 参数
|
||||
let index = href.indexOf('?');
|
||||
let path = href;
|
||||
if (index !== -1) {
|
||||
path = href.substring(0, index);
|
||||
let paramString = href.substring(index + 1, href.length);
|
||||
let paramArray = paramString.split('&');
|
||||
let params = {};
|
||||
paramArray.forEach((paramObject) => {
|
||||
let paramItem = paramObject.split('=');
|
||||
params[paramItem[0]] = paramItem[1];
|
||||
});
|
||||
hrefComponent.params = params;
|
||||
} else {
|
||||
hrefComponent.params = {};
|
||||
}
|
||||
// update-begin--author:liaozhiyang---date:20231218---for:【QQYUN-6366】升级到antd4.x
|
||||
hrefComponent.model.open = true;
|
||||
// update-end--author:liaozhiyang---date:20231218---for:【QQYUN-6366】升级到antd4.x
|
||||
hrefComponent.model.title = '操作';
|
||||
hrefComponent.is = markRaw(defineAsyncComponent(() => importViewsFile(path)));
|
||||
}
|
||||
|
||||
//如果是树列表 操作列只能右侧固定
|
||||
let fixedAction:any = 'right';
|
||||
if(onlineTableContext.isTree()){
|
||||
fixedAction = 'right'
|
||||
}
|
||||
const actionColumn = reactive<OnlineColumn>({
|
||||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
slots: { customRender: 'action' },
|
||||
fixed: fixedAction,
|
||||
align: 'center',
|
||||
width: 150,
|
||||
});
|
||||
|
||||
// 监听扩展参数的固定列配置,动态改变操作列的固定方式
|
||||
watch(() => extConfigJson?.value, () => {
|
||||
if (extConfigJson?.value?.tableFixedAction === 1) {
|
||||
actionColumn.fixed = extConfigJson?.value?.tableFixedActionType || 'right';
|
||||
if (onlineTableContext.isTree()) {
|
||||
actionColumn.fixed = 'right';
|
||||
}
|
||||
}
|
||||
// update-begin--author:liaozhiyang---date:20260309---for:【issues/9336】列宽拖动不了
|
||||
if (extConfigJson?.value?.canResizeColumn === 1 && columns.value.length > 0) {
|
||||
applyResizableColumns(columns.value);
|
||||
onlineTableContext.reloadTable();
|
||||
}
|
||||
// update-end--author:liaozhiyang---date:20260309---for:【issues/9336】列宽拖动不了
|
||||
});
|
||||
|
||||
// 流程按钮状态
|
||||
function bpmStatusFilter(tableColumns: OnlineColumn[]): boolean {
|
||||
let flag = false;
|
||||
for (let i = 0; i < tableColumns.length; i++) {
|
||||
let item = tableColumns[i];
|
||||
let fieldName = item.dataIndex;
|
||||
if (fieldName!.toLowerCase() == 'bpm_status') {
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
onlineTableContext['hasBpmStatus'] = flag;
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件
|
||||
* @param text
|
||||
*/
|
||||
function downloadRowFile(text, record, column, id) {
|
||||
if (!text) {
|
||||
return;
|
||||
}
|
||||
// update-begin--author:liaozhiyang---date:20240124---for:【QQYUN-8020】online 表单有多个文件走下载接口
|
||||
if (text.indexOf(',') > 0) {
|
||||
downloadFile(`/online/cgform/field/download/${id}/${record.id}/${column.dataIndex}`, `文件_${record.id}.zip`);
|
||||
} else {
|
||||
const url = getFileAccessHttpUrl(text);
|
||||
window.open(url);
|
||||
}
|
||||
// update-end--author:liaozhiyang---date:20240124---for:【QQYUN-8020】online 表单有多个文件走下载接口
|
||||
}
|
||||
|
||||
/**
|
||||
* 图片
|
||||
* @param text
|
||||
*/
|
||||
function getImgView(text) {
|
||||
if (text && text.indexOf(',') > 0) {
|
||||
// update-begin--author:liaozhiyang---date:20250325---for:【issues/7990】图片参数中包含逗号会错误的识别成多张图
|
||||
text = split(text)[0];
|
||||
// update-end--author:liaozhiyang---date:20250325---for:【issues/7990】图片参数中包含逗号会错误的识别成多张图
|
||||
}
|
||||
return getFileAccessHttpUrl(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据编码获取省市区文本
|
||||
* @param code
|
||||
*/
|
||||
function getPcaText(code, column) {
|
||||
if (!code) {
|
||||
return '';
|
||||
}
|
||||
// update-begin--author:liaozhiyang---date:20260204---for:【QQYUN-14694】online支持配置独立的省、市、县
|
||||
let includeParent = true;
|
||||
let fieldExtendJson = column?.fieldExtendJson;
|
||||
let level = 3;
|
||||
if (fieldExtendJson) {
|
||||
fieldExtendJson = JSON.parse(fieldExtendJson);
|
||||
if (['province', 'city', 'region'].includes(fieldExtendJson.displayLevel)) {
|
||||
if (fieldExtendJson.displayLevel === 'province') {
|
||||
level = 1;
|
||||
} else if (fieldExtendJson.displayLevel === 'city') {
|
||||
level = 2;
|
||||
} else if (fieldExtendJson.displayLevel === 'region') {
|
||||
level = 3;
|
||||
}
|
||||
includeParent = false;
|
||||
}
|
||||
}
|
||||
return getAreaTextByCodeAnyLevel(code, includeParent, level as 1 | 2 | 3);
|
||||
// update-end--author:liaozhiyang---date:20260204---for:【QQYUN-14694】online支持配置独立的省、市、县
|
||||
}
|
||||
|
||||
/**
|
||||
* 日期格式化
|
||||
* @param text
|
||||
*/
|
||||
function getFormatDate(text, column) {
|
||||
if (!text) {
|
||||
return '';
|
||||
}
|
||||
let a = text;
|
||||
if (a.length > 10) {
|
||||
a = a.substring(0, 10);
|
||||
}
|
||||
// update-begin--author:liaozhiyang---date:20240430---for:【issues/6094】online 日期(年月日)控件增加年、年月,年周,年季度等格式
|
||||
let fieldExtendJson = column?.fieldExtendJson;
|
||||
if (fieldExtendJson) {
|
||||
fieldExtendJson = JSON.parse(fieldExtendJson);
|
||||
if (fieldExtendJson.picker && fieldExtendJson.picker != 'default') {
|
||||
const result = getWeekMonthQuarterYear(a);
|
||||
return result[fieldExtendJson.picker];
|
||||
}
|
||||
}
|
||||
// update-end--author:liaozhiyang---date:20240430---for:【issues/6094】online 日期(年月日)控件增加年、年月,年周,年季度等格式
|
||||
return a;
|
||||
}
|
||||
|
||||
watch(selectedKeys, () => {
|
||||
onlineTableContext['selectedRowKeys'] = toRaw(selectedKeys.value);
|
||||
});
|
||||
|
||||
onlineTableContext['clearSelectedRow'] = () => {
|
||||
selectedKeys.value = [];
|
||||
onlineTableContext['selectedRows'] = [];
|
||||
onlineTableContext['selectedRowKeys'] = [];
|
||||
};
|
||||
|
||||
/**
|
||||
* 预览列表 cell 图片
|
||||
* @param text
|
||||
*/
|
||||
function viewOnlineCellImage(text) {
|
||||
if (text) {
|
||||
let imgList: any = [];
|
||||
// update-begin--author:liaozhiyang---date:20250325---for:【issues/7990】图片参数中包含逗号会错误的识别成多张图
|
||||
const arr = split(text);
|
||||
// update-end--author:liaozhiyang---date:20250325---for:【issues/7990】图片参数中包含逗号会错误的识别成多张图
|
||||
for (let str of arr) {
|
||||
if (str) {
|
||||
imgList.push(getFileAccessHttpUrl(str));
|
||||
}
|
||||
}
|
||||
createImgPreview({ imageList: imgList });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* link table控件在列表上显示 支持点击跳转表单
|
||||
* @param id
|
||||
* @param hrefTableName
|
||||
*/
|
||||
const onlinePopModalRef = ref();
|
||||
async function handleClickLinkTable(id, hrefTableName, isListReadOnly){
|
||||
popTableId.value = hrefTableName;
|
||||
let formStatus = await onlinePopModalRef.value.getFormStatus();
|
||||
// 判断当前表单是否支持编辑,不能编辑跳详情表单
|
||||
if(formStatus==true){
|
||||
hrefMainTableId.value = hrefTableName;
|
||||
openOnlineHrefModal(true, {
|
||||
isUpdate: true,
|
||||
disableSubmit: true,
|
||||
hideSub: true,
|
||||
record:{id: id},
|
||||
})
|
||||
}else{
|
||||
openPopModal(true, {
|
||||
isUpdate: true,
|
||||
// update-begin--author:liaozhiyang---date:20250318---for:【issues/7930】表格列表中支持关联记录配置是否只读
|
||||
disableSubmit: isListReadOnly ? true : false,
|
||||
// update-end--author:liaozhiyang---date:20250318---for:【issues/7930】表格列表中支持关联记录配置是否只读
|
||||
record: {
|
||||
id: id
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
columns,
|
||||
actionColumn,
|
||||
selectedKeys,
|
||||
rowSelection,
|
||||
enableScrollBar,
|
||||
tableScroll,
|
||||
downloadRowFile,
|
||||
getImgView,
|
||||
getPcaText,
|
||||
getFormatDate,
|
||||
handleColumnResult,
|
||||
onSelectChange,
|
||||
hrefComponent,
|
||||
viewOnlineCellImage,
|
||||
hrefMainTableId,
|
||||
registerOnlineHrefModal,
|
||||
registerPopModal,
|
||||
openPopModal,
|
||||
openOnlineHrefModal,
|
||||
onlinePopModalRef,
|
||||
popTableId,
|
||||
handleClickFieldHref,
|
||||
};
|
||||
}
|
||||
@ -1,187 +0,0 @@
|
||||
<template>
|
||||
<div class="cust-onl-form">
|
||||
<a-spin :spinning="spinLoading">
|
||||
<online-form
|
||||
ref="onlineFormCompRef"
|
||||
:id="formId"
|
||||
:disabled="disabled"
|
||||
:form-template="formTemplate"
|
||||
:isTree="isTreeForm"
|
||||
:pidField="pidFieldName"
|
||||
:taskId="taskId"
|
||||
@rendered="renderSuccess"
|
||||
@success="handleSuccess"
|
||||
@validate="validateBack"
|
||||
@close="handleClose"
|
||||
>
|
||||
<template #bottom>
|
||||
<div style="width: 100%; text-align: center; margin-top: 5px" v-if="!disabled && !spinLoading && showSubmitButton">
|
||||
<a-button preIcon="ant-design:check" style="width: 126px" type="primary" @click="handleSubmit" :loading="buttonLoading"> 提 交 </a-button>
|
||||
</div>
|
||||
<!-- 任务办理意见 -->
|
||||
<TaskOpinionList class="task-opinion" :taskId="taskOriginalId" :procInsId="procInsId" :processTabType="processTabType" />
|
||||
</template>
|
||||
</online-form>
|
||||
</a-spin>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* 工作流online表单调--中转的意义在于在此查询表单信息
|
||||
*/
|
||||
import OnlineForm from './OnlineForm.vue';
|
||||
import { defineComponent, ref, watch, nextTick, computed } from 'vue';
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { getRefPromise } from '../../hooks/auto/useAutoForm';
|
||||
import TaskOpinionList from "@/views/super/online/cgform/auto/comp/TaskOpinionList.vue";
|
||||
import {useGlobSetting} from "@/hooks/setting";
|
||||
|
||||
export default defineComponent({
|
||||
name: 'ProcessOnlineForm',
|
||||
inheritAttrs: false,
|
||||
components: {
|
||||
TaskOpinionList,
|
||||
OnlineForm,
|
||||
},
|
||||
props: {
|
||||
dataId: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
tableName: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
taskId: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
taskOriginalId: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
procInsId: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
processTabType: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
emits: ['success','validate'],
|
||||
setup(props, { emit }) {
|
||||
const onlineFormCompRef = ref();
|
||||
const formId = ref('');
|
||||
const formTemplate = ref(1);
|
||||
const isTreeForm = ref(false);
|
||||
const pidFieldName = ref('');
|
||||
const spinLoading = ref(false);
|
||||
|
||||
//监听表名改变 重新加载表单
|
||||
watch(
|
||||
() => props.tableName,
|
||||
(val) => {
|
||||
if (!val) {
|
||||
return;
|
||||
}
|
||||
loadFormItems();
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
//update-begin-author:liusq---date:2026-01-20--for: 增加判断,新弹窗online表单不显示提交按钮
|
||||
const showSubmitButton = computed(() => {
|
||||
return !useGlobSetting().useNewTaskModal;
|
||||
});
|
||||
//update-end-author:liusq---date:2026-01-20--for: 增加判断,新弹窗online表单不显示提交按钮
|
||||
//加载表单
|
||||
async function loadFormItems() {
|
||||
spinLoading.value = true;
|
||||
const url = `/online/cgform/api/getFormItemBytbname/${props.tableName}`;
|
||||
const params = { taskId: props.taskId };
|
||||
try {
|
||||
let result = await defHttp.get({ url, params });
|
||||
console.log('动态表单查询结果是:', result);
|
||||
formId.value = result.head.id;
|
||||
formTemplate.value = Number(result.head.formTemplate || 1);
|
||||
isTreeForm.value = result.head.isTree === 'Y';
|
||||
pidFieldName.value = result.head.treeParentIdField || '';
|
||||
await nextTick(async () => {
|
||||
let myForm = await getRefPromise(onlineFormCompRef);
|
||||
myForm.createRootProperties(result);
|
||||
});
|
||||
} catch (e) {
|
||||
console.error('流程表单查询异常', e);
|
||||
}
|
||||
}
|
||||
|
||||
//渲染完成 装载数据
|
||||
async function renderSuccess() {
|
||||
let myForm = await getRefPromise(onlineFormCompRef);
|
||||
spinLoading.value = false;
|
||||
myForm.show(true, {
|
||||
id: props.dataId,
|
||||
});
|
||||
}
|
||||
|
||||
//表单提交
|
||||
const buttonLoading = ref(false);
|
||||
async function handleSubmit(showTip = true) {
|
||||
buttonLoading.value = true;
|
||||
onlineFormCompRef.value.handleSubmit(showTip);
|
||||
}
|
||||
function handleSuccess(data = null) {
|
||||
buttonLoading.value = false;
|
||||
emit('success', data);
|
||||
}
|
||||
//表单校验
|
||||
function handleValidate() {
|
||||
onlineFormCompRef.value.handleValidate();
|
||||
}
|
||||
//表单校验失败
|
||||
function validateBack(data = null) {
|
||||
emit('validate', data);
|
||||
}
|
||||
function handleClose() {
|
||||
buttonLoading.value = false;
|
||||
}
|
||||
|
||||
return {
|
||||
onlineFormCompRef,
|
||||
formId,
|
||||
formTemplate,
|
||||
isTreeForm,
|
||||
pidFieldName,
|
||||
renderSuccess,
|
||||
handleSuccess,
|
||||
handleClose,
|
||||
handleSubmit,
|
||||
handleValidate,
|
||||
validateBack,
|
||||
buttonLoading,
|
||||
spinLoading,
|
||||
showSubmitButton,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.cust-onl-form .ant-input-disabled {
|
||||
background-color: #fff;
|
||||
color: #000;
|
||||
}
|
||||
.cust-onl-form .ant-select-disabled .ant-select-selection {
|
||||
background: #fff;
|
||||
color: #000;
|
||||
}
|
||||
.cust-onl-form .ant-input-number-disabled {
|
||||
background-color: #fff;
|
||||
color: #000;
|
||||
}
|
||||
</style>
|
||||
@ -1,177 +0,0 @@
|
||||
<template>
|
||||
<!-- 意见区域 -->
|
||||
<div class="opinion-area" v-if="opinionPrint">
|
||||
<!-- 标题头 -->
|
||||
<div class="opinion-header">
|
||||
<h3>审批意见</h3>
|
||||
<div class="header-line"></div>
|
||||
</div>
|
||||
|
||||
<!-- 意见列表 -->
|
||||
<div class="opinion-list">
|
||||
<a-list itemLayout="vertical" :split="false">
|
||||
<template v-for="(item, index) in bpmLogList" :key="index">
|
||||
<a-list-item class="opinion-item">
|
||||
<a-list-item-meta :description="item.remarks">
|
||||
<template #title>
|
||||
<div class="opinion-meta">
|
||||
<span class="user-name">{{ item.opUserName }}</span>
|
||||
<span class="task-tag">[{{ item.taskName }}]</span>
|
||||
<span class="op-time">{{ formatTime(item.opTime) }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</a-list-item-meta>
|
||||
</a-list-item>
|
||||
</template>
|
||||
</a-list>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
// 监听流程流转信息
|
||||
import {inject, ref, watchEffect} from 'vue';
|
||||
import { taskTransInfo } from '@/views/super/bpm/process/personalOffice/myHandleTask/task.handle.api';
|
||||
import dayjs from 'dayjs';
|
||||
// 参数
|
||||
const props = defineProps({
|
||||
taskId: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
procInsId: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
processTabType: {
|
||||
type: String,
|
||||
default: '',
|
||||
}
|
||||
});
|
||||
|
||||
const opinionPrint = inject('opinionPrint');
|
||||
// 审批记录/意见信息
|
||||
const bpmLogList = ref([]);
|
||||
|
||||
// 监听流程流转信息
|
||||
watchEffect(() => {
|
||||
props.procInsId && getTaskTransInfo();
|
||||
});
|
||||
// 获取流程流转信息
|
||||
async function getTaskTransInfo() {
|
||||
let taskType = props.processTabType || 'history';
|
||||
//查询条件-run只需要taskId, history只需要procInstId
|
||||
let params = { taskId: props.taskId, procInstId: props.procInsId };
|
||||
let data = await taskTransInfo(params, taskType);
|
||||
bpmLogList.value = data.bpmLogList;
|
||||
}
|
||||
// 时间格式化
|
||||
function formatTime(time) {
|
||||
if (!time) return '';
|
||||
return dayjs(time).format('YYYY-MM-DD HH:mm');
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
/* 意见区域整体样式 */
|
||||
.opinion-area {
|
||||
margin-top: 24px;
|
||||
margin-bottom: 24px;
|
||||
padding: 16px;
|
||||
background-color: #f9f9f9;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* 标题头样式 */
|
||||
.opinion-header {
|
||||
margin-bottom: 16px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.opinion-header h3 {
|
||||
color: #333;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.header-line {
|
||||
height: 2px;
|
||||
background: linear-gradient(to right, #1890ff, transparent);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* 意见列表样式 */
|
||||
.opinion-list {
|
||||
overflow-y: auto;
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
/* 单个意见项样式 */
|
||||
.opinion-item {
|
||||
padding: 12px 16px;
|
||||
margin-bottom: 12px;
|
||||
background-color: #fff;
|
||||
border-radius: 6px;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.opinion-item:hover {
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
/* 用户信息样式 */
|
||||
.opinion-meta {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.task-tag {
|
||||
color: #ff6d75;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.op-time {
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/* 意见内容样式 */
|
||||
:deep(.ant-list-item-meta-description) {
|
||||
padding-left: 42px;
|
||||
color: #555;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
@media print {
|
||||
body * {
|
||||
visibility: hidden;
|
||||
}
|
||||
.daily-opinion,
|
||||
.daily-opinion * {
|
||||
visibility: visible;
|
||||
}
|
||||
.daily-opinion {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
table {
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
ul,
|
||||
ol {
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
</style>
|
||||
Loading…
x
Reference in New Issue
Block a user