Compare commits
21 Commits
109d7fbdf3
...
8248c5b51b
| Author | SHA1 | Date |
|---|---|---|
|
|
8248c5b51b | |
|
|
c7dddbd5be | |
|
|
7211095458 | |
|
|
562b5a8733 | |
|
|
859d586b29 | |
|
|
bfa1c35647 | |
|
|
843acc3415 | |
|
|
37f22d3544 | |
|
|
9d56205714 | |
|
|
2e377e4991 | |
|
|
19d1bff08f | |
|
|
345feabcbb | |
|
|
bebef7ed4c | |
|
|
0665363eb9 | |
|
|
b4c2219682 | |
|
|
880c5a49bc | |
|
|
249319edc9 | |
|
|
1c450a231e | |
|
|
daf515cd63 | |
|
|
0abdaf9bf9 | |
|
|
ae4477e596 |
|
|
@ -7,9 +7,9 @@ VITE_PUBLIC_PATH = /
|
|||
# Basic interface address SPA
|
||||
#VITE_GLOB_API_URL=/basic-api
|
||||
#财源
|
||||
VITE_GLOB_API_URL=http://192.168.10.102:9500
|
||||
# VITE_GLOB_API_URL=http://192.168.10.102:9500
|
||||
#基础框架
|
||||
#VITE_GLOB_API_URL=http://192.168.10.102:9023
|
||||
VITE_GLOB_API_URL=http://192.168.10.102:9023
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@ VITE_BUILD_COMPRESS = 'none'
|
|||
|
||||
# Basic interface address SPA
|
||||
#财源
|
||||
VITE_GLOB_API_URL=http://192.168.10.102:9500
|
||||
#VITE_GLOB_API_URL=http://192.168.10.102:9500
|
||||
#基础框架
|
||||
#VITE_GLOB_API_URL=http://192.168.10.102:9023
|
||||
VITE_GLOB_API_URL=http://192.168.10.102:9023
|
||||
|
||||
# File upload address, optional
|
||||
# It can be forwarded by nginx or write the actual address directly
|
||||
|
|
|
|||
|
|
@ -102,7 +102,10 @@
|
|||
"mapbox-gl-utils": "^0.44.0",
|
||||
"@mapbox/mapbox-gl-draw": "^1.4.1",
|
||||
"mapbox-gl-draw-snap-mode": "^0.2.0",
|
||||
"mapbox-extensions":"^1.3.38",
|
||||
"terraformer-wkt-parser": "^1.2.1",
|
||||
"ceel-json-editor":"^0.0.3",
|
||||
"@originjs/vite-plugin-commonjs":"^1.0.3",
|
||||
"mars3d": "^3.7.0",
|
||||
"mars3d-cesium": "^1.113.0",
|
||||
"min-dash": "^4.2.1",
|
||||
|
|
|
|||
|
|
@ -22,3 +22,14 @@ export function uploadApi(
|
|||
params,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
export function fileUploadApi(params: UploadFileParams,url:string,onUploadProgress: (progressEvent: AxiosProgressEvent) => void,) {
|
||||
return defHttp.uploadFile<UploadApiResult>(
|
||||
{
|
||||
url: url,
|
||||
onUploadProgress,
|
||||
},
|
||||
params,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,8 @@ import ApiTree from './components/ApiTree.vue';
|
|||
import ApiTreeSelect from './components/ApiTreeSelect.vue';
|
||||
import ApiCascader from './components/ApiCascader.vue';
|
||||
import ApiTransfer from './components/ApiTransfer.vue';
|
||||
import { BasicUpload, ImageUpload } from '@/components/Upload';
|
||||
import { BasicUpload, ImageUpload,VideoUpload,FileUpload } from '@/components/Upload';
|
||||
import {Location } from '@/components/Map'
|
||||
import { StrengthMeter } from '@/components/StrengthMeter';
|
||||
import { IconPicker } from '@/components/Icon';
|
||||
import { CountdownInput } from '@/components/CountDown';
|
||||
|
|
@ -45,6 +46,9 @@ componentMap.set('InputTextArea', Input.TextArea);
|
|||
componentMap.set('InputNumber', InputNumber);
|
||||
componentMap.set('AutoComplete', AutoComplete);
|
||||
componentMap.set('ImageUpload', ImageUpload);
|
||||
componentMap.set("VideoUpload",VideoUpload);
|
||||
componentMap.set("FileUpload",FileUpload);
|
||||
componentMap.set("Location",Location);
|
||||
componentMap.set('Select', Select);
|
||||
componentMap.set('ApiSelect', ApiSelect);
|
||||
componentMap.set('ApiTree', ApiTree);
|
||||
|
|
|
|||
|
|
@ -111,7 +111,16 @@
|
|||
|
||||
const keyValue = ref('');
|
||||
const FieldsValue = ref({});
|
||||
const [registerForm, { getFieldsValue, setFieldsValue, updateSchema, resetFields, validate }] =
|
||||
useForm({
|
||||
labelWidth: 100,
|
||||
schemas: formColumns,
|
||||
showActionButtonGroup: false,
|
||||
baseColProps: { lg: 24, md: 24 },
|
||||
});
|
||||
async function getFormHistory() {
|
||||
console.log('getFormHistory');
|
||||
|
||||
const data = await LoadFormScheme({
|
||||
schemeId: props.formVerison,
|
||||
});
|
||||
|
|
@ -119,12 +128,15 @@
|
|||
const scheme = JSON.parse(data.scheme);
|
||||
console.log(scheme);
|
||||
console.log(props.formConfig);
|
||||
console.log("subTableColumns",subTableColumns)
|
||||
subTableDB.value = scheme.db;
|
||||
let disDetail = false;
|
||||
scheme.formInfo.tabList.forEach((tabElement, index) => {
|
||||
tabElement.schemas.forEach((element) => {
|
||||
if (element.field == props.formRelationId) {
|
||||
keyValue.value = element.componentProps.fieldName;
|
||||
getFormDetail();
|
||||
disDetail = true;
|
||||
}
|
||||
//流程设置的表单显示和编辑与表单做关联
|
||||
props.formConfig.forEach((configElement) => {
|
||||
|
|
@ -211,11 +223,22 @@
|
|||
}
|
||||
});
|
||||
formModalVisible.value = true;
|
||||
resetFields();
|
||||
setTimeout(() => {
|
||||
resetFields();
|
||||
console.log(props.flowFormData);
|
||||
if (!disDetail) {
|
||||
console.log('赋值赋值');
|
||||
if (props.flowFormData) {
|
||||
setFieldsValue(props.flowFormData);
|
||||
}
|
||||
}
|
||||
}, 10);
|
||||
scrollValue.value = { x: (subTableColumns.value.length - 1) * 140, y: 400 };
|
||||
}
|
||||
}
|
||||
async function tabsChange(e) {
|
||||
console.log('tabsChange');
|
||||
|
||||
formColumns.forEach((element) => {
|
||||
element.show = false;
|
||||
if (element.parentValue == e) {
|
||||
|
|
@ -225,7 +248,6 @@
|
|||
// 切换时保存值
|
||||
const values = await validate();
|
||||
console.log(values);
|
||||
console.log(Object.keys(FieldsValue.value));
|
||||
if (Object.keys(FieldsValue.value).length == 0) {
|
||||
FieldsValue.value = values;
|
||||
}
|
||||
|
|
@ -245,14 +267,9 @@
|
|||
});
|
||||
console.log(FieldsValue.value);
|
||||
}
|
||||
const [registerForm, { getFieldsValue, setFieldsValue, updateSchema, resetFields, validate }] =
|
||||
useForm({
|
||||
labelWidth: 100,
|
||||
schemas: formColumns,
|
||||
showActionButtonGroup: false,
|
||||
baseColProps: { lg: 24, md: 24 },
|
||||
});
|
||||
|
||||
async function getFormDetail() {
|
||||
console.log('getFormDetail');
|
||||
var instance = JSON.parse(props.instanceInfo);
|
||||
const querys = {
|
||||
id: props.formVerison,
|
||||
|
|
@ -281,28 +298,18 @@
|
|||
}
|
||||
async function getForm() {
|
||||
try {
|
||||
console.log(getFieldsValue());
|
||||
const values = await validate();
|
||||
console.log(values);
|
||||
console.log(FieldsValue.value);
|
||||
for (const key in values) {
|
||||
for (const fieKey in FieldsValue.value) {
|
||||
if (key == fieKey) {
|
||||
if (values[key] != undefined) {
|
||||
FieldsValue.value[key] = values[key];
|
||||
values[key] = FieldsValue.value[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log(values);
|
||||
console.log(FieldsValue.value);
|
||||
let saveSubTableList = [];
|
||||
let query;
|
||||
if (Object.keys(FieldsValue.value).length == 0) {
|
||||
query = values;
|
||||
} else {
|
||||
query = FieldsValue.value;
|
||||
}
|
||||
let query = values;
|
||||
console.log(query);
|
||||
subTableList.value.forEach((item) => {
|
||||
let emptyObj = {};
|
||||
|
|
@ -325,12 +332,11 @@
|
|||
getForm,
|
||||
});
|
||||
onMounted(() => {
|
||||
if (props.flowFormData) {
|
||||
FieldsValue.value = props.flowFormData;
|
||||
}
|
||||
if (props.formVerison) {
|
||||
getFormHistory();
|
||||
} else {
|
||||
setFieldsValue({
|
||||
...props.flowFormData,
|
||||
});
|
||||
}
|
||||
});
|
||||
const addListItem = () => {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
import { withInstall } from '@/utils';
|
||||
import getLocation from './src/components/Location.vue'
|
||||
|
||||
export const Location = withInstall(getLocation);
|
||||
|
|
@ -0,0 +1,287 @@
|
|||
<template>
|
||||
<div>
|
||||
|
||||
<div class="mapContainer" :id="'mapContainer'+mapRandom">
|
||||
<div class="refresh-button">
|
||||
<ReloadOutlined @click="onrefresh"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import mapboxgl, { Map, Popup } from 'mapbox-gl';
|
||||
import { ref, toRefs, watch,onMounted } from 'vue';
|
||||
import { ReloadOutlined } from '@ant-design/icons-vue';
|
||||
import type { UploadFile, UploadProps } from 'ant-design-vue';
|
||||
import { Modal, Upload } from 'ant-design-vue';
|
||||
import { on } from '@/utils/domUtils';
|
||||
import { UploadRequestOption } from 'ant-design-vue/lib/vc-upload/interface';
|
||||
import { useMessage } from '@/hooks/web/useMessage';
|
||||
import { isArray, isFunction, isObject, isString } from '@/utils/is';
|
||||
import { warn } from '@/utils/log';
|
||||
import { useI18n } from '@/hooks/web/useI18n';
|
||||
import { useUploadType } from '../hooks/useUpload';
|
||||
import { uploadContainerProps } from '../props';
|
||||
import { isImgTypeByName } from '../helper';
|
||||
import { UploadResultStatus } from '@/components/Upload/src/types/typing';
|
||||
import { parse } from 'path';
|
||||
|
||||
defineOptions({ name: 'ImageUpload' });
|
||||
const mapRandom = ref(parseInt(Math.random()*100000).toString())
|
||||
|
||||
const emit = defineEmits(['change', 'update:value', 'delete']);
|
||||
const props = defineProps({
|
||||
...uploadContainerProps,
|
||||
});
|
||||
const { t } = useI18n();
|
||||
const { createMessage } = useMessage();
|
||||
const { accept, helpText, maxNumber, maxSize } = toRefs(props);
|
||||
const isInnerOperate = ref<boolean>(false);
|
||||
const { getStringAccept } = useUploadType({
|
||||
acceptRef: accept,
|
||||
helpTextRef: helpText,
|
||||
maxNumberRef: maxNumber,
|
||||
maxSizeRef: maxSize,
|
||||
});
|
||||
const previewOpen = ref<boolean>(false);
|
||||
const previewImage = ref<string>('');
|
||||
const previewTitle = ref<string>('');
|
||||
|
||||
const fileList = ref<UploadProps['fileList']>([]);
|
||||
const isLtMsg = ref<boolean>(true);
|
||||
const isActMsg = ref<boolean>(true);
|
||||
|
||||
let map:Map;
|
||||
|
||||
onMounted(() => {
|
||||
mapboxgl.accessToken = "pk.eyJ1Ijoic2hpY2hhbzEyMyIsImEiOiJja3FobnI1aDEwNGF6Mm9vOXVhNnBzZmFhIn0.2fZKiMqCQHxVY74QShMEGQ"
|
||||
map = initMap();
|
||||
map.on("load",function(){
|
||||
refreshLocation();
|
||||
})
|
||||
})
|
||||
|
||||
watch(
|
||||
() => props.value,
|
||||
(v) => {
|
||||
if (isInnerOperate.value) {
|
||||
isInnerOperate.value = false;
|
||||
return;
|
||||
}
|
||||
if (v) {
|
||||
let value: string[] = [];
|
||||
if (isArray(v)) {
|
||||
value = v;
|
||||
} else {
|
||||
value.push(v);
|
||||
}
|
||||
fileList.value = value.map((item, i) => {
|
||||
if (item && isString(item)) {
|
||||
return {
|
||||
uid: -i + '',
|
||||
name: item.substring(item.lastIndexOf('/') + 1),
|
||||
status: 'done',
|
||||
url: item,
|
||||
};
|
||||
} else if (item && isObject(item)) {
|
||||
return item;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}) as UploadProps['fileList'];
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const initMap = () => {
|
||||
return new mapboxgl.Map({
|
||||
container: 'mapContainer'+mapRandom.value,
|
||||
language: 'zh-cmn',
|
||||
projection: 'equirectangular', // wgs84参考系
|
||||
style: {
|
||||
glyphs: 'mapbox://fonts/mapbox/{fontstack}/{range}.pbf',
|
||||
version: 8,
|
||||
sources: {
|
||||
'raster-tiles': {
|
||||
type: 'raster',
|
||||
tiles: [
|
||||
`https://t0.tianditu.gov.cn/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=b6585bc41ee16251dbe6b1af64f375d9`,
|
||||
],
|
||||
tileSize: 256,
|
||||
},
|
||||
},
|
||||
layers: [
|
||||
{
|
||||
id: 'tdt-img-tiles',
|
||||
type: 'raster',
|
||||
source: 'raster-tiles',
|
||||
minzoom: 0,
|
||||
maxzoom: 18,
|
||||
},
|
||||
],
|
||||
},
|
||||
maxZoom: 22,
|
||||
minZoom: 6,
|
||||
zoom: 15,
|
||||
center: [118.298906,35.135013],
|
||||
});
|
||||
};
|
||||
|
||||
const refreshLocation = () => {
|
||||
map.addSource('points', {
|
||||
'type': 'geojson',
|
||||
'data': {
|
||||
'type': 'FeatureCollection',
|
||||
'features': [
|
||||
{
|
||||
'type': 'Feature',
|
||||
'properties': {},
|
||||
'geometry': {
|
||||
'type': 'Point',
|
||||
'coordinates': [118.298906,35.135013]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
// Add a circle layer
|
||||
map.addLayer({
|
||||
'id': 'circle',
|
||||
'type': 'circle',
|
||||
'source': 'points',
|
||||
'paint': {
|
||||
'circle-color': '#409EFF',
|
||||
'circle-radius': 6,
|
||||
'circle-stroke-width': 3,
|
||||
'circle-stroke-color': '#ffffff'
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const onrefresh = () => {
|
||||
createMessage.success(t('component.map.refreshSuccess'));
|
||||
}
|
||||
|
||||
function getBase64<T extends string | ArrayBuffer | null>(file: File) {
|
||||
return new Promise<T>((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
reader.readAsDataURL(file);
|
||||
reader.onload = () => {
|
||||
resolve(reader.result as T);
|
||||
};
|
||||
reader.onerror = (error) => reject(error);
|
||||
});
|
||||
}
|
||||
|
||||
const handlePreview = async (file: UploadFile) => {
|
||||
console.log("fileEEEEE",file);
|
||||
if (!file.url && !file.preview) {
|
||||
file.preview = await getBase64<string>(file.originFileObj!);
|
||||
}
|
||||
previewImage.value = file.url || file.preview || '';
|
||||
previewOpen.value = true;
|
||||
previewTitle.value =
|
||||
file.name || previewImage.value.substring(previewImage.value.lastIndexOf('/') + 1);
|
||||
};
|
||||
|
||||
const handleRemove = async (file: UploadFile) => {
|
||||
if (fileList.value) {
|
||||
const index = fileList.value.findIndex((item) => item.uid === file.uid);
|
||||
index !== -1 && fileList.value.splice(index, 1);
|
||||
const value = getValue();
|
||||
isInnerOperate.value = true;
|
||||
emit('change', value);
|
||||
emit('delete', file);
|
||||
}
|
||||
};
|
||||
|
||||
const handleCancel = () => {
|
||||
previewOpen.value = false;
|
||||
previewTitle.value = '';
|
||||
};
|
||||
|
||||
const beforeUpload = (file: File) => {
|
||||
const { maxSize, accept } = props;
|
||||
const { name } = file;
|
||||
const isAct = isImgTypeByName(name);
|
||||
if (!isAct) {
|
||||
createMessage.error(t('component.upload.acceptUpload', [accept]));
|
||||
isActMsg.value = false;
|
||||
// 防止弹出多个错误提示
|
||||
setTimeout(() => (isActMsg.value = true), 1000);
|
||||
}
|
||||
const isLt = file.size / 1024 / 1024 > maxSize;
|
||||
if (isLt) {
|
||||
createMessage.error(t('component.upload.maxSizeMultiple', [maxSize]));
|
||||
isLtMsg.value = false;
|
||||
// 防止弹出多个错误提示
|
||||
setTimeout(() => (isLtMsg.value = true), 1000);
|
||||
}
|
||||
return (isAct && !isLt) || Upload.LIST_IGNORE;
|
||||
};
|
||||
|
||||
async function customRequest(info: UploadRequestOption<any>) {
|
||||
const { api } = props;
|
||||
if (!api || !isFunction(api)) {
|
||||
return warn('upload api must exist and be a function');
|
||||
}
|
||||
try {
|
||||
const res = await props.api?.({
|
||||
data: {
|
||||
...(props.uploadParams || {}),
|
||||
},
|
||||
file: info.file,
|
||||
name: props.name,
|
||||
filename: props.filename,
|
||||
});
|
||||
info.onSuccess!(res.data);
|
||||
const value = getValue();
|
||||
isInnerOperate.value = true;
|
||||
emit('change', value);
|
||||
} catch (e: any) {
|
||||
console.log(e);
|
||||
info.onError!(e);
|
||||
}
|
||||
}
|
||||
|
||||
function getValue() {
|
||||
const list = (fileList.value || [])
|
||||
.filter((item) => item?.status === UploadResultStatus.DONE)
|
||||
.map((item: any) => {
|
||||
return item?.url || item?.response?.url;
|
||||
});
|
||||
return props.multiple ? list : list.length > 0 ? list[0] : '';
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.ant-upload-select-picture-card i {
|
||||
color: #999;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
.ant-upload-select-picture-card .ant-upload-text {
|
||||
margin-top: 8px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.mapContainer{
|
||||
width:100%;
|
||||
height:280px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.refresh-button{
|
||||
position:absolute;
|
||||
top:6px;
|
||||
right:6px;
|
||||
width:30px;
|
||||
height:30px;
|
||||
border-radius: 4px;
|
||||
background:#fff;
|
||||
line-height: 30px;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
import type { BasicColumn, ActionItem } from '@/components/Table';
|
||||
import { FileBasicColumn, FileItem, PreviewFileItem, UploadResultStatus } from '../types/typing';
|
||||
import { isImgTypeByName } from '../helper';
|
||||
import { Progress, Tag } from 'ant-design-vue';
|
||||
import TableAction from '@/components/Table/src/components/TableAction.vue';
|
||||
import ThumbUrl from './ThumbUrl.vue';
|
||||
import { useI18n } from '@/hooks/web/useI18n';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
// 文件上传列表
|
||||
export function createTableColumns(): FileBasicColumn[] {
|
||||
return [
|
||||
{
|
||||
dataIndex: 'thumbUrl',
|
||||
title: t('component.upload.legend'),
|
||||
width: 100,
|
||||
customRender: ({ record }) => {
|
||||
const { thumbUrl } = (record as FileItem) || {};
|
||||
return thumbUrl && <ThumbUrl fileUrl={thumbUrl} />;
|
||||
},
|
||||
},
|
||||
{
|
||||
dataIndex: 'name',
|
||||
title: t('component.upload.fileName'),
|
||||
align: 'left',
|
||||
customRender: ({ text, record }) => {
|
||||
const { percent, status: uploadStatus } = (record as FileItem) || {};
|
||||
let status: 'normal' | 'exception' | 'active' | 'success' = 'normal';
|
||||
if (uploadStatus === UploadResultStatus.ERROR) {
|
||||
status = 'exception';
|
||||
} else if (uploadStatus === UploadResultStatus.UPLOADING) {
|
||||
status = 'active';
|
||||
} else if (uploadStatus === UploadResultStatus.SUCCESS) {
|
||||
status = 'success';
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<p class="truncate mb-1 max-w-[280px]" title={text}>
|
||||
{text}
|
||||
</p>
|
||||
<Progress percent={percent} size="small" status={status} />
|
||||
</div>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
dataIndex: 'size',
|
||||
title: t('component.upload.fileSize'),
|
||||
width: 100,
|
||||
customRender: ({ text = 0 }) => {
|
||||
return text && (text / 1024).toFixed(2) + 'KB';
|
||||
},
|
||||
},
|
||||
{
|
||||
dataIndex: 'status',
|
||||
title: t('component.upload.fileStatue'),
|
||||
width: 100,
|
||||
customRender: ({ text }) => {
|
||||
if (text === UploadResultStatus.SUCCESS) {
|
||||
return <Tag color="green">{() => t('component.upload.uploadSuccess')}</Tag>;
|
||||
} else if (text === UploadResultStatus.ERROR) {
|
||||
return <Tag color="red">{() => t('component.upload.uploadError')}</Tag>;
|
||||
} else if (text === UploadResultStatus.UPLOADING) {
|
||||
return <Tag color="blue">{() => t('component.upload.uploading')}</Tag>;
|
||||
}
|
||||
|
||||
return text || t('component.upload.pending');
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
export function createActionColumn(handleRemove: Function): FileBasicColumn {
|
||||
return {
|
||||
width: 120,
|
||||
title: t('component.upload.operating'),
|
||||
dataIndex: 'action',
|
||||
fixed: false,
|
||||
customRender: ({ record }) => {
|
||||
const actions: ActionItem[] = [
|
||||
{
|
||||
label: t('component.upload.del'),
|
||||
color: 'error',
|
||||
onClick: handleRemove.bind(null, record),
|
||||
},
|
||||
];
|
||||
return <TableAction actions={actions} outside={true} />;
|
||||
},
|
||||
};
|
||||
}
|
||||
// 文件预览列表
|
||||
export function createPreviewColumns(): BasicColumn[] {
|
||||
return [
|
||||
{
|
||||
dataIndex: 'url',
|
||||
title: t('component.upload.legend'),
|
||||
width: 100,
|
||||
customRender: ({ record }) => {
|
||||
const { url } = (record as PreviewFileItem) || {};
|
||||
return isImgTypeByName(url) && <ThumbUrl fileUrl={url} />;
|
||||
},
|
||||
},
|
||||
{
|
||||
dataIndex: 'name',
|
||||
title: t('component.upload.fileName'),
|
||||
align: 'left',
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
export function createPreviewActionColumn({
|
||||
handleRemove,
|
||||
handleDownload,
|
||||
}: {
|
||||
handleRemove: Fn;
|
||||
handleDownload: Fn;
|
||||
}): BasicColumn {
|
||||
return {
|
||||
width: 160,
|
||||
title: t('component.upload.operating'),
|
||||
dataIndex: 'action',
|
||||
fixed: false,
|
||||
customRender: ({ record }) => {
|
||||
const actions: ActionItem[] = [
|
||||
{
|
||||
label: t('component.upload.del'),
|
||||
color: 'error',
|
||||
onClick: handleRemove.bind(null, record),
|
||||
},
|
||||
{
|
||||
label: t('component.upload.download'),
|
||||
onClick: handleDownload.bind(null, record),
|
||||
},
|
||||
];
|
||||
|
||||
return <TableAction actions={actions} outside={true} />;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
export function checkFileType(file: File, accepts: string[]) {
|
||||
const newTypes = accepts.join('|');
|
||||
// const reg = /\.(jpg|jpeg|png|gif|txt|doc|docx|xls|xlsx|xml)$/i;
|
||||
const reg = new RegExp('\\.(' + newTypes + ')$', 'i');
|
||||
|
||||
return reg.test(file.name);
|
||||
}
|
||||
|
||||
export function checkImgType(file: File) {
|
||||
return isImgTypeByName(file.name);
|
||||
}
|
||||
|
||||
export function isImgTypeByName(name: string) {
|
||||
return /\.(jpg|jpeg|png|gif|webp)$/i.test(name);
|
||||
}
|
||||
|
||||
|
||||
export function isVideoTypeByName(name: string) {
|
||||
return /\.(mp4|mov|avi)$/i.test(name);
|
||||
}
|
||||
|
||||
export function getBase64WithFile(file: File) {
|
||||
return new Promise<{
|
||||
result: string;
|
||||
file: File;
|
||||
}>((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
reader.readAsDataURL(file);
|
||||
reader.onload = () => resolve({ result: reader.result as string, file });
|
||||
reader.onerror = (error) => reject(error);
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
import { Ref, unref, computed } from 'vue';
|
||||
import { useI18n } from '@/hooks/web/useI18n';
|
||||
|
||||
const { t } = useI18n();
|
||||
export function useUploadType({
|
||||
acceptRef,
|
||||
helpTextRef,
|
||||
maxNumberRef,
|
||||
maxSizeRef,
|
||||
}: {
|
||||
acceptRef: Ref<string[]>;
|
||||
helpTextRef: Ref<string>;
|
||||
maxNumberRef: Ref<number>;
|
||||
maxSizeRef: Ref<number>;
|
||||
}) {
|
||||
// 文件类型限制
|
||||
const getAccept = computed(() => {
|
||||
const accept = unref(acceptRef);
|
||||
if (accept && accept.length > 0) {
|
||||
return accept;
|
||||
}
|
||||
return [];
|
||||
});
|
||||
const getStringAccept = computed(() => {
|
||||
return unref(getAccept)
|
||||
.map((item) => {
|
||||
if (item.indexOf('/') > 0 || item.startsWith('.')) {
|
||||
return item;
|
||||
} else {
|
||||
return `.${item}`;
|
||||
}
|
||||
})
|
||||
.join(',');
|
||||
});
|
||||
|
||||
// 支持jpg、jpeg、png格式,不超过2M,最多可选择10张图片,。
|
||||
const getHelpText = computed(() => {
|
||||
const helpText = unref(helpTextRef);
|
||||
if (helpText) {
|
||||
return helpText;
|
||||
}
|
||||
const helpTexts: string[] = [];
|
||||
|
||||
const accept = unref(acceptRef);
|
||||
if (accept.length > 0) {
|
||||
helpTexts.push(t('component.upload.accept', [accept.join(',')]));
|
||||
}
|
||||
|
||||
const maxSize = unref(maxSizeRef);
|
||||
if (maxSize) {
|
||||
helpTexts.push(t('component.upload.maxSize', [maxSize]));
|
||||
}
|
||||
|
||||
const maxNumber = unref(maxNumberRef);
|
||||
if (maxNumber && maxNumber !== Infinity) {
|
||||
helpTexts.push(t('component.upload.maxNumber', [maxNumber]));
|
||||
}
|
||||
return helpTexts.join(',');
|
||||
});
|
||||
return { getAccept, getStringAccept, getHelpText };
|
||||
}
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
import type { PropType } from 'vue';
|
||||
import { FileBasicColumn } from './types/typing';
|
||||
|
||||
import type { Options } from 'sortablejs';
|
||||
|
||||
import { Merge } from '@/utils/types';
|
||||
|
||||
type SortableOptions = Merge<
|
||||
Omit<Options, 'onEnd'>,
|
||||
{
|
||||
onAfterEnd?: <T = any, R = any>(params: T) => R;
|
||||
// ...可扩展
|
||||
}
|
||||
>;
|
||||
|
||||
type ListType = 'text' | 'picture' | 'picture-card';
|
||||
|
||||
export const basicProps = {
|
||||
listType: {
|
||||
type: String as PropType<ListType>,
|
||||
default: 'picture-card',
|
||||
},
|
||||
helpText: {
|
||||
type: String as PropType<string>,
|
||||
default: '',
|
||||
},
|
||||
// 文件最大多少MB
|
||||
maxSize: {
|
||||
type: Number as PropType<number>,
|
||||
default: 2,
|
||||
},
|
||||
// 最大数量的文件,Infinity不限制
|
||||
maxNumber: {
|
||||
type: Number as PropType<number>,
|
||||
default: 1,
|
||||
},
|
||||
// 根据后缀,或者其他
|
||||
accept: {
|
||||
type: Array as PropType<string[]>,
|
||||
default: () => [],
|
||||
},
|
||||
multiple: {
|
||||
type: Boolean as PropType<boolean>,
|
||||
default: false,
|
||||
},
|
||||
uploadParams: {
|
||||
type: Object as PropType<any>,
|
||||
default: () => ({}),
|
||||
},
|
||||
api: {
|
||||
type: Function as PropType<PromiseFn>,
|
||||
default: null,
|
||||
required: true,
|
||||
},
|
||||
name: {
|
||||
type: String as PropType<string>,
|
||||
default: 'file',
|
||||
},
|
||||
filename: {
|
||||
type: String as PropType<string>,
|
||||
default: null,
|
||||
},
|
||||
fileListOpenDrag: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
|
||||
fileListDragOptions: {
|
||||
type: Object as PropType<SortableOptions>,
|
||||
default: () => ({}),
|
||||
},
|
||||
};
|
||||
|
||||
export const uploadContainerProps = {
|
||||
value: {
|
||||
type: Array as PropType<string[]>,
|
||||
default: () => [],
|
||||
},
|
||||
...basicProps,
|
||||
showPreviewNumber: {
|
||||
type: Boolean as PropType<boolean>,
|
||||
default: true,
|
||||
},
|
||||
emptyHidePreview: {
|
||||
type: Boolean as PropType<boolean>,
|
||||
default: false,
|
||||
},
|
||||
};
|
||||
|
||||
export const previewProps = {
|
||||
value: {
|
||||
type: Array as PropType<string[]>,
|
||||
default: () => [],
|
||||
},
|
||||
};
|
||||
|
||||
export const fileListProps = {
|
||||
columns: {
|
||||
type: Array as PropType<FileBasicColumn[]>,
|
||||
default: null,
|
||||
},
|
||||
actionColumn: {
|
||||
type: Object as PropType<FileBasicColumn>,
|
||||
default: null,
|
||||
},
|
||||
dataSource: {
|
||||
type: Array as PropType<any[]>,
|
||||
default: null,
|
||||
},
|
||||
openDrag: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
dragOptions: {
|
||||
type: Object as PropType<SortableOptions>,
|
||||
default: () => ({}),
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
import { BasicColumn } from '@/components/Table';
|
||||
import { UploadApiResult } from '@/api/sys/model/uploadModel';
|
||||
|
||||
export enum UploadResultStatus {
|
||||
DONE = 'done',
|
||||
SUCCESS = 'success',
|
||||
ERROR = 'error',
|
||||
UPLOADING = 'uploading',
|
||||
}
|
||||
|
||||
export interface FileItem {
|
||||
thumbUrl?: string;
|
||||
name: string;
|
||||
size: string | number;
|
||||
type?: string;
|
||||
percent: number;
|
||||
file: File;
|
||||
status?: UploadResultStatus;
|
||||
response?: UploadApiResult;
|
||||
uuid: string;
|
||||
}
|
||||
|
||||
export interface PreviewFileItem {
|
||||
url: string;
|
||||
name: string;
|
||||
type: string;
|
||||
}
|
||||
|
||||
export interface FileBasicColumn extends Omit<BasicColumn, 'customRender'> {
|
||||
/**
|
||||
* Renderer of the table cell. The return value should be a VNode, or an object for colSpan/rowSpan config
|
||||
* @type Function | ScopedSlot
|
||||
*/
|
||||
customRender?: Function;
|
||||
/**
|
||||
* Title of this column
|
||||
* @type any (string | slot)
|
||||
*/
|
||||
title: string;
|
||||
|
||||
/**
|
||||
* Display field of the data record, could be set like a.b.c
|
||||
* @type string
|
||||
*/
|
||||
dataIndex: string;
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
<template #closeIcon>
|
||||
<CloseCircleOutlined />
|
||||
</template>
|
||||
<div class="title">上传shp</div>
|
||||
<div class="title">上传数据</div>
|
||||
<div class="content">
|
||||
<a-steps
|
||||
class="steps"
|
||||
|
|
@ -45,6 +45,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="upload-form">
|
||||
|
||||
<a-form
|
||||
ref="formRef"
|
||||
:model="uploadFrom"
|
||||
|
|
@ -55,26 +56,74 @@
|
|||
<a-form-item label="服务名称" name="serverName">
|
||||
<a-input v-model:value="uploadFrom.serverName" placeholder="请输入服务名称" />
|
||||
</a-form-item>
|
||||
<a-form-item label="空间参考" name="spaceType">
|
||||
<!-- <a-input v-model:value="uploadFrom.spaceType" /> -->
|
||||
<a-select v-model:value="uploadFrom.spaceType" placeholder="请选择空间参考">
|
||||
<a-select-option value="EPSG:4326">EPSG:4326</a-select-option>
|
||||
<a-select-option value="EPSG:3857">EPSG:3857</a-select-option>
|
||||
<a-select-option value="EPSG:900913">EPSG:900913</a-select-option>
|
||||
|
||||
<!-- 显示条件:文件类型为Excel时 -->
|
||||
<a-form-item label="图斑数据" name="hasFeature" v-if="!isShp">
|
||||
<a-select v-model:value="uploadFrom.hasFeature" placeholder="请选择是否具有图斑数据">
|
||||
<a-select-option value="1">是</a-select-option>
|
||||
<a-select-option value="0">否</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="表名" name="tableName">
|
||||
<a-input v-model:value="uploadFrom.tableName" placeholder="请输入表名" />
|
||||
|
||||
<!-- 显示条件:文件类型为shp 或者 类型为Excel时有图斑数据 -->
|
||||
<a-form-item label="空间参考" name="spaceType" v-if="isShp || (!isShp && uploadFrom.hasFeature == '1')">
|
||||
<a-select v-model:value="uploadFrom.spaceType" placeholder="请选择空间参考">
|
||||
<a-select-option value="EPSG:4326">EPSG:4326</a-select-option>
|
||||
<a-select-option value="3857">EPSG:3857</a-select-option>
|
||||
<a-select-option value="900913">EPSG:900913</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
|
||||
<!-- 显示条件:文件类型为Excel有图斑时 -->
|
||||
<a-form-item label="数据类型" name="spaceType" v-if="!isShp && uploadFrom.hasFeature == '1'">
|
||||
<a-select v-model:value="uploadFrom.layerType" placeholder="请选择数据类型">
|
||||
<a-select-option value="point">点</a-select-option>
|
||||
<a-select-option value="linestring">线</a-select-option>
|
||||
<a-select-option value="polygon">面</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="数据表名" name="tableName">
|
||||
<a-row :gutter="12">
|
||||
<a-col :span="20">
|
||||
<a-input v-model:value="uploadFrom.tableName" placeholder="请输入表名" />
|
||||
</a-col>
|
||||
<a-col :span="4">
|
||||
<!-- <a-tooltip title="从现有数据表中选择">
|
||||
<a-button type="primary" :icon="h(PlusOutlined)" @click="handlerGetExistsTableList"/>
|
||||
</a-tooltip> -->
|
||||
|
||||
<a-popover placement="topLeft">
|
||||
<template #content>
|
||||
<a-table :dataSource="dataSource" :columns="columns" :size="'small'" >
|
||||
<template #bodyCell="{ column,record }">
|
||||
<template v-if="column.key === 'operation'">
|
||||
<a-button type="" :icon="h(PlusOutlined)" @click="handlerGetExistsTableList(record)" />
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</template>
|
||||
|
||||
<template #title>
|
||||
<span>从现有数据表中选择</span>
|
||||
</template>
|
||||
<a-button type="primary" :icon="h(PlusOutlined)" />
|
||||
</a-popover>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
|
||||
<div class="upload-span-button">
|
||||
<a-button type="primary" :icon="h(PlusOutlined)" @click="submitShp">上传</a-button>
|
||||
<a-button type="primary" :icon="h(CloudUploadOutlined)" @click="submitShp">上传</a-button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="edit-info-div" v-show="current === 1">
|
||||
<a-table
|
||||
:columns="columns"
|
||||
:columns="tablecolumns"
|
||||
:data-source="dataList"
|
||||
:pagination="false"
|
||||
:bordered="true"
|
||||
|
|
@ -112,6 +161,7 @@
|
|||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="submit-success" v-show="current === 2">
|
||||
<div class="success-content">
|
||||
<CheckCircleOutlined style="font-size: 100px; color: #1fd286; margin-bottom: 30px" />
|
||||
|
|
@ -119,6 +169,11 @@
|
|||
<div><a-button type="primary">查看数据</a-button></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 已有数据表 -->
|
||||
<div class="exist-table-list" v-if="showExistTableList">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
|
@ -132,29 +187,54 @@
|
|||
CheckCircleOutlined,
|
||||
} from '@ant-design/icons-vue';
|
||||
import './index.scss';
|
||||
import { InboxOutlined } from '@ant-design/icons-vue';
|
||||
import { InboxOutlined,CloudUploadOutlined } from '@ant-design/icons-vue';
|
||||
import { message } from 'ant-design-vue';
|
||||
import type { UploadChangeParam } from 'ant-design-vue';
|
||||
import type { UploadProps } from 'ant-design-vue';
|
||||
// import { uploadShp } from '@/api/sys/analysis.ts'
|
||||
import axios from 'axios';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { FILETYPE } from '../util'
|
||||
import { FILETYPE } from '../util'
|
||||
import {ObjectToUrl} from '../src/tool'
|
||||
const dataSource = reactive([
|
||||
{
|
||||
"tablename":"monitor"
|
||||
},
|
||||
{
|
||||
"tablename":"monitor0527"
|
||||
},
|
||||
])
|
||||
|
||||
const columns = reactive([
|
||||
{
|
||||
title: '数据表名称',
|
||||
dataIndex: 'tablename',
|
||||
key: 'tablename',
|
||||
},{
|
||||
title: '选择数据表',
|
||||
dataIndex: 'operation',
|
||||
key: 'operation',
|
||||
}
|
||||
])
|
||||
|
||||
const current = ref(0);
|
||||
const fileList = ref<UploadProps['fileList']>([]);
|
||||
const props = defineProps(['openModal']);
|
||||
const emits = defineEmits(['update:openModal']);
|
||||
const uploadFrom = reactive({
|
||||
serverName: '',
|
||||
serverName: null,
|
||||
hasFeature:null,
|
||||
spaceType: null,
|
||||
tableName: '',
|
||||
layerType:null,
|
||||
tableName: null,
|
||||
});
|
||||
const formRef = ref();
|
||||
const dataList = ref([]);
|
||||
const isShp = ref(false);
|
||||
const isShp = ref<Boolean>(true);
|
||||
const showExistTableList = ref<Boolean>(false)
|
||||
|
||||
// todo
|
||||
const columns = [
|
||||
const tablecolumns = [
|
||||
{ title: 'Shp原始字段', dataIndex: 'name', key: 'name' },
|
||||
{ title: '数据类型', dataIndex: 'type', key: 'type' },
|
||||
{ title: '数据长度', dataIndex: 'length', key: 'length' },
|
||||
|
|
@ -162,44 +242,146 @@ import { FILETYPE } from '../util'
|
|||
{ title: '中文名称', dataIndex: 'initName', key: 'initName' },
|
||||
{ title: '操作', dataIndex: 'operation', key: 'operation' },
|
||||
];
|
||||
const uploadFormRules = {
|
||||
serverName: [{ required: true, message: '请输入服务名称', trigger: 'blur' }],
|
||||
spaceType: [{ required: true, message: '请选择参考系', trigger: 'blur' }],
|
||||
tableName: [{ required: true, message: '请输入表名', trigger: 'blur' }],
|
||||
};
|
||||
|
||||
const beforeUpload: UploadProps['beforeUpload'] = (file) => {
|
||||
console.log('beforeUpload',file)
|
||||
file.type === FILETYPE.ZIP? isShp.value = true: isShp.value = false
|
||||
|
||||
|
||||
const uploadFormRules = reactive({
|
||||
serverName: [{ required: true, message: '请输入服务名称', trigger: 'blur' }],
|
||||
hasFeature: [{ required: true, message: '请选择是否有图斑数据', trigger: 'blur' }],
|
||||
spaceType: [{ required: true, message: '请选择参考系', trigger: 'blur' }],
|
||||
layerType: [{ required: true, message: '请选数据类型', trigger: 'blur' }],
|
||||
tableName: [{ required: true, message: '请输入表名', trigger: 'blur' }],
|
||||
});
|
||||
|
||||
|
||||
const beforeUpload:UploadProps['beforeUpload'] = (file) => {
|
||||
file.type === FILETYPE.ZIP ? isShp.value = true: isShp.value = false
|
||||
fileList.value = [file];
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
const handlerUploadFile = ()=>{
|
||||
let url = "http://192.168.10.102:9500/api/Files/Upload"
|
||||
|
||||
const [proxyFile] = fileList.value
|
||||
let file = proxyFile.originFileObj
|
||||
|
||||
let formData = new FormData();
|
||||
formData.append('files', file)
|
||||
// formData.append('serverName',uploadFrom.serverName)
|
||||
// formData.append('spaceType',uploadFrom.spaceType)
|
||||
// formData.append('tableName',uploadFrom.tableName)
|
||||
|
||||
|
||||
axios.post(url,formData,{headers: {'Content-Type': 'multipart/form-data;charset=UTF-8','X-Token':"95a1a7a8"}}).then(res => {
|
||||
alert(res.data.result[0].filePath);
|
||||
handlerCreateLayer(res.data.result[0].filePath)
|
||||
})
|
||||
}
|
||||
|
||||
const handlerCreateLayer =(filePath)=>{
|
||||
|
||||
// upload 接口返回路径的反斜杠替换 20240528\\2024052814563161320172.zip → 20240528/2024052814563161320172.zip
|
||||
|
||||
filePath = filePath.replace(/\\/,'/');
|
||||
|
||||
let addForm = {
|
||||
filePath:filePath,
|
||||
tableName:uploadFrom.tableName,
|
||||
srid:uploadFrom.spaceType
|
||||
}
|
||||
let params = ObjectToUrl(addForm);
|
||||
|
||||
axios.post("http://192.168.10.102:9500/api/PolygonalShape/CreateGISLayer"+params,{},{headers:{'Content-Type': 'multipart/form-data;charset=UTF-8','X-Token':"95a1a7a8"}}).then(res=>{
|
||||
console.log("helloworld",res);
|
||||
})
|
||||
}
|
||||
|
||||
const submitShp = () => {
|
||||
formRef.value.validate().then(() => {
|
||||
if(fileList.value?.length < 1){
|
||||
message.warning('请选择shp文件')
|
||||
message.warning('请选择需要上传的文件')
|
||||
return
|
||||
}
|
||||
|
||||
// 文件上传FormData()
|
||||
let formData = new FormData();
|
||||
const [proxyFile] = fileList.value
|
||||
let file = proxyFile.originFileObj
|
||||
|
||||
const [proxyFile] = fileList.value
|
||||
|
||||
let file = proxyFile.originFileObj
|
||||
|
||||
formData.append('file', file)
|
||||
formData.append('serverName',uploadFrom.serverName)
|
||||
formData.append('spaceType',uploadFrom.spaceType)
|
||||
formData.append('tableName',uploadFrom.tableName)
|
||||
let url = ""
|
||||
isShp.value? url = 'http://221.2.83.254:9006/geoserver/uploadFile': url = 'http://221.2.83.254:9006/geoserver/uploadExcelFile'
|
||||
axios.post(url,formData,{headers: {'Content-Type': 'multipart/form-data;charset=UTF-8'}}).then(res => {
|
||||
|
||||
|
||||
// isShp.value ? url = "http://192.168.10.102:9500/api/Files/Upload" : url = "http://192.168.10.102:9500/api/Files/Upload"
|
||||
|
||||
// let data = [
|
||||
// {
|
||||
// "length": 1024,
|
||||
// "name": "name",
|
||||
// "type": "varchar"
|
||||
// },
|
||||
// {
|
||||
// "length": 1024,
|
||||
// "name": "num",
|
||||
// "type": "varchar"
|
||||
// },
|
||||
// {
|
||||
// "length": 1024,
|
||||
// "name": "type",
|
||||
// "type": "varchar"
|
||||
// },
|
||||
// {
|
||||
// "length": 1024,
|
||||
// "name": "shebeiid",
|
||||
// "type": "varchar"
|
||||
// },
|
||||
// {
|
||||
// "length": 1024,
|
||||
// "name": "forestryty",
|
||||
// "type": "varchar"
|
||||
// },
|
||||
// {
|
||||
// "length": "",
|
||||
// "name": "geom",
|
||||
// "type": "geometry"
|
||||
// },
|
||||
// {
|
||||
// "length": 1024,
|
||||
// "name": "road",
|
||||
// "type": "varchar"
|
||||
// },
|
||||
// {
|
||||
// "length": 1024,
|
||||
// "name": "checksite",
|
||||
// "type": "varchar"
|
||||
// },
|
||||
// {
|
||||
// "length": 1024,
|
||||
// "name": "lng",
|
||||
// "type": "varchar"
|
||||
// },
|
||||
// {
|
||||
// "length": 1024,
|
||||
// "name": "lat",
|
||||
// "type": "varchar"
|
||||
// }
|
||||
// ]
|
||||
|
||||
axios.post(url,formData,{headers: {'Content-Type': 'multipart/form-data;charset=UTF-8'}}).then(res => {
|
||||
let data = res.data.data.heads
|
||||
let showData = data.map(item => {
|
||||
return {...item,refName:item.name.toLowerCase(),initName:item.name,key:uuidv4()}
|
||||
})
|
||||
|
||||
dataList.value = showData
|
||||
current.value++
|
||||
|
||||
}).catch(err => {
|
||||
console.log(err)
|
||||
})
|
||||
|
|
@ -214,6 +396,7 @@ const closeModal = () => {
|
|||
fileList.value = []
|
||||
current.value = 0
|
||||
}
|
||||
|
||||
const deleteListItem = (record) => {
|
||||
dataList.value = dataList.value.filter(item => item.key !== record.key)
|
||||
}
|
||||
|
|
@ -230,22 +413,27 @@ const insertListItem = () => {
|
|||
const submitDataList = () => {
|
||||
|
||||
|
||||
let refRelation = {}
|
||||
// let refRelation = {}
|
||||
|
||||
dataList.value.forEach((item,index)=>{
|
||||
refRelation[item.refName] = item.initName;
|
||||
})
|
||||
// dataList.value.forEach((item,index)=>{
|
||||
// refRelation[item.refName] = item.initName;
|
||||
// })
|
||||
|
||||
console.log("refRelation",refRelation);
|
||||
// console.log("refRelation",refRelation);
|
||||
|
||||
|
||||
let exportForm = {
|
||||
"newHeads": dataList.value,
|
||||
"refRelation": JSON.stringify(refRelation),
|
||||
}
|
||||
// let exportForm = {
|
||||
// "newHeads": dataList.value,
|
||||
// "refRelation": JSON.stringify(refRelation),
|
||||
// }
|
||||
|
||||
// console.log(dataList.value)
|
||||
// current.value++
|
||||
current.value++
|
||||
}
|
||||
|
||||
// 获取现有数据表
|
||||
const handlerGetExistsTableList = (record )=>{
|
||||
uploadFrom.tableName = record.tablename
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
@ -336,5 +524,14 @@ const submitDataList = () => {
|
|||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
.exist-table-list{
|
||||
width:100%;
|
||||
height: calc( 100% - 60px);
|
||||
position:absolute;
|
||||
top:60px;
|
||||
left:0px;
|
||||
background:#fff;
|
||||
border-radius: 12px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -36,7 +36,13 @@
|
|||
|
||||
// 图形绘制工具类
|
||||
import MapboxDraw from '@mapbox/mapbox-gl-draw';
|
||||
|
||||
|
||||
import { generateUUID,getGeometryCenter } from './src/tool'
|
||||
|
||||
// 测量工具
|
||||
import { SwitchLayerControl,MeasureControl } from 'mapbox-extensions'
|
||||
import 'mapbox-extensions/dist/index.css'
|
||||
|
||||
import U from 'mapbox-gl-utils';
|
||||
import 'mapbox-gl/dist/mapbox-gl.css';
|
||||
import './src/index.less';
|
||||
|
|
@ -156,6 +162,23 @@
|
|||
});
|
||||
|
||||
window.handlerCopyFeature = handlerCopyFeature;
|
||||
|
||||
map.addControl(new MeasureControl({
|
||||
horizontal : true, //default false
|
||||
btnBgColor : '#ffffff', //default '#ffffff'
|
||||
btnActiveColor:'#ddd', //default '#ddd'
|
||||
geometryClick:true, //defualt false
|
||||
enableModes:['Point','LineString','Polygon'],//default all
|
||||
onStart:()=>{},
|
||||
onStop:()=>{},
|
||||
measurePointOptions:{
|
||||
},
|
||||
measureLineStringOptions:{
|
||||
},
|
||||
measurePolygonOptions:{
|
||||
}
|
||||
}),"top-left")
|
||||
|
||||
});
|
||||
});
|
||||
// 销毁地图
|
||||
|
|
@ -242,57 +265,66 @@
|
|||
|
||||
// 初始化绘图空间
|
||||
const handlerInitDrawTool = (feature, bool) => {
|
||||
if (feature.features.length > 0) {
|
||||
feature.features.forEach((item) => {
|
||||
if (item.geometry.type == 'MultiPolygon') {
|
||||
let arr: any = ref([]);
|
||||
item.geometry.coordinates.forEach((val) => {
|
||||
arr.value.push(val[0]);
|
||||
});
|
||||
item.geometry.coordinates = arr.value;
|
||||
item.geometry.type = 'Polygon';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// if (feature.features.length > 0) {
|
||||
|
||||
// feature.features.forEach((item) => {
|
||||
|
||||
// if (item.geometry.type == 'MultiPolygon') {
|
||||
// let arr: any = ref([]);
|
||||
// item.geometry.coordinates.forEach((val) => {
|
||||
// arr.value.push(val[0]);
|
||||
// });
|
||||
// item.geometry.coordinates = arr.value;
|
||||
// item.geometry.type = 'Polygon';
|
||||
// }
|
||||
// });
|
||||
|
||||
// }
|
||||
|
||||
geojson.geojson = feature;
|
||||
console.log('drawTool', drawTool);
|
||||
console.log('feature', feature);
|
||||
if (drawTool) {
|
||||
drawTool.deleteAll();
|
||||
if (feature.features) {
|
||||
drawTool.set(geojson.geojson);
|
||||
geojson.geojson = feature;
|
||||
|
||||
|
||||
if (drawTool) {
|
||||
drawTool.deleteAll();
|
||||
if (feature.features) {
|
||||
drawTool.set(geojson.geojson);
|
||||
}
|
||||
} else {
|
||||
drawTool = new MapboxDraw({
|
||||
modes: {
|
||||
...MapboxDraw.modes,
|
||||
draw_point: SnapPointMode,
|
||||
draw_polygon: SnapPolygonMode,
|
||||
draw_line_string: SnapLineMode,
|
||||
direct_select: SnapDirectSelect,
|
||||
},
|
||||
styles: customDrawStyles,
|
||||
userProperties: true,
|
||||
snap: true,
|
||||
snapOptions: {
|
||||
snapPx: 12, // defaults to 15
|
||||
snapToMidPoints: true, // defaults to false
|
||||
snapVertexPriorityDistance: 0.0025, // defaults to 1.25
|
||||
},
|
||||
guides: false,
|
||||
});
|
||||
|
||||
map.addControl(drawTool, 'top-right');
|
||||
|
||||
if (feature.features) {
|
||||
drawTool.set(geojson.geojson);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
drawTool = new MapboxDraw({
|
||||
modes: {
|
||||
...MapboxDraw.modes,
|
||||
draw_point: SnapPointMode,
|
||||
draw_polygon: SnapPolygonMode,
|
||||
draw_line_string: SnapLineMode,
|
||||
direct_select: SnapDirectSelect,
|
||||
},
|
||||
styles: customDrawStyles,
|
||||
userProperties: true,
|
||||
snap: true,
|
||||
snapOptions: {
|
||||
snapPx: 12, // defaults to 15
|
||||
snapToMidPoints: true, // defaults to false
|
||||
snapVertexPriorityDistance: 0.0025, // defaults to 1.25
|
||||
},
|
||||
guides: false,
|
||||
});
|
||||
map.addControl(drawTool, 'top-right');
|
||||
if (feature.features) {
|
||||
drawTool.set(geojson.geojson);
|
||||
}
|
||||
}
|
||||
// 正在绘制
|
||||
if (bool) {
|
||||
|
||||
// 正在绘制
|
||||
// if (bool) {
|
||||
// drawing.value = true;
|
||||
// } else {
|
||||
// drawing.value = false;
|
||||
// }
|
||||
|
||||
drawing.value = true;
|
||||
} else {
|
||||
drawing.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 将图斑复制到指定图层
|
||||
|
|
@ -386,7 +418,7 @@
|
|||
const handlerLocation = (lngLat) => {
|
||||
map.flyTo({
|
||||
center: lngLat,
|
||||
zoom: 16,
|
||||
zoom: 17,
|
||||
speed: 10, // 飞行速度
|
||||
curve: 1, // 飞行曲线
|
||||
easing(t) {
|
||||
|
|
@ -476,42 +508,40 @@
|
|||
|
||||
const handlerDraw = (features = null, bool = false) => {
|
||||
|
||||
console.log("features",features);
|
||||
|
||||
let geo = {
|
||||
type: 'FeatureCollection',
|
||||
features: [],
|
||||
};
|
||||
|
||||
console.log('features', features);
|
||||
console.log('bool', bool);
|
||||
|
||||
if (features == null) {
|
||||
bool = true;
|
||||
} else {
|
||||
if (features.length > 0) {
|
||||
for (let i = 0; i < features.length; i++) {
|
||||
|
||||
try {
|
||||
|
||||
let featureTemp = WktToGeojson(features[i].value);
|
||||
|
||||
let feature = {
|
||||
id: 'cd1d93c0e4a6747ff597f' + parseInt(1000000000 * Math.random()).toString(),
|
||||
type: 'Feature',
|
||||
properties: {},
|
||||
geometry: featureTemp,
|
||||
id: generateUUID(),
|
||||
type: 'Feature',
|
||||
properties: {},
|
||||
geometry: featureTemp,
|
||||
};
|
||||
|
||||
geo.features.push(feature);
|
||||
|
||||
// 获取第一个图斑的中心点跳转
|
||||
if(i == 0){
|
||||
let lngLat = getGeometryCenter(feature);
|
||||
handlerLocation(lngLat);
|
||||
}
|
||||
} catch (e) {
|
||||
console.log('WKT解析错误,请检查WKT数据格式是否有误');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handlerInitDrawTool(geo, bool);
|
||||
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
|
|
@ -519,6 +549,7 @@
|
|||
handlerLocation,
|
||||
handlerCancleDraw,
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
|
@ -526,10 +557,12 @@
|
|||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.map-box {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.layer-control-center {
|
||||
position: absolute;
|
||||
padding: 10px;
|
||||
|
|
@ -538,20 +571,23 @@
|
|||
background: #ffffff;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.layer-control-center p {
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.draw-control-center {
|
||||
position: absolute;
|
||||
padding: 7px;
|
||||
padding: 8px;
|
||||
top: 15px;
|
||||
right: 15px;
|
||||
background: #ffffff;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.draw-control-center .draw-btn {
|
||||
float: left;
|
||||
margin: 0px 6px;
|
||||
margin: 0px 7px;
|
||||
padding: 5px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
|
@ -560,9 +596,11 @@
|
|||
background-color: rgb(0 0 0/5%);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mapboxgl-ctrl-group:not(:empty) {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.mapboxgl-ctrl-group {
|
||||
padding: 10px;
|
||||
border-radius: 12px;
|
||||
|
|
@ -575,17 +613,20 @@
|
|||
height: 20px !important;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.mapboxgl-ctrl-top-right {
|
||||
|
||||
}
|
||||
|
||||
.mapboxgl-ctrl-group button + button {
|
||||
border: 0px;
|
||||
margin: 0px 10px;
|
||||
margin: 0px 6px;
|
||||
}
|
||||
|
||||
.mapbox-gl-draw_ctrl-draw-btn:hover {
|
||||
transform: scale(1.2);
|
||||
}
|
||||
|
||||
.mapbox-gl-draw_polygon {
|
||||
background-image: url(/polygon.png);
|
||||
background-size: 100% 100%;
|
||||
|
|
@ -603,7 +644,7 @@
|
|||
background-size: 100% 100%;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
margin: 0px 10px;
|
||||
margin: 0px 6px;
|
||||
}
|
||||
|
||||
.mapbox-gl-draw_trash {
|
||||
|
|
@ -626,5 +667,15 @@
|
|||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.jas-ctrl-measure{
|
||||
position:relative;
|
||||
top:6px;
|
||||
left:190px;
|
||||
}
|
||||
|
||||
.jas-ctrl-measure-item{
|
||||
height:22px;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
|
@ -225,70 +225,91 @@
|
|||
popup.remove();
|
||||
createMessage.success('复制成功!');
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.mapboxgl-ctrl-group:not(:empty) {
|
||||
box-shadow: none;
|
||||
}
|
||||
.mapboxgl-ctrl-group {
|
||||
background: none !important;
|
||||
}
|
||||
.mapbox-gl-draw_ctrl-draw-btn {
|
||||
width: 40px !important;
|
||||
height: 40px !important;
|
||||
float: left;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.mapboxgl-ctrl-top-right {
|
||||
}
|
||||
|
||||
.mapboxgl-ctrl-group button + button {
|
||||
border: 0px;
|
||||
margin: 0px 3px;
|
||||
}
|
||||
|
||||
.mapbox-gl-draw_ctrl-draw-btn:hover {
|
||||
transform: scale(1.2);
|
||||
}
|
||||
.mapbox-gl-draw_polygon {
|
||||
background-image: url(/polygon.png);
|
||||
background-size: 100% 100%;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
.mapbox-gl-draw_point {
|
||||
background-image: url(/point.png);
|
||||
background-size: 100% 100%;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
.mapbox-gl-draw_line {
|
||||
background-image: url(/line.png);
|
||||
background-size: 100% 100%;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.mapbox-gl-draw_trash {
|
||||
background-image: url(/del.png);
|
||||
background-size: 100% 100%;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.mapbox-gl-draw_combine {
|
||||
background-image: url(/combine.png);
|
||||
background-size: 100% 100%;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.mapbox-gl-draw_uncombine {
|
||||
background-image: url(/uncombine.png);
|
||||
background-size: 100% 100%;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
.draw-control-center .draw-btn {
|
||||
float: left;
|
||||
margin: 0px 6px;
|
||||
padding: 5px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.draw-control-center .draw-btn:hover {
|
||||
background-color: rgb(0 0 0/5%);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mapboxgl-ctrl-group:not(:empty) {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.mapboxgl-ctrl-group {
|
||||
padding: 10px;
|
||||
border-radius: 12px;
|
||||
position: relative;
|
||||
right: 140px;
|
||||
top: 5px;
|
||||
}
|
||||
.mapbox-gl-draw_ctrl-draw-btn {
|
||||
width: 20px !important;
|
||||
height: 20px !important;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.mapboxgl-ctrl-top-right {
|
||||
|
||||
}
|
||||
|
||||
.mapboxgl-ctrl-group button + button {
|
||||
border: 0px;
|
||||
margin: 0px 6px;
|
||||
}
|
||||
|
||||
.mapbox-gl-draw_ctrl-draw-btn:hover {
|
||||
transform: scale(1.2);
|
||||
}
|
||||
|
||||
.mapbox-gl-draw_polygon {
|
||||
background-image: url(/polygon.png);
|
||||
background-size: 100% 100%;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
.mapbox-gl-draw_point {
|
||||
background-image: url(/point.png);
|
||||
background-size: 100% 100%;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
.mapbox-gl-draw_line {
|
||||
background-image: url(/line.png);
|
||||
background-size: 100% 100%;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
margin: 0px 6px;
|
||||
}
|
||||
|
||||
.mapbox-gl-draw_trash {
|
||||
background-image: url(/del.png);
|
||||
background-size: 100% 100%;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.mapbox-gl-draw_combine {
|
||||
background-image: url(/combine.png);
|
||||
background-size: 100% 100%;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.mapbox-gl-draw_uncombine {
|
||||
background-image: url(/uncombine.png);
|
||||
background-size: 100% 100%;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
|
@ -42,6 +42,7 @@
|
|||
</a-button>
|
||||
<a-button type="primary" @click="handlerAddToLayerList">
|
||||
=======
|
||||
|
||||
</a-button> -->
|
||||
<a-button type="primary">
|
||||
<template #icon>
|
||||
|
|
@ -86,14 +87,19 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
import { PlusOutlined } from '@ant-design/icons-vue'
|
||||
import { errorImage } from '../../util.js'
|
||||
import { ref,defineEmits } from "vue"
|
||||
import { ref,defineEmits,reactive } from "vue"
|
||||
import MapboxMap from '@/components/MapboxMaps/index.vue'
|
||||
import { DrawingType } from '@/enums/mapEnum';
|
||||
import { useMessage } from '@/hooks/web/useMessage';
|
||||
|
||||
const { createMessage } = useMessage();
|
||||
|
||||
|
||||
|
||||
|
||||
const emits = defineEmits(["handlerAddToLayerList"])
|
||||
const data = ref('vector-data')
|
||||
const sort = ref('default')
|
||||
|
|
|
|||
|
|
@ -8,4 +8,5 @@ const GeojsonToWkt = (geojsonData)=> {
|
|||
return WKT.convert(geojsonData)
|
||||
}
|
||||
|
||||
|
||||
export {WktToGeojson,GeojsonToWkt}
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
// 生成UUID
|
||||
import { ControlOutlined } from '@ant-design/icons-vue';
|
||||
import * as turf from '@turf/turf'
|
||||
|
||||
// js生成UUID
|
||||
const generateUUID = ()=>{
|
||||
|
||||
var d = new Date().getTime(); //Timestamp
|
||||
|
||||
var d2 = (performance && performance.now && (performance.now()*1000)) || 0;
|
||||
|
||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
||||
var r = Math.random() * 16;
|
||||
if(d > 0) {
|
||||
|
|
@ -19,4 +19,42 @@ const generateUUID = ()=>{
|
|||
});
|
||||
}
|
||||
|
||||
export { generateUUID }
|
||||
// js 针对后端post接口参数拼接到url的情况 将json参数转换为 ?key1=value1&key2=value2
|
||||
const ObjectToUrl = (obj)=>{
|
||||
let params = "?";
|
||||
for(let item in obj){
|
||||
params+=item+"="+obj[item]+"&"
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
|
||||
// turf获取几何图形的中心
|
||||
const getGeometryCenter = (geometry)=>{
|
||||
let coordinates = [];
|
||||
switch(geometry.geometry.type.toUpperCase()){
|
||||
case "POINT":
|
||||
|
||||
break;
|
||||
case "MULTIPOINT":
|
||||
|
||||
break;
|
||||
case "LINESTRING":
|
||||
|
||||
break;
|
||||
case "MULTILINESTRING":
|
||||
|
||||
break;
|
||||
case "POLYGON":
|
||||
coordinates = geometry.geometry.coordinates
|
||||
break;
|
||||
case "MULTIPOLYGON":
|
||||
coordinates = geometry.geometry.coordinates[0]
|
||||
break;
|
||||
}
|
||||
let polygon = turf.polygon(coordinates);
|
||||
let center = turf.centerOfMass(polygon);
|
||||
return center.geometry.coordinates;
|
||||
}
|
||||
|
||||
export { generateUUID,ObjectToUrl,getGeometryCenter }
|
||||
|
|
@ -71,13 +71,14 @@
|
|||
<a-radio-button value="1" @click="handlePostClick(false)">岗位</a-radio-button>
|
||||
<a-radio-button value="2" @click="handleRoleClick(false)">角色</a-radio-button>
|
||||
<a-radio-button value="3" @click="handleAccountClick(false)">用户</a-radio-button>
|
||||
<a-radio-button value="3" @click="handleLevelClick(false)">上下级</a-radio-button>
|
||||
<a-radio-button value="3" @click="handleNodeAuditorClick(false)"
|
||||
<a-radio-button value="4" @click="handleLevelClick(false)">上下级</a-radio-button>
|
||||
<a-radio-button value="5" @click="handleNodeAuditorClick(false)"
|
||||
>节点执行人</a-radio-button
|
||||
>
|
||||
<a-radio-button value="3" @click="handleAuditorSqlClick(false)"
|
||||
<a-radio-button value="6" @click="handleAuditorSqlClick(false)"
|
||||
>表字段</a-radio-button
|
||||
>
|
||||
<a-radio-button value="7" @click="handleSQLClick(false)">执行SQL</a-radio-button>
|
||||
</a-radio-group>
|
||||
</a-space>
|
||||
<a-table
|
||||
|
|
@ -486,6 +487,15 @@
|
|||
>
|
||||
<SelectForm ref="formRef" />
|
||||
</a-modal>
|
||||
<a-modal
|
||||
width="40%"
|
||||
v-model:open="data.SQLOpen"
|
||||
title="添加SQL"
|
||||
@ok="executeSQLHandleOk"
|
||||
:destroyOnClose="true"
|
||||
>
|
||||
<ExecuteSQL ref="executeSQLRef" />
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
@ -494,7 +504,7 @@
|
|||
import { SelectPos } from '@/components/SelectPos/index';
|
||||
import { SelectRole } from '@/components/SelectRole/index';
|
||||
import { SelectAccount } from '@/components/SelectAccount/index';
|
||||
import { AuditorLevel, AuditorSql, AuditorNode } from './page';
|
||||
import { AuditorLevel, AuditorSql, AuditorNode, ExecuteSQL } from './page';
|
||||
import { DeleteOutlined, PlusOutlined } from '@ant-design/icons-vue';
|
||||
import { flowStore } from '@/store/modules/flow';
|
||||
import { SelectForm } from '@/components/SelectForm/index';
|
||||
|
|
@ -601,6 +611,7 @@
|
|||
formOpen: false,
|
||||
formVerisons: [],
|
||||
formName: '',
|
||||
SQLOpen: false,
|
||||
});
|
||||
|
||||
watch(
|
||||
|
|
@ -642,6 +653,8 @@
|
|||
return '节点';
|
||||
case '6':
|
||||
return '表字段';
|
||||
case '7':
|
||||
return 'SQL';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -669,10 +682,14 @@
|
|||
node.value.lookUsers = node.value.lookUsers.concat(addData2);
|
||||
updateWfData('lookUsers');
|
||||
} else {
|
||||
let addData = selectData.filter(
|
||||
(t) => node.value.auditUsers.findIndex((t2) => t2.id == t.id && t2.type == t.type) == -1,
|
||||
);
|
||||
node.value.auditUsers = node.value.auditUsers.concat(addData);
|
||||
if (selectData.type == 7) {
|
||||
node.value.auditUsers.push(selectData);
|
||||
} else {
|
||||
let addData = selectData.filter(
|
||||
(t) => node.value.auditUsers.findIndex((t2) => t2.id == t.id && t2.type == t.type) == -1,
|
||||
);
|
||||
node.value.auditUsers = node.value.auditUsers.concat(addData);
|
||||
}
|
||||
updateWfData('auditUsers');
|
||||
}
|
||||
}
|
||||
|
|
@ -739,6 +756,22 @@
|
|||
data.nodeOpen = false;
|
||||
}
|
||||
}
|
||||
// 执行SQL
|
||||
const executeSQLRef = ref<any>();
|
||||
|
||||
function handleSQLClick(isLooker) {
|
||||
nodeId.value = node.value.id;
|
||||
data.isLooker = isLooker;
|
||||
data.SQLOpen = true;
|
||||
}
|
||||
function executeSQLHandleOk() {
|
||||
executeSQLRef.value.validateForm();
|
||||
let obj = executeSQLRef.value.getForm();
|
||||
if (obj.Sql != '') {
|
||||
addTableData(obj);
|
||||
data.SQLOpen = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 数据表字段选择
|
||||
const sqlRef = ref<any>();
|
||||
|
|
@ -889,7 +922,6 @@
|
|||
obj.fieldName = element.componentProps.fieldName;
|
||||
fields.push(obj);
|
||||
} else if (['Grid'].includes(element.component) || element.type == 'subTable') {
|
||||
console.log('gridtable');
|
||||
fields.push({
|
||||
field: `${element.field}_add`,
|
||||
label: `${element.label || '表格'}-添加按钮`,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
export { default as AuditorLevel } from './src/auditorLevel.vue';
|
||||
export { default as AuditorSql } from './src/auditorSql.vue';
|
||||
export { default as AuditorNode } from './src/auditorNode.vue';
|
||||
export { default as ExecuteSQL } from './src/executeSQL.vue';
|
||||
|
|
|
|||
|
|
@ -0,0 +1,56 @@
|
|||
<template>
|
||||
<div class="l-from-body">
|
||||
<a-form
|
||||
ref="formRef"
|
||||
:rules="data.rules"
|
||||
:model="data.formData"
|
||||
labelAlign="left"
|
||||
:label-col="labelCol"
|
||||
:wrapper-col="wrapperCol"
|
||||
>
|
||||
<a-form-item label="SQL语句" name="Sql">
|
||||
<a-textarea v-model:value="data.formData.Sql" placeholder="SQL语句" :rows="4" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue';
|
||||
|
||||
const formRef = ref<any>();
|
||||
const labelCol = { span: 7 };
|
||||
const wrapperCol = { span: 17 };
|
||||
const data = reactive({
|
||||
formData: {
|
||||
Sql: '',
|
||||
type: '7',
|
||||
},
|
||||
rules: {
|
||||
Sql: [{ required: true, message: '请输入SQL语句' }],
|
||||
},
|
||||
});
|
||||
function validateForm() {
|
||||
formRef.value
|
||||
.validate()
|
||||
.then(async () => {
|
||||
return true;
|
||||
})
|
||||
.catch(async () => {
|
||||
return false;
|
||||
});
|
||||
}
|
||||
function getForm() {
|
||||
let rows = data.formData;
|
||||
rows.name = data.formData.Sql;
|
||||
return rows;
|
||||
}
|
||||
defineExpose({
|
||||
getForm,
|
||||
validateForm,
|
||||
});
|
||||
</script>
|
||||
<style scoped>
|
||||
.l-from-body {
|
||||
padding: 10px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,6 +1,10 @@
|
|||
import { withInstall } from '@/utils';
|
||||
import basicUpload from './src/BasicUpload.vue';
|
||||
import uploadImage from './src/components/ImageUpload.vue';
|
||||
import uploadVideo from './src/components/VideoUpload.vue';
|
||||
import uploadFile from './src/components/FileUpload.vue'
|
||||
|
||||
export const ImageUpload = withInstall(uploadImage);
|
||||
export const BasicUpload = withInstall(basicUpload);
|
||||
export const VideoUpload = withInstall(uploadVideo);
|
||||
export const FileUpload = withInstall(uploadFile);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,216 @@
|
|||
<template>
|
||||
<div>
|
||||
<UploadDragger
|
||||
v-bind="$attrs"
|
||||
:list-type="listType"
|
||||
:accept="getStringAccept"
|
||||
:multiple="multiple"
|
||||
:maxCount="maxNumber"
|
||||
:before-upload="beforeUpload"
|
||||
:custom-request="customRequest"
|
||||
@preview="handlePreview"
|
||||
@remove="handleRemove"
|
||||
>
|
||||
<!-- <div v-if="fileList && fileList.length < maxNumber">
|
||||
<plus-outlined />
|
||||
<div style="margin-top: 8px">{{ t('component.upload.upload') }}</div>
|
||||
</div> -->
|
||||
<p class="ant-upload-drag-icon">
|
||||
<inbox-outlined></inbox-outlined>
|
||||
</p>
|
||||
<p class="ant-upload-text">单击或拖动文件到此区域进行上传</p>
|
||||
<p class="ant-upload-hint">
|
||||
支持单次或批量上传。
|
||||
</p>
|
||||
|
||||
</UploadDragger>
|
||||
<Modal :open="previewOpen" :title="previewTitle" :footer="null" @cancel="handleCancel">
|
||||
<img alt="" style="width: 100%" :src="previewImage" />
|
||||
</Modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, toRefs, watch } from 'vue';
|
||||
import { PlusOutlined,InboxOutlined } from '@ant-design/icons-vue';
|
||||
import type { UploadFile, UploadProps } from 'ant-design-vue';
|
||||
import { Modal, UploadDragger } from 'ant-design-vue';
|
||||
import { UploadRequestOption } from 'ant-design-vue/lib/vc-upload/interface';
|
||||
import { useMessage } from '@/hooks/web/useMessage';
|
||||
import { isArray, isFunction, isObject, isString } from '@/utils/is';
|
||||
import { warn } from '@/utils/log';
|
||||
import { useI18n } from '@/hooks/web/useI18n';
|
||||
import { useUploadType } from '../hooks/useUpload';
|
||||
import { uploadContainerProps } from '../props';
|
||||
import { isImgTypeByName } from '../helper';
|
||||
import { UploadResultStatus } from '@/components/Upload/src/types/typing';
|
||||
import { fileUploadApi } from '@/api/sys/upload';
|
||||
|
||||
defineOptions({ name: 'ImageUpload' });
|
||||
|
||||
const emit = defineEmits(['change', 'update:value', 'delete']);
|
||||
const props = defineProps({
|
||||
...uploadContainerProps,
|
||||
});
|
||||
const { t } = useI18n();
|
||||
const { createMessage } = useMessage();
|
||||
const { accept, helpText, maxNumber, maxSize } = toRefs(props);
|
||||
const isInnerOperate = ref<boolean>(false);
|
||||
const { getStringAccept } = useUploadType({
|
||||
acceptRef: accept,
|
||||
helpTextRef: helpText,
|
||||
maxNumberRef: maxNumber,
|
||||
maxSizeRef: maxSize,
|
||||
});
|
||||
const previewOpen = ref<boolean>(false);
|
||||
const previewImage = ref<string>('');
|
||||
const previewTitle = ref<string>('');
|
||||
|
||||
const fileList = ref<UploadProps['fileList']>([]);
|
||||
const isLtMsg = ref<boolean>(true);
|
||||
const isActMsg = ref<boolean>(true);
|
||||
|
||||
watch(
|
||||
() => props.value,
|
||||
(v) => {
|
||||
if (isInnerOperate.value) {
|
||||
isInnerOperate.value = false;
|
||||
return;
|
||||
}
|
||||
if (v) {
|
||||
let value: string[] = [];
|
||||
if (isArray(v)) {
|
||||
value = v;
|
||||
} else {
|
||||
value.push(v);
|
||||
}
|
||||
fileList.value = value.map((item, i) => {
|
||||
if (item && isString(item)) {
|
||||
return {
|
||||
uid: -i + '',
|
||||
name: item.substring(item.lastIndexOf('/') + 1),
|
||||
status: 'done',
|
||||
url: item,
|
||||
};
|
||||
} else if (item && isObject(item)) {
|
||||
return item;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}) as UploadProps['fileList'];
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
function getBase64<T extends string | ArrayBuffer | null>(file: File) {
|
||||
return new Promise<T>((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
reader.readAsDataURL(file);
|
||||
reader.onload = () => {
|
||||
resolve(reader.result as T);
|
||||
};
|
||||
reader.onerror = (error) => reject(error);
|
||||
});
|
||||
}
|
||||
|
||||
const handlePreview = async (file: UploadFile) => {
|
||||
console.log("fileEEEEE",file);
|
||||
if (!file.url && !file.preview) {
|
||||
file.preview = await getBase64<string>(file.originFileObj!);
|
||||
}
|
||||
previewImage.value = file.url || file.preview || '';
|
||||
previewOpen.value = true;
|
||||
previewTitle.value =
|
||||
file.name || previewImage.value.substring(previewImage.value.lastIndexOf('/') + 1);
|
||||
};
|
||||
|
||||
const handleRemove = async (file: UploadFile) => {
|
||||
if (fileList.value) {
|
||||
const index = fileList.value.findIndex((item) => item.uid === file.uid);
|
||||
index !== -1 && fileList.value.splice(index, 1);
|
||||
const value = getValue();
|
||||
isInnerOperate.value = true;
|
||||
emit('change', value);
|
||||
emit('delete', file);
|
||||
}
|
||||
};
|
||||
|
||||
const handleCancel = () => {
|
||||
previewOpen.value = false;
|
||||
previewTitle.value = '';
|
||||
};
|
||||
|
||||
const beforeUpload = (file: File) => {
|
||||
const { maxSize, accept } = props;
|
||||
const { name } = file;
|
||||
const isAct = isImgTypeByName(name);
|
||||
if (!isAct) {
|
||||
createMessage.error(t('component.upload.acceptUpload', [accept]));
|
||||
isActMsg.value = false;
|
||||
// 防止弹出多个错误提示
|
||||
setTimeout(() => (isActMsg.value = true), 1000);
|
||||
}
|
||||
const isLt = file.size / 1024 / 1024 > maxSize;
|
||||
if (isLt) {
|
||||
createMessage.error(t('component.upload.maxSizeMultiple', [maxSize]));
|
||||
isLtMsg.value = false;
|
||||
// 防止弹出多个错误提示
|
||||
setTimeout(() => (isLtMsg.value = true), 1000);
|
||||
}
|
||||
return (isAct && !isLt) || Upload.LIST_IGNORE;
|
||||
};
|
||||
|
||||
async function customRequest(info: UploadRequestOption<any>) {
|
||||
const { api,server,action } = props;
|
||||
// if (!api || !isFunction(api)) {
|
||||
// return warn('upload api must exist and be a function');
|
||||
// }
|
||||
try {
|
||||
const res = await fileUploadApi?.({
|
||||
data: {
|
||||
...(props.uploadParams || {}),
|
||||
},
|
||||
file: info.file,
|
||||
name: props.name,
|
||||
filename: props.filename,
|
||||
});
|
||||
|
||||
fileList.value?.push({
|
||||
uid: '-1',
|
||||
name: info.file.name,
|
||||
status: 'done',
|
||||
url: server+"/"+res.data.result[0].filePath,
|
||||
})
|
||||
|
||||
// info.onSuccess!();
|
||||
const value = getValue();
|
||||
// isInnerOperate.value = true;
|
||||
emit('change', value);
|
||||
} catch (e: any) {
|
||||
info.onError!(e);
|
||||
}
|
||||
|
||||
console.log("fileList",fileList);
|
||||
}
|
||||
|
||||
function getValue() {
|
||||
let saveData = "";
|
||||
fileList.value.forEach((item,index)=>{
|
||||
item.url?.splice(server,"");
|
||||
saveData+=item.url+","
|
||||
})
|
||||
return saveData;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.ant-upload-select-picture-card i {
|
||||
color: #999;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
.ant-upload-select-picture-card .ant-upload-text {
|
||||
margin-top: 8px;
|
||||
color: #666;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,11 +1,22 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="video-item" v-for="(item,index) in fileList" :key="index">
|
||||
<div class="video-delete-btn" @click="handlerDelete(index)">
|
||||
<CloseOutlined/>
|
||||
</div>
|
||||
<a-image
|
||||
width="100px"
|
||||
:src="item.url"
|
||||
></a-image>
|
||||
</div>
|
||||
|
||||
|
||||
<Upload
|
||||
v-bind="$attrs"
|
||||
v-model:file-list="fileList"
|
||||
:list-type="listType"
|
||||
:accept="getStringAccept"
|
||||
:multiple="multiple"
|
||||
:showUploadList="false"
|
||||
:maxCount="maxNumber"
|
||||
:before-upload="beforeUpload"
|
||||
:custom-request="customRequest"
|
||||
|
|
@ -17,16 +28,18 @@
|
|||
<div style="margin-top: 8px">{{ t('component.upload.upload') }}</div>
|
||||
</div>
|
||||
</Upload>
|
||||
|
||||
<Modal :open="previewOpen" :title="previewTitle" :footer="null" @cancel="handleCancel">
|
||||
<img alt="" style="width: 100%" :src="previewImage" />
|
||||
</Modal>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, toRefs, watch } from 'vue';
|
||||
import { PlusOutlined } from '@ant-design/icons-vue';
|
||||
import type { UploadFile, UploadProps } from 'ant-design-vue';
|
||||
import { ref, toRefs, watch,reactive, onMounted } from 'vue';
|
||||
import { PlusOutlined,CloseOutlined } from '@ant-design/icons-vue';
|
||||
import type { UploadFile, UploadProps,UploadChangeParam } from 'ant-design-vue';
|
||||
import { Modal, Upload } from 'ant-design-vue';
|
||||
import { UploadRequestOption } from 'ant-design-vue/lib/vc-upload/interface';
|
||||
import { useMessage } from '@/hooks/web/useMessage';
|
||||
|
|
@ -37,6 +50,8 @@
|
|||
import { uploadContainerProps } from '../props';
|
||||
import { isImgTypeByName } from '../helper';
|
||||
import { UploadResultStatus } from '@/components/Upload/src/types/typing';
|
||||
import { actions } from '@/views/demo/page/account/center/data';
|
||||
import { fileUploadApi } from '@/api/sys/upload';
|
||||
|
||||
defineOptions({ name: 'ImageUpload' });
|
||||
|
||||
|
|
@ -46,29 +61,32 @@
|
|||
});
|
||||
const { t } = useI18n();
|
||||
const { createMessage } = useMessage();
|
||||
const { accept, helpText, maxNumber, maxSize } = toRefs(props);
|
||||
const { accept, helpText, maxNumber, maxSize} = toRefs(props);
|
||||
const isInnerOperate = ref<boolean>(false);
|
||||
const { getStringAccept } = useUploadType({
|
||||
acceptRef: accept,
|
||||
helpTextRef: helpText,
|
||||
maxNumberRef: maxNumber,
|
||||
maxSizeRef: maxSize,
|
||||
maxSizeRef: maxSize
|
||||
});
|
||||
|
||||
const previewOpen = ref<boolean>(false);
|
||||
const previewImage = ref<string>('');
|
||||
const previewTitle = ref<string>('');
|
||||
|
||||
const fileList = ref<UploadProps['fileList']>([]);
|
||||
const imageList = reactive([])
|
||||
const isLtMsg = ref<boolean>(true);
|
||||
const isActMsg = ref<boolean>(true);
|
||||
|
||||
|
||||
watch(
|
||||
() => props.value,
|
||||
(v) => {
|
||||
() => props.value,(v) => {
|
||||
if (isInnerOperate.value) {
|
||||
isInnerOperate.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (v) {
|
||||
let value: string[] = [];
|
||||
if (isArray(v)) {
|
||||
|
|
@ -76,6 +94,7 @@
|
|||
} else {
|
||||
value.push(v);
|
||||
}
|
||||
|
||||
fileList.value = value.map((item, i) => {
|
||||
if (item && isString(item)) {
|
||||
return {
|
||||
|
|
@ -90,35 +109,75 @@
|
|||
return;
|
||||
}
|
||||
}) as UploadProps['fileList'];
|
||||
|
||||
}
|
||||
|
||||
let arr = props.value?.split(",") as [];
|
||||
fileList.value = [];
|
||||
const { server } = props
|
||||
arr.forEach((item,index)=>{
|
||||
if(item){
|
||||
fileList.value?.push({
|
||||
uid: '-1',
|
||||
name: item,
|
||||
status: 'done',
|
||||
url: server+item
|
||||
})
|
||||
console.log("fileListItem",fileList.value)
|
||||
}
|
||||
})
|
||||
console.log("ImagefileList",fileList.value);
|
||||
|
||||
},
|
||||
);
|
||||
|
||||
function getBase64<T extends string | ArrayBuffer | null>(file: File) {
|
||||
return new Promise<T>((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
reader.readAsDataURL(file);
|
||||
reader.onload = () => {
|
||||
resolve(reader.result as T);
|
||||
};
|
||||
reader.onerror = (error) => reject(error);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// function getBase64<T extends string | ArrayBuffer | null>(file: File) {
|
||||
// return new Promise<T>((resolve, reject) => {
|
||||
// const reader = new FileReader();
|
||||
// reader.readAsDataURL(file);
|
||||
// reader.onload = () => {
|
||||
// resolve(reader.result as T);
|
||||
// };
|
||||
// reader.onerror = (error) => reject(error);
|
||||
// });
|
||||
// }
|
||||
|
||||
const handlePreview = async (file: UploadFile) => {
|
||||
const { server } = props
|
||||
if (!file.url && !file.preview) {
|
||||
file.preview = await getBase64<string>(file.originFileObj!);
|
||||
// file.preview = await getBase64<string>(file.originFileObj!);
|
||||
}
|
||||
previewImage.value = file.url || file.preview || '';
|
||||
console.log("file",file);
|
||||
previewOpen.value = true;
|
||||
previewTitle.value =
|
||||
file.name || previewImage.value.substring(previewImage.value.lastIndexOf('/') + 1);
|
||||
};
|
||||
|
||||
// const handleChange = (info: UploadChangeParam) => {
|
||||
// if (info.file.status === 'uploading') {
|
||||
// return;
|
||||
// }
|
||||
// if (info.file.status === 'done') {
|
||||
// console.log("donw",info);
|
||||
// }
|
||||
// if (info.file.status === 'error') {
|
||||
|
||||
// }
|
||||
// };
|
||||
const handlerDelete = (index) => {
|
||||
fileList.value.splice(index,1);
|
||||
let value = getValue();
|
||||
emit("change",value);
|
||||
}
|
||||
|
||||
const handleRemove = async (file: UploadFile) => {
|
||||
if (fileList.value) {
|
||||
const index = fileList.value.findIndex((item) => item.uid === file.uid);
|
||||
index !== -1 && fileList.value.splice(index, 1);
|
||||
|
||||
const value = getValue();
|
||||
isInnerOperate.value = true;
|
||||
emit('change', value);
|
||||
|
|
@ -152,36 +211,58 @@
|
|||
};
|
||||
|
||||
async function customRequest(info: UploadRequestOption<any>) {
|
||||
const { api } = props;
|
||||
if (!api || !isFunction(api)) {
|
||||
return warn('upload api must exist and be a function');
|
||||
}
|
||||
|
||||
const { api,server,action } = props;
|
||||
|
||||
// if (!api || !isFunction(api)) {
|
||||
// return warn('upload api must exist and be a function');
|
||||
// }
|
||||
|
||||
try {
|
||||
const res = await props.api?.({
|
||||
const res = await fileUploadApi?.({
|
||||
data: {
|
||||
...(props.uploadParams || {}),
|
||||
},
|
||||
file: info.file,
|
||||
name: props.name,
|
||||
filename: props.filename,
|
||||
});
|
||||
info.onSuccess!(res.data);
|
||||
},server+action);
|
||||
|
||||
|
||||
fileList.value?.push({
|
||||
uid: '-1',
|
||||
name: info.file.name,
|
||||
status: 'done',
|
||||
url: server+"/"+res.data.result[0].filePath,
|
||||
})
|
||||
|
||||
info.onSuccess!();
|
||||
const value = getValue();
|
||||
isInnerOperate.value = true;
|
||||
// isInnerOperate.value = true;
|
||||
emit('change', value);
|
||||
} catch (e: any) {
|
||||
console.log(e);
|
||||
info.onError!(e);
|
||||
}
|
||||
}
|
||||
|
||||
function getValue() {
|
||||
const list = (fileList.value || [])
|
||||
.filter((item) => item?.status === UploadResultStatus.DONE)
|
||||
.map((item: any) => {
|
||||
return item?.url || item?.response?.url;
|
||||
});
|
||||
return props.multiple ? list : list.length > 0 ? list[0] : '';
|
||||
// fileList.value.forEach((item,index)=>{
|
||||
// item.url?.splice(server,"");
|
||||
// saveData+=item.url+","
|
||||
// })
|
||||
// return saveData;
|
||||
let path = "";
|
||||
const {server} = props;
|
||||
fileList.value?.forEach((item,index)=>{
|
||||
path+=item.url?.replace(server,"")+",";
|
||||
})
|
||||
return path;
|
||||
// const list = (fileList.value || [])
|
||||
// .filter((item) => item?.status === UploadResultStatus.DONE)
|
||||
// .map((item: any) => {
|
||||
// return item?.url || item?.response?.url;
|
||||
// });
|
||||
// return props.multiple ? list : list.length > 0 ? list[0] : '';
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
@ -195,4 +276,33 @@
|
|||
margin-top: 8px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.video-item{
|
||||
position:relative;
|
||||
width:100px;
|
||||
height:100px;
|
||||
margin-right:10px;
|
||||
margin-bottom:10px;
|
||||
float:left;
|
||||
overflow: hidden;
|
||||
border-radius: 6px;
|
||||
background:#fff;
|
||||
text-align: center;
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
.video-delete-btn{
|
||||
position:absolute;
|
||||
top:-5px;
|
||||
right:-5px;
|
||||
width:30px;
|
||||
height:30px;
|
||||
border-bottom-left-radius: 80%;
|
||||
background:rgb(0 0 0 / 20%);
|
||||
color:#fff;
|
||||
line-height: 30px;
|
||||
text-align: center;
|
||||
z-index:999999999999;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -187,7 +187,7 @@
|
|||
item.percent = complete;
|
||||
},
|
||||
);
|
||||
let data = ret != undefined ? ret.data : {};
|
||||
const { data } = ret;
|
||||
item.status = UploadResultStatus.SUCCESS;
|
||||
item.response = data;
|
||||
return {
|
||||
|
|
@ -206,7 +206,9 @@
|
|||
|
||||
// 点击开始上传
|
||||
async function handleStartUpload() {
|
||||
const { maxNumber } = props;
|
||||
|
||||
const { maxNumber,action } = props;
|
||||
alert(action);
|
||||
if ((fileListRef.value.length + props.previewFileList?.length ?? 0) > maxNumber) {
|
||||
return createMessage.warning(t('component.upload.maxNumber', [maxNumber]));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,300 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="video-item" v-for="(item,index) in fileList" :key="index">
|
||||
<div class="video-delete-btn" @click="handlerDelete(index)">
|
||||
<CloseOutlined/>
|
||||
</div>
|
||||
<img src="./video.png" @click="handlePreview(item)" alt="">
|
||||
<p>{{ item.name}}</p>
|
||||
</div>
|
||||
|
||||
<Upload
|
||||
v-bind="$attrs"
|
||||
:list-type="listType"
|
||||
:accept="getStringAccept"
|
||||
:multiple="multiple"
|
||||
:showUploadList="false"
|
||||
:maxCount="maxNumber"
|
||||
:before-upload="beforeUpload"
|
||||
:custom-request="customRequest"
|
||||
@preview="handlePreview"
|
||||
@remove="handleRemove"
|
||||
>
|
||||
<div v-if="fileList && fileList.length < maxNumber">
|
||||
<plus-outlined />
|
||||
<div style="margin-top: 8px">{{ t('component.upload.upload') }}</div>
|
||||
</div>
|
||||
</Upload>
|
||||
|
||||
<Modal :open="previewOpen" :title="previewTitle" :footer="null" @cancel="handleCancel">
|
||||
<!-- <img alt="" style="width: 100%" :src="previewImage" /> -->
|
||||
<video :src="previewImage" class="video-player" controls muted autoplay></video>
|
||||
</Modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, toRefs, watch,reactive, onMounted } from 'vue';
|
||||
import { PlusOutlined,CloseOutlined } from '@ant-design/icons-vue';
|
||||
import type { UploadFile, UploadProps } from 'ant-design-vue';
|
||||
import { Modal, Upload } from 'ant-design-vue';
|
||||
import { UploadRequestOption } from 'ant-design-vue/lib/vc-upload/interface';
|
||||
import { useMessage } from '@/hooks/web/useMessage';
|
||||
import { isArray, isFunction, isObject, isString } from '@/utils/is';
|
||||
import { warn } from '@/utils/log';
|
||||
import { useI18n } from '@/hooks/web/useI18n';
|
||||
import { useUploadType } from '../hooks/useUpload';
|
||||
import { uploadContainerProps } from '../props';
|
||||
import { isVideoTypeByName } from '../helper';
|
||||
import { UploadResultStatus } from '@/components/Upload/src/types/typing';
|
||||
import { fileUploadApi } from '@/api/sys/upload';
|
||||
|
||||
defineOptions({ name: 'VideoUpload' });
|
||||
|
||||
const emit = defineEmits(['change', 'update:value', 'delete']);
|
||||
const props = defineProps({
|
||||
...uploadContainerProps,
|
||||
});
|
||||
const { t } = useI18n();
|
||||
const { createMessage } = useMessage();
|
||||
const { accept, helpText, maxNumber, maxSize } = toRefs(props);
|
||||
const isInnerOperate = ref<boolean>(false);
|
||||
const { getStringAccept } = useUploadType({
|
||||
acceptRef: accept,
|
||||
helpTextRef: helpText,
|
||||
maxNumberRef: maxNumber,
|
||||
maxSizeRef: maxSize,
|
||||
});
|
||||
const previewOpen = ref<boolean>(false);
|
||||
const previewImage = ref<string>('');
|
||||
const previewTitle = ref<string>('');
|
||||
|
||||
const fileList = ref<UploadProps['fileList']>([]);
|
||||
const isLtMsg = ref<boolean>(true);
|
||||
const isActMsg = ref<boolean>(true);
|
||||
|
||||
const showUploadList = reactive({
|
||||
showRemoveIcon: true,
|
||||
showPreviewIcon: true
|
||||
})
|
||||
|
||||
|
||||
watch(
|
||||
() => props.value,
|
||||
(v) => {
|
||||
if (isInnerOperate.value) {
|
||||
isInnerOperate.value = false;
|
||||
return;
|
||||
}
|
||||
if (v) {
|
||||
let value: string[] = [];
|
||||
if (isArray(v)) {
|
||||
value = v;
|
||||
} else {
|
||||
value.push(v);
|
||||
}
|
||||
fileList.value = value.map((item, i) => {
|
||||
if (item && isString(item)) {
|
||||
return {
|
||||
uid: -i + '',
|
||||
name: item.substring(item.lastIndexOf('/') + 1),
|
||||
status: 'done',
|
||||
url: item,
|
||||
};
|
||||
} else if (item && isObject(item)) {
|
||||
return item;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}) as UploadProps['fileList'];
|
||||
}
|
||||
let arr = props.value?.split(",") as [];
|
||||
fileList.value = [];
|
||||
const { server } = props
|
||||
arr.forEach((item,index)=>{
|
||||
if(item){
|
||||
fileList.value?.push({
|
||||
uid: '-1',
|
||||
name: item,
|
||||
status: 'done',
|
||||
url: server+item
|
||||
})
|
||||
console.log("fileListItem",fileList.value)
|
||||
}
|
||||
})
|
||||
console.log("fileList",fileList.value);
|
||||
},
|
||||
);
|
||||
|
||||
onMounted(()=>{
|
||||
|
||||
})
|
||||
|
||||
function getBase64<T extends string | ArrayBuffer | null>(file: File) {
|
||||
return new Promise<T>((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
reader.readAsDataURL(file);
|
||||
reader.onload = () => {
|
||||
resolve(reader.result as T);
|
||||
};
|
||||
reader.onerror = (error) => reject(error);
|
||||
});
|
||||
}
|
||||
|
||||
const handlePreview = async (file: UploadFile) => {
|
||||
|
||||
previewImage.value = file.url || file.preview || '';
|
||||
previewOpen.value = true;
|
||||
previewTitle.value =
|
||||
file.name || previewImage.value.substring(previewImage.value.lastIndexOf('/') + 1);
|
||||
};
|
||||
|
||||
const handlerDelete = (index) => {
|
||||
fileList.value.splice(index,1);
|
||||
let value = getValue();
|
||||
emit("change",value);
|
||||
}
|
||||
|
||||
const handleRemove = async (file: UploadFile) => {
|
||||
if (fileList.value) {
|
||||
const index = fileList.value.findIndex((item) => item.uid === file.uid);
|
||||
index !== -1 && fileList.value.splice(index, 1);
|
||||
const value = getValue();
|
||||
isInnerOperate.value = true;
|
||||
emit('change', value);
|
||||
emit('delete', file);
|
||||
}
|
||||
};
|
||||
|
||||
const handleCancel = () => {
|
||||
previewOpen.value = false;
|
||||
previewTitle.value = '';
|
||||
};
|
||||
|
||||
const beforeUpload = (file: File) => {
|
||||
const { maxSize, accept } = props;
|
||||
const { name } = file;
|
||||
const isAct = isVideoTypeByName(name);
|
||||
if (!isAct) {
|
||||
createMessage.error(t('component.upload.acceptUpload', [accept]));
|
||||
isActMsg.value = false;
|
||||
// 防止弹出多个错误提示
|
||||
setTimeout(() => (isActMsg.value = true), 1000);
|
||||
}
|
||||
const isLt = file.size / 1024 / 1024 > maxSize;
|
||||
if (isLt) {
|
||||
createMessage.error(t('component.upload.maxSizeMultiple', [maxSize]));
|
||||
isLtMsg.value = false;
|
||||
// 防止弹出多个错误提示
|
||||
setTimeout(() => (isLtMsg.value = true), 1000);
|
||||
}
|
||||
return (isAct && !isLt) || Upload.LIST_IGNORE;
|
||||
};
|
||||
|
||||
async function customRequest(info: UploadRequestOption<any>) {
|
||||
const { api,action,server } = props;
|
||||
|
||||
|
||||
// if (!api || !isFunction(api)) {
|
||||
// return warn('upload api must exist and be a function');
|
||||
// }
|
||||
try {
|
||||
const res = await fileUploadApi?.({
|
||||
data: {
|
||||
...(props.uploadParams || {}),
|
||||
},
|
||||
file: info.file,
|
||||
name: props.name,
|
||||
filename: props.filename,
|
||||
},server+action);
|
||||
|
||||
|
||||
fileList.value?.push({
|
||||
uid: '-1',
|
||||
name: info.file.name,
|
||||
status: 'done',
|
||||
url: server+"/"+res.data.result[0].filePath,
|
||||
})
|
||||
|
||||
// info.onSuccess!();
|
||||
|
||||
const value = getValue();
|
||||
|
||||
isInnerOperate.value = true;
|
||||
emit('change', value);
|
||||
} catch (e: any) {
|
||||
info.onError!(e);
|
||||
}
|
||||
}
|
||||
|
||||
function getValue() {
|
||||
const { server } = props;
|
||||
let saveData = "";
|
||||
fileList.value.forEach((item,index)=>{
|
||||
console.log("fileListItem",item);
|
||||
saveData+=item.url?.replace(server,"")+","
|
||||
})
|
||||
return saveData;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.ant-upload-select-picture-card i {
|
||||
color: #999;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
.ant-upload-select-picture-card .ant-upload-text {
|
||||
margin-top: 8px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.video-item{
|
||||
position:relative;
|
||||
width:100px;
|
||||
height:100px;
|
||||
margin-right:10px;
|
||||
margin-bottom:10px;
|
||||
float:left;
|
||||
overflow: hidden;
|
||||
border-radius: 6px;
|
||||
background:#fff;
|
||||
text-align: center;
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
.video-delete-btn{
|
||||
position:absolute;
|
||||
top:-5px;
|
||||
right:-5px;
|
||||
width:30px;
|
||||
height:30px;
|
||||
border-bottom-left-radius: 80%;
|
||||
background:rgb(0 0 0 / 20%);
|
||||
color:#fff;
|
||||
line-height: 30px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.video-item img{
|
||||
width:80px;
|
||||
height:80px;
|
||||
}
|
||||
|
||||
.video-item p{
|
||||
overflow: hidden;
|
||||
color:#777!important;
|
||||
font-size:12px;
|
||||
text-overflow:ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.ant-upload-wrapper {
|
||||
width:100px!important;
|
||||
}
|
||||
|
||||
.video-player{
|
||||
width:500px;
|
||||
margin:10px;
|
||||
}
|
||||
</style>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 54 KiB |
|
|
@ -14,6 +14,11 @@ export function isImgTypeByName(name: string) {
|
|||
return /\.(jpg|jpeg|png|gif|webp)$/i.test(name);
|
||||
}
|
||||
|
||||
|
||||
export function isVideoTypeByName(name: string) {
|
||||
return /\.(mp4|mov|avi)$/i.test(name);
|
||||
}
|
||||
|
||||
export function getBase64WithFile(file: File) {
|
||||
return new Promise<{
|
||||
result: string;
|
||||
|
|
|
|||
|
|
@ -24,6 +24,14 @@ export const basicProps = {
|
|||
type: String as PropType<string>,
|
||||
default: '',
|
||||
},
|
||||
action: {
|
||||
type: String as PropType<string>,
|
||||
default: '',
|
||||
},
|
||||
server: {
|
||||
type: String as PropType<string>,
|
||||
default: '',
|
||||
},
|
||||
// 文件最大多少MB
|
||||
maxSize: {
|
||||
type: Number as PropType<number>,
|
||||
|
|
@ -54,7 +62,7 @@ export const basicProps = {
|
|||
},
|
||||
name: {
|
||||
type: String as PropType<string>,
|
||||
default: 'file',
|
||||
default: 'files',
|
||||
},
|
||||
filename: {
|
||||
type: String as PropType<string>,
|
||||
|
|
@ -64,7 +72,6 @@ export const basicProps = {
|
|||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
|
||||
fileListDragOptions: {
|
||||
type: Object as PropType<SortableOptions>,
|
||||
default: () => ({}),
|
||||
|
|
|
|||
|
|
@ -124,5 +124,9 @@
|
|||
"redoTip": "点击图片可刷新",
|
||||
"dragText": "请按住滑块拖动",
|
||||
"successText": "验证通过"
|
||||
},
|
||||
"map":{
|
||||
"refreshSuccess":"获取位置成功!",
|
||||
"refreshError":"获取位置失败!"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
|
||||
import MapboxMaps from '@/components/MapboxMaps/MapboxMap.vue';
|
||||
// import MapboxMaps from '@/components/MapboxMaps/MapComponent.vue';
|
||||
import {ref,reactive} from 'vue';
|
||||
import { DrawingType } from '@/enums/mapEnum';
|
||||
|
||||
|
|
@ -27,7 +28,7 @@
|
|||
const layers = reactive([
|
||||
{
|
||||
id:1,
|
||||
name:"沂水县道路中心线1",
|
||||
name:"沂水县道路中心线",
|
||||
checked:false,
|
||||
layer:{
|
||||
'id': 'roadnetLine1',
|
||||
|
|
@ -58,39 +59,6 @@
|
|||
'line-width': 1
|
||||
}
|
||||
}
|
||||
},{
|
||||
id:2,
|
||||
name:"沂水县道路中心线2",
|
||||
checked:false,
|
||||
layer:{
|
||||
'id': 'roadnetLine2',
|
||||
'type': 'line',
|
||||
'source': {
|
||||
type: 'vector',
|
||||
tiles: [ 'http://192.168.10.102:9020/api/DroneCaseinfo/QueryVectorTileByTable?z={z}&x={x}&y={y}&table=yishuixian&X-Token=1ded3fe7'],
|
||||
minzoom: 1,
|
||||
maxzoom: 20
|
||||
},
|
||||
"source-layer": "yishuixian",
|
||||
'layout': {
|
||||
'line-join': 'round',
|
||||
'line-cap': 'round'
|
||||
},
|
||||
'paint': {
|
||||
'line-color': [
|
||||
"case",
|
||||
["==", ["get", "handle_status_id"], 0],
|
||||
"#E6A23C",
|
||||
["==", ["get", "handle_status_id"], 1],
|
||||
"#409EFF",
|
||||
["==", ["get", "handle_status_id"], 2],
|
||||
"#67C23A",
|
||||
// 默认
|
||||
"#E6A23C",
|
||||
],
|
||||
'line-width': 1
|
||||
}
|
||||
}
|
||||
}
|
||||
])
|
||||
|
||||
|
|
@ -104,12 +72,11 @@
|
|||
// const feature ="LINESTRING (118.55483239594203 35.81329409678203, 118.54889167836416 35.806406839795216, 118.55647247134772 35.80285975465173, 118.56157492816281 35.803303140294986)"
|
||||
|
||||
// const feature = "POLYGON ((118.54774514802972 35.80786133598188, 118.54515277045988 35.79816597053564, 118.55919536113471 35.80085134034624, 118.56021460056033 35.80462789316549, 118.5595188628206 35.80695604583504, 118.5580066425723 35.80815336506183, 118.54774514802972 35.80786133598188))"
|
||||
|
||||
|
||||
let drawFeatures = [
|
||||
{
|
||||
"columnName": "mapgeom",
|
||||
"value": "POLYGON ((118.55901684631719 35.8045110934671, 118.55946931550466 35.80449259041045, 118.55946551324392 35.80463444717644, 118.559024450841 35.80464061486234, 118.55901684631719 35.8045110934671))"
|
||||
"value": "MULTIPOLYGON (((118.55901684631719 35.8045110934671, 118.55946931550466 35.80449259041045, 118.55946551324392 35.80463444717644, 118.559024450841 35.80464061486234, 118.55901684631719 35.8045110934671)))"
|
||||
}, {
|
||||
"columnName": "mapgeom",
|
||||
"value": "POLYGON ((118.5591119028685 35.804344565958516, 118.5594579087177 35.804344565958516, 118.55945410645693 35.80424279914757, 118.55910049608158 35.80423663146167, 118.5591119028685 35.804344565958516))"
|
||||
|
|
@ -139,25 +106,21 @@ let drawFeatures = [
|
|||
|
||||
|
||||
setTimeout(function(){
|
||||
MapboxComponent.value.handlerDraw()
|
||||
// MapboxComponent.value.handlerDraw()
|
||||
},6000)
|
||||
|
||||
// 图斑定位
|
||||
setTimeout(function(){
|
||||
MapboxComponent.value.handlerLocation([118.556717,35.80391]);
|
||||
},6000)
|
||||
|
||||
|
||||
// setTimeout(function(){
|
||||
// MapboxComponent.value.handlerLocation([118.556717,35.80391]);
|
||||
// },6000)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const mapDrawControl: DrawingType[] = [DrawingType.Polygon, DrawingType.Line];
|
||||
const mapOnLoad = (map) => {
|
||||
|
||||
//
|
||||
|
||||
|
||||
// map 对象
|
||||
console.log('map::: ', map);
|
||||
// mapU封装对象
|
||||
|
|
|
|||
|
|
@ -162,12 +162,38 @@
|
|||
let subTableId = ref(null);
|
||||
let subTableData = ref([]);
|
||||
let subTableList = ref([]);
|
||||
const setSubTableData = (dataList) => {
|
||||
dataList.forEach((item) => {
|
||||
if (item.type === 'subTable') {
|
||||
subTableId.value = item.field;
|
||||
let tableData = [];
|
||||
item.columns.forEach((itemColumn) => {
|
||||
|
||||
// if (props.formConfig.schemas) {
|
||||
// props.formConfig.schemas.forEach((item) => {
|
||||
// if (item.type === 'subTable') {
|
||||
// subTableId.value = item.field;
|
||||
// let tableData = [];
|
||||
// item.columns.forEach((itemColumn) => {
|
||||
// itemColumn.children.forEach((itemColumnChild) => {
|
||||
// tableData.push(itemColumnChild);
|
||||
// subTableColumns.value.push({
|
||||
// key: itemColumnChild.field,
|
||||
// title: itemColumnChild.label,
|
||||
// dataIndex: itemColumnChild.field,
|
||||
// width: 120,
|
||||
// ...itemColumnChild,
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// scrollValue.value = { x: (subTableColumns.value.length - 1) * 140, y: 300 };
|
||||
// subTableData.value = tableData;
|
||||
// }else{
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
console.log("props.schema",props.schema)
|
||||
|
||||
if (props.schema) {
|
||||
if(props.schema.type === "subTable"){
|
||||
subTableId.value = props.schema.field
|
||||
let tableData = [];
|
||||
props.schema.columns.forEach((itemColumn) => {
|
||||
itemColumn.children.forEach((itemColumnChild) => {
|
||||
tableData.push(itemColumnChild);
|
||||
subTableColumns.value.push({
|
||||
|
|
@ -181,14 +207,7 @@
|
|||
});
|
||||
scrollValue.value = { x: (subTableColumns.value.length - 1) * 140, y: 300 };
|
||||
subTableData.value = tableData;
|
||||
}else if(item.columns){
|
||||
setSubTableData(item.columns[0].children)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (props.formConfig.schemas) {
|
||||
setSubTableData(props.formConfig.schemas)
|
||||
}
|
||||
}
|
||||
|
||||
const addListItem = () => {
|
||||
|
|
@ -207,6 +226,9 @@
|
|||
const delListItem = (column, record) => {
|
||||
subTableList.value = subTableList.value.filter((item) => item.key != record.key);
|
||||
};
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@
|
|||
/>
|
||||
</FormItem>
|
||||
<FormItem label="脚本" v-if="['Button'].includes(formConfig.currentItem.component)">
|
||||
<a-button type="primary" size="mini" @click="handleButtonClick"> 点击脚本 </a-button>
|
||||
<a-button size="mini" @click="handleButtonClick"> 点击脚本 </a-button>
|
||||
</FormItem>
|
||||
|
||||
<FormItem
|
||||
|
|
@ -283,9 +283,9 @@
|
|||
watch(
|
||||
() => formConfig.value.currentItem?.field,
|
||||
(_newValue, oldValue) => {
|
||||
currentIndex.value = formConfig.value.schemas.findIndex(
|
||||
(element) => element.field === formConfig.value.currentItem.field,
|
||||
);
|
||||
// currentIndex.value = formConfig.value.schemas.findIndex(
|
||||
// (element) => element.field === formConfig.value.currentItem.field,
|
||||
// );
|
||||
formConfig.value.schemas &&
|
||||
formItemsForEach(formConfig.value.schemas, (item) => {
|
||||
if (item.link) {
|
||||
|
|
@ -310,9 +310,9 @@
|
|||
() => formConfig.value.currentItem && formConfig.value.currentItem.component,
|
||||
() => {
|
||||
// console.log(formConfig.value);
|
||||
currentIndex.value = formConfig.value.schemas.findIndex(
|
||||
(element) => element.field === formConfig.value.currentItem.field,
|
||||
);
|
||||
// currentIndex.value = formConfig.value.schemas.findIndex(
|
||||
// (element) => element.field === formConfig.value.currentItem.field,
|
||||
// );
|
||||
allOptions.value = [];
|
||||
baseComponentControlAttrs.forEach((item) => {
|
||||
item.category = 'control';
|
||||
|
|
@ -378,7 +378,8 @@
|
|||
let arr = allOptions.value.filter((item) => {
|
||||
return item.category == 'input';
|
||||
});
|
||||
|
||||
console.log(arr);
|
||||
console.log(currentIndex.value);
|
||||
arr.forEach((item) => {
|
||||
if (item.name == 'dataTable') {
|
||||
if (currentIndex.value == -1) {
|
||||
|
|
|
|||
|
|
@ -76,7 +76,6 @@
|
|||
<a-space direction="vertical">
|
||||
<a-button
|
||||
v-model:value="formConfig.beforeSetData"
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click="handleBtnClick('beforeSetData')"
|
||||
>
|
||||
|
|
@ -84,7 +83,6 @@
|
|||
</a-button>
|
||||
<a-button
|
||||
v-model:value="formConfig.afterValidateForm"
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click="handleBtnClick('afterValidateForm')"
|
||||
>
|
||||
|
|
@ -92,7 +90,6 @@
|
|||
</a-button>
|
||||
<a-button
|
||||
v-model:value="formConfig.afterSaveEvent"
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click="handleBtnClick('afterSaveEvent')"
|
||||
>
|
||||
|
|
@ -100,7 +97,6 @@
|
|||
</a-button>
|
||||
<a-button
|
||||
v-model:value="formConfig.changeDataEvent"
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click="handleBtnClick('changeDataEvent')"
|
||||
>
|
||||
|
|
@ -209,11 +205,9 @@
|
|||
}
|
||||
// 脚本窗口提交
|
||||
function handleSubmit() {
|
||||
if (formContent.value.indexOf('=>') != -1) {
|
||||
// 表示是老版本,提示其修改为新的版本
|
||||
message.warning('脚本没有更新为最新的版本!');
|
||||
if (!checkChinese(formContent.value)) {
|
||||
message.warning('脚本的代码部分不能含有中文字符!');
|
||||
return;
|
||||
// } else if() {
|
||||
}
|
||||
if (btnClickEvent_now) {
|
||||
if (btnClickEvent_now == 'beforeSetData') {
|
||||
|
|
@ -228,6 +222,33 @@
|
|||
}
|
||||
closeModal();
|
||||
}
|
||||
|
||||
function checkChinese(str) {
|
||||
// 分割字符串为多行
|
||||
const lines = str.split('\n');
|
||||
let flag = true;
|
||||
|
||||
// 遍历每一行
|
||||
for (const line of lines) {
|
||||
// 先检查并移除console.log及其后的内容
|
||||
const consoleIndex = line.indexOf('console.log');
|
||||
let partToCheck = line;
|
||||
if (consoleIndex !== -1) {
|
||||
partToCheck = line.substring(0, consoleIndex).trim(); // 移除console.log及其后的内容,并去掉前导空格
|
||||
}
|
||||
|
||||
// 再检查'//'
|
||||
const commentIndex = partToCheck.indexOf('//');
|
||||
// 如果有'//',检查'//'前的部分并去掉前导空格;如果没有,保留原部分
|
||||
partToCheck =
|
||||
commentIndex !== -1 ? partToCheck.substring(0, commentIndex).trim() : partToCheck;
|
||||
// 代码部分不能含有中文字符
|
||||
if (!/[\u4e00-\u9fa5]/.test(partToCheck)) {
|
||||
flag = false;
|
||||
}
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
|
|
|||
|
|
@ -1146,6 +1146,57 @@ const componentAttrs: IBaseComponentProps = {
|
|||
component: 'Input',
|
||||
},
|
||||
],
|
||||
ImageUpload: [
|
||||
{
|
||||
name: 'server',
|
||||
label: '文件服务器地址',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
name: 'action',
|
||||
label: '文件上传接口',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
name: 'name',
|
||||
label: '附件参数名',
|
||||
component: 'Input',
|
||||
},
|
||||
],
|
||||
VideoUpload: [
|
||||
{
|
||||
name: 'server',
|
||||
label: '文件服务器地址',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
name: 'action',
|
||||
label: '文件上传接口',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
name: 'name',
|
||||
label: '附件参数名',
|
||||
component: 'Input',
|
||||
},
|
||||
],
|
||||
FileUpload: [
|
||||
{
|
||||
name: 'server',
|
||||
label: '文件服务器地址',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
name: 'action',
|
||||
label: '文件上传接口',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
name: 'name',
|
||||
label: '附件参数名',
|
||||
component: 'Input',
|
||||
},
|
||||
],
|
||||
// ColorPicker: [
|
||||
// {
|
||||
// name: 'defaultValue',
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@
|
|||
* @param jsonData
|
||||
*/
|
||||
const showModal = (jsonData: IFormConfig) => {
|
||||
console.log("formModel",state.formModel);
|
||||
console.log('showModal-', jsonData);
|
||||
formatRules(jsonData.schemas);
|
||||
state.formConfig = jsonData as any;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { IVFormComponent } from '../typings/v-form-component';
|
|||
import { isArray } from 'lodash-es';
|
||||
import { componentMap as VbenCmp, add } from '@/components/Form/src/componentMap';
|
||||
import { ComponentType } from '@/components/Form/src/types';
|
||||
|
||||
import { uploadApi,fileUploadApi } from '@/api/sys/upload';
|
||||
import { componentMap as Cmp } from '../components';
|
||||
import { Component } from 'vue';
|
||||
import { getDeptList, getAccountList, getPosGroupList } from '@/api/demo/system';
|
||||
|
|
@ -532,7 +532,63 @@ export const baseComponents: IVFormComponent[] = [
|
|||
colProps: { span: 24 },
|
||||
field: '',
|
||||
componentProps: {},
|
||||
},
|
||||
},{
|
||||
component: 'FileUpload',
|
||||
label: '文件上传',
|
||||
icon: 'ant-design:file-add-outlined',
|
||||
field: '',
|
||||
colProps: { span: 24 },
|
||||
componentProps: {
|
||||
api:uploadApi,
|
||||
maxNumber:10,
|
||||
maxSize: 2,
|
||||
name:"files",
|
||||
action:"/api/Files/Upload",
|
||||
server:"http://221.2.83.254:9001"
|
||||
},
|
||||
},{
|
||||
component: 'ImageUpload',
|
||||
label: '图片上传',
|
||||
icon: 'ant-design:file-image-outlined',
|
||||
field: '',
|
||||
colProps: { span: 24 },
|
||||
componentProps: {
|
||||
api:fileUploadApi,
|
||||
maxNumber:10,
|
||||
accept: ['png', 'jpeg', 'jpg'],
|
||||
maxSize: 2,
|
||||
name:"files",
|
||||
action:"/api/Files/Upload",
|
||||
server:"http://192.168.10.102:9023"
|
||||
},
|
||||
},{
|
||||
component: 'VideoUpload',
|
||||
label: '视频上传',
|
||||
icon: 'ant-design:video-camera-outlined',
|
||||
field: '',
|
||||
colProps: { span: 24 },
|
||||
componentProps: {
|
||||
api:fileUploadApi,
|
||||
maxNumber:10,
|
||||
accept: ['mp4', 'mov', 'avi'],
|
||||
maxSize: 100,
|
||||
name:"files",
|
||||
action:"/api/Files/Upload",
|
||||
server:"http://192.168.10.102:9023"
|
||||
},
|
||||
},{
|
||||
component: 'Location',
|
||||
label: '获取位置',
|
||||
icon: 'ant-design:environment-outlined',
|
||||
field: '',
|
||||
colProps: { span: 24 },
|
||||
componentProps: {
|
||||
api:()=>1,
|
||||
maxNumber:10,
|
||||
accept: ['mp4', 'mov', 'avi'],
|
||||
maxSize: 100,
|
||||
},
|
||||
}
|
||||
];
|
||||
|
||||
// https://next.antdv.com/components/transfer-cn
|
||||
|
|
|
|||
|
|
@ -14,7 +14,12 @@
|
|||
<template v-if="tabsColumns.length > 1">
|
||||
<a-tabs style="width: 100%" @change="tabsChange">
|
||||
<a-tab-pane v-for="(colItem, index) in tabsColumns" :tab="colItem.label" :key="index">
|
||||
<BasicForm ref="myDataBaseFormRef" @register="registerForm" />
|
||||
<BasicForm
|
||||
ref="myDataBaseFormRef"
|
||||
@register="registerForm"
|
||||
@click="codeClickFunction('beforeSetData', beforeSetData)"
|
||||
@change="codeClickFunction('changeDataEvent', changeDataEvent)"
|
||||
/>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</template>
|
||||
|
|
@ -23,6 +28,8 @@
|
|||
ref="myDataBaseFormRef"
|
||||
@register="registerForm"
|
||||
v-if="formModalVisible && tabsColumns.length < 1"
|
||||
@click="codeClickFunction('beforeSetData', beforeSetData)"
|
||||
@change="codeClickFunction('changeDataEvent', changeDataEvent)"
|
||||
/>
|
||||
<template v-for="(item, index) in cardLayout" :key="index">
|
||||
<a-row style="width: 100%">
|
||||
|
|
@ -44,6 +51,20 @@
|
|||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
<template v-for="(item, index) in buttonLayout" :key="index">
|
||||
<a-row style="width: 100%">
|
||||
<a-col :span="item?.colProps?.span || 24" style="padding: 10px">
|
||||
<a-button
|
||||
:type="item.componentProps.type"
|
||||
:shape="item.componentProps.shape"
|
||||
:size="item.componentProps.size"
|
||||
@click="codeClickFunction('codeClick', item.componentProps.clickCode)"
|
||||
>
|
||||
{{ item.label }}
|
||||
</a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
<a-table
|
||||
class="sub-table"
|
||||
:columns="subTableColumns"
|
||||
|
|
@ -86,6 +107,7 @@
|
|||
import { v4 as uuidv4 } from 'uuid';
|
||||
import FormItem from './ShowFormModal/FormItem/index.vue';
|
||||
import CallModalFormItem from './CallModalFormItem/index.vue';
|
||||
|
||||
// import FormRender from '@/views/demo/form-design/components/VFormCreate/components/FormRender.vue';
|
||||
|
||||
const emit = defineEmits(['success']);
|
||||
|
|
@ -112,8 +134,21 @@
|
|||
const scrollValue = ref();
|
||||
const cardLayout = ref([]);
|
||||
const createOrModifyList = ref([]);
|
||||
// 按钮
|
||||
const buttonLayout = ref([]);
|
||||
// 脚本
|
||||
const beforeSetData = ref('');
|
||||
const afterValidateForm = ref('');
|
||||
const afterSaveEvent = ref('');
|
||||
const changeDataEvent = ref('');
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner((data: any) => {
|
||||
console.log('daaaaa', data);
|
||||
// 脚本
|
||||
beforeSetData.value = data?.beforeSetData;
|
||||
afterValidateForm.value = data?.afterValidateForm;
|
||||
afterSaveEvent.value = data?.afterSaveEvent;
|
||||
changeDataEvent.value = data?.changeDataEvent;
|
||||
|
||||
isUpdate.value = !!data?.isUpdate;
|
||||
isDetail.value = !!data?.isDetail;
|
||||
const arr: FormSchema[] = [];
|
||||
|
|
@ -133,6 +168,9 @@
|
|||
if (opt.component === 'Card') {
|
||||
cardLayout.value.push(opt);
|
||||
}
|
||||
if (opt.component === 'Button') {
|
||||
buttonLayout.value.push(opt);
|
||||
}
|
||||
if (['createuser', 'createtime', 'modifyuser', 'modifytime'].includes(opt.type)) {
|
||||
createOrModifyList.value.push(opt);
|
||||
}
|
||||
|
|
@ -163,6 +201,20 @@
|
|||
scrollValue.value = { x: (subTableColumns.value.length - 1) * 140, y: 300 };
|
||||
subTableData.value = tableData;
|
||||
}
|
||||
if (opt.columns) {
|
||||
opt.columns.forEach((itemColumn) => {
|
||||
itemColumn.children.forEach((itemColumnChild) => {
|
||||
console.log('itemColumnChild', itemColumnChild);
|
||||
itemColumnChild.itemProps.hidden = true;
|
||||
if (index == 0) {
|
||||
itemColumnChild.itemProps.hidden = false;
|
||||
}
|
||||
arr.push(itemColumnChild);
|
||||
val.children.push(itemColumnChild);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
opt.itemProps.hidden = true;
|
||||
if (index == 0) {
|
||||
opt.itemProps.hidden = false;
|
||||
|
|
@ -173,6 +225,7 @@
|
|||
});
|
||||
tabsColumns.value = item.componentProps.options;
|
||||
console.log('tabsColumns', tabsColumns.value);
|
||||
console.log('formColumns', formColumns.value);
|
||||
} else {
|
||||
if (item.rules !== undefined) {
|
||||
let myString = item.rules[0].pattern;
|
||||
|
|
@ -188,6 +241,9 @@
|
|||
if (item.component === 'Card') {
|
||||
cardLayout.value.push(item);
|
||||
}
|
||||
if (item.component === 'Button') {
|
||||
buttonLayout.value.push(item);
|
||||
}
|
||||
if (['createuser', 'createtime', 'modifyuser', 'modifytime'].includes(item.type)) {
|
||||
createOrModifyList.value.push(item);
|
||||
}
|
||||
|
|
@ -272,14 +328,14 @@
|
|||
console.log('eee', e);
|
||||
console.log('tabsColumns', tabsColumns);
|
||||
const columns: FormSchema[] = [];
|
||||
// tabsColumns.value.forEach((item) => {
|
||||
// item.children.forEach((val) => {
|
||||
// val.itemProps.hidden = true;
|
||||
// });
|
||||
// });
|
||||
// tabsColumns.value[e].children.forEach((item) => {
|
||||
// item.itemProps.hidden = false;
|
||||
// });
|
||||
tabsColumns.value.forEach((item) => {
|
||||
item.children.forEach((val) => {
|
||||
val.itemProps.hidden = true;
|
||||
});
|
||||
});
|
||||
tabsColumns.value[e].children.forEach((item) => {
|
||||
item.itemProps.hidden = false;
|
||||
});
|
||||
tabsColumns.value.forEach((item) => {
|
||||
item.children.forEach((val) => {
|
||||
columns.push(val);
|
||||
|
|
@ -287,10 +343,16 @@
|
|||
});
|
||||
console.log('columns', columns);
|
||||
console.log('formColumns', formColumns);
|
||||
const obj = getFieldsValue();
|
||||
console.log('values', getFieldsValue());
|
||||
// resetFields();
|
||||
setTimeout(() => {
|
||||
updateSchema(columns);
|
||||
console.log('values', getFieldsValue());
|
||||
resetFields();
|
||||
}, 100);
|
||||
setTimeout(() => {
|
||||
setFieldsValue(obj);
|
||||
}, 500);
|
||||
}
|
||||
function generateUniqueDigits(length: number): number[] {
|
||||
const digits = new Set<number>();
|
||||
|
|
@ -328,18 +390,20 @@
|
|||
async function ModalSureClick() {
|
||||
try {
|
||||
const values = await validate();
|
||||
// 添加校验后脚本
|
||||
codeClickFunction('afterValidateForm', afterValidateForm.value);
|
||||
console.log('values', values);
|
||||
let query = values;
|
||||
let saveSubTableList = [];
|
||||
// subTableList.value.forEach((item) => {
|
||||
// let emptyObj = {};
|
||||
// for (const key in item) {
|
||||
// if (key === 'key') continue;
|
||||
// emptyObj[key] = item[key];
|
||||
// }
|
||||
// saveSubTableList.push(emptyObj);
|
||||
// });
|
||||
// query[subTableId.value] = JSON.stringify(saveSubTableList);
|
||||
subTableList.value.forEach((item) => {
|
||||
let emptyObj = {};
|
||||
for (const key in item) {
|
||||
if (key === 'key') continue;
|
||||
emptyObj[key] = item[key];
|
||||
}
|
||||
saveSubTableList.push(emptyObj);
|
||||
});
|
||||
query[subTableId.value] = JSON.stringify(saveSubTableList);
|
||||
let params: any = {
|
||||
schemeId: primaryQuery.value.id,
|
||||
isUpdate: isUpdate.value,
|
||||
|
|
@ -376,6 +440,9 @@
|
|||
}
|
||||
} finally {
|
||||
setModalProps({ confirmLoading: false });
|
||||
// 添加保存后脚本
|
||||
codeClickFunction('afterSaveEvent', afterSaveEvent.value);
|
||||
closeFunc();
|
||||
}
|
||||
}
|
||||
async function handleCreateFlow(processId) {
|
||||
|
|
@ -399,7 +466,37 @@
|
|||
return createMessage.error('保存草稿失败');
|
||||
}
|
||||
}
|
||||
// 脚本执行方法
|
||||
async function codeClickFunction(code, codeClick) {
|
||||
try {
|
||||
// 动态导入utils模块
|
||||
const { utils } = await import('./utils');
|
||||
eval(codeClick);
|
||||
} catch (e) {
|
||||
switch (code) {
|
||||
case 'codeClick':
|
||||
createMessage.success('【按钮组件脚本】错误:' + e);
|
||||
break;
|
||||
case 'beforeSetData':
|
||||
createMessage.success('【添加赋值前脚本】错误:' + e);
|
||||
break;
|
||||
case 'afterValidateForm':
|
||||
createMessage.success('【添加校验后脚本】错误:' + e);
|
||||
break;
|
||||
case 'afterSaveEvent':
|
||||
createMessage.success('【添加保存后脚本】错误:' + e);
|
||||
break;
|
||||
case 'changeDataEvent':
|
||||
createMessage.success('【添加数据改变脚本】错误:' + e);
|
||||
break;
|
||||
default:
|
||||
createMessage.success('【未知脚本】错误:' + e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
const closeFunc = () => {
|
||||
buttonLayout.value = [];
|
||||
cardLayout.value = [];
|
||||
createOrModifyList.value = [];
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
ref="formBoxRef"
|
||||
:formConfig="formConfig"
|
||||
:flowFormData="props.flowFormData"
|
||||
:formVerison="designerData.formCurrentNode.formVerison"
|
||||
v-if="formVisble"
|
||||
/>
|
||||
</a-tab-pane>
|
||||
|
|
@ -257,10 +258,12 @@
|
|||
});
|
||||
if (data) {
|
||||
const scheme = JSON.parse(data.scheme);
|
||||
scheme.formInfo.schemas.forEach((element) => {
|
||||
if (element.field == designerData.formCurrentNode.formRelationId) {
|
||||
keyValue.value = element.componentProps.fieldName;
|
||||
}
|
||||
scheme.formInfo.tabList.forEach((tabElement) => {
|
||||
tabElement.schemas.forEach((element) => {
|
||||
if (element.field == designerData.formCurrentNode.formRelationId) {
|
||||
keyValue.value = element.componentProps.fieldName;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -186,6 +186,7 @@
|
|||
getTitle.value = '新增';
|
||||
data.btnList.forEach((element) => {
|
||||
if (element.prop === 'Add' && element.isWFlow) {
|
||||
alert("Add");
|
||||
flowCode.value = element.wFlowCode;
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -321,7 +321,7 @@
|
|||
let chlidKey: any = ref();
|
||||
if (val.type === 'chlid') {
|
||||
getOutKeyList(params).then((res: Recordable) => {
|
||||
console.log('ressss', res)
|
||||
console.log('ressss', res);
|
||||
if (res[0]) {
|
||||
res[0].db_codecolumnsList.forEach((item) => {
|
||||
if (item.isPrimaryKey == 1) {
|
||||
|
|
@ -332,9 +332,9 @@
|
|||
});
|
||||
}
|
||||
setTimeout(() => {
|
||||
console.log('chlidKey', chlidKey.value)
|
||||
console.log('chlidKey', chlidKey.value);
|
||||
}, 500);
|
||||
|
||||
|
||||
if (rel.formInfo.schemas.length > 1) {
|
||||
rel.formInfo.schemas.forEach((item) => {
|
||||
if (
|
||||
|
|
@ -408,6 +408,10 @@
|
|||
},
|
||||
activeKey: 1,
|
||||
status: 'Add',
|
||||
beforeSetData: '',
|
||||
afterValidateForm: '',
|
||||
afterSaveEvent: '',
|
||||
changeDataEvent: '',
|
||||
});
|
||||
|
||||
const handleClickForm = (status) => {
|
||||
|
|
@ -431,7 +435,7 @@
|
|||
if (rows.length > 0) {
|
||||
query.value.keyValue = rows[0][str.value];
|
||||
}
|
||||
console.log('config', config)
|
||||
console.log('config', config);
|
||||
switch (status) {
|
||||
case 'Add':
|
||||
btnList.value.forEach((element) => {
|
||||
|
|
@ -448,6 +452,10 @@
|
|||
query: query.value,
|
||||
addParams: addParamsArr.value,
|
||||
btnList: btnList.value,
|
||||
beforeSetData: config.beforeSetData,
|
||||
afterValidateForm: config.afterValidateForm,
|
||||
afterSaveEvent: config.afterSaveEvent,
|
||||
changeDataEvent: config.changeDataEvent,
|
||||
};
|
||||
if (haveMap.value) {
|
||||
showFormModalData.value = toProps;
|
||||
|
|
@ -482,6 +490,10 @@
|
|||
recordChildren: formData.value,
|
||||
query: query.value,
|
||||
btnList: btnList.value,
|
||||
beforeSetData: config.beforeSetData,
|
||||
afterValidateForm: config.afterValidateForm,
|
||||
afterSaveEvent: config.afterSaveEvent,
|
||||
changeDataEvent: config.changeDataEvent,
|
||||
};
|
||||
if (haveMap.value) {
|
||||
showFormModalData.value = toProps;
|
||||
|
|
@ -612,6 +624,7 @@
|
|||
layerFields: {},
|
||||
};
|
||||
}
|
||||
console.log('columnObj', columnObj)
|
||||
paramsId.value = res.formScheme.id;
|
||||
btnList.value = columnObj.table.btns;
|
||||
if (columnObj.table.columns) {
|
||||
|
|
@ -651,6 +664,11 @@
|
|||
unref(asyncExpandTreeRef)?.expandAll(true);
|
||||
});
|
||||
formConfig.value.schemas = formObj.formInfo.schemas;
|
||||
// 表单脚本
|
||||
formConfig.value.beforeSetData = formObj.formInfo.beforeSetData;
|
||||
formConfig.value.afterValidateForm = formObj.formInfo.afterValidateForm;
|
||||
formConfig.value.afterSaveEvent = formObj.formInfo.afterSaveEvent;
|
||||
formConfig.value.changeDataEvent = formObj.formInfo.changeDataEvent;
|
||||
});
|
||||
}
|
||||
//弹窗确定后返回调用
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
// utils.ts
|
||||
export const utils = {
|
||||
add: function add(a: number, b: number): number {
|
||||
return a + b;
|
||||
},
|
||||
subtract: function subtract(a: number, b: number): number {
|
||||
return a - b;
|
||||
},
|
||||
};
|
||||
|
|
@ -213,9 +213,19 @@
|
|||
const arr: any = [];
|
||||
formScheme.value.formInfo.tabList.forEach((item, index) => {
|
||||
item.schemas.forEach((val) => {
|
||||
arr.push(val);
|
||||
if (val.type == 'subTable' && val.columns) {
|
||||
console.log('val', val)
|
||||
val.columns.forEach((col) => {
|
||||
col.children.forEach((chil) => {
|
||||
arr.push(chil);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
arr.push(val);
|
||||
}
|
||||
});
|
||||
});
|
||||
console.log('item.columns', arr)
|
||||
formScheme.value.formInfo.schemas = arr;
|
||||
}
|
||||
if (formScheme.value.formInfo.tabList && formScheme.value.formInfo.tabList.length == 1) {
|
||||
|
|
|
|||
|
|
@ -154,6 +154,7 @@
|
|||
let query: any = { keyValue: record.schemeId };
|
||||
const preview: any = await functionGetPreviewForm(query);
|
||||
let scheme = JSON.parse(preview.scheme);
|
||||
console.log('scheme1111', scheme);
|
||||
if (scheme.formInfo.tabList && scheme.formInfo.tabList.length > 1) {
|
||||
const arr: any = [];
|
||||
scheme.formInfo.tabList.forEach((item, index) => {
|
||||
|
|
|
|||
|
|
@ -152,6 +152,7 @@
|
|||
let tableData = await getTableColumnData(schems);
|
||||
let tabArr: any = [];
|
||||
let tabLabelArr: any = [];
|
||||
console.log('beforedesignTab', designTab);
|
||||
designTab.schemas.forEach((item) => {
|
||||
if (item.component !== 'Tabs') {
|
||||
if (item.componentProps.defaultValue) {
|
||||
|
|
@ -193,7 +194,7 @@
|
|||
}
|
||||
// 设计子表给里面的控件增加csType字段
|
||||
if (list.type == 'subTable') {
|
||||
list.columns = changeCloums(item.columns, tableData);
|
||||
list.columns = changeCloums(list.columns, tableData);
|
||||
}
|
||||
tabArr.push(list.componentProps.fieldName);
|
||||
if (!list.componentProps.fieldName) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue