高级查询组件存在缺陷、dockerfile文件提交、删除详情表单组件
parent
46c3c5d15d
commit
40009824d0
|
@ -19,7 +19,7 @@ VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false
|
|||
VITE_GLOB_API_URL=/jeecgboot
|
||||
|
||||
#后台接口全路径地址(必填)
|
||||
VITE_GLOB_DOMAIN_URL=http://api3.boot.jeecg.com
|
||||
VITE_GLOB_DOMAIN_URL=http://jeecg-boot-system:8080/jeecg-boot
|
||||
|
||||
# 接口父路径前缀
|
||||
VITE_GLOB_API_URL_PREFIX=
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
FROM nginx
|
||||
MAINTAINER jeecgos@163.com
|
||||
VOLUME /tmp
|
||||
ENV LANG en_US.UTF-8
|
||||
RUN echo "server { \
|
||||
listen 80; \
|
||||
location /jeecgboot { \
|
||||
proxy_pass http://jeecg-boot-system:8080/jeecg-boot; \
|
||||
proxy_redirect off; \
|
||||
proxy_set_header Host jeecg-boot-system; \
|
||||
proxy_set_header X-Real-IP \$remote_addr; \
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; \
|
||||
} \
|
||||
#解决Router(mode: 'history')模式下,刷新路由地址不能找到页面的问题 \
|
||||
location / { \
|
||||
root /var/www/html/; \
|
||||
index index.html index.htm; \
|
||||
if (!-e \$request_filename) { \
|
||||
rewrite ^(.*)\$ /index.html?s=\$1 last; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
access_log /var/log/nginx/access.log ; \
|
||||
} " > /etc/nginx/conf.d/default.conf \
|
||||
&& mkdir -p /var/www \
|
||||
&& mkdir -p /var/www/html
|
||||
|
||||
ADD dist/ /var/www/html/
|
||||
EXPOSE 80
|
||||
EXPOSE 443
|
21
README.md
21
README.md
|
@ -77,8 +77,29 @@ yarn build
|
|||
```
|
||||
|
||||
|
||||
## Docker镜像用法
|
||||
- 编译项目
|
||||
|
||||
```bash
|
||||
git clone https://github.com/jeecgboot/jeecgboot-vue3.git
|
||||
|
||||
cd jeecgboot-vue3
|
||||
|
||||
yarn install
|
||||
|
||||
yarn build
|
||||
|
||||
```
|
||||
- 启动容器
|
||||
```bash
|
||||
docker build -t jeecgboot-vue3 .
|
||||
docker run --name jeecgboot-vue3-nginx -p 80:80 -d jeecgboot-vue3
|
||||
```
|
||||
|
||||
- host设置(127.0.0.1不行,得设置具体IP)
|
||||
```bash
|
||||
192.168.5.100 jeecg-boot-system
|
||||
```
|
||||
|
||||
|
||||
## 功能模块
|
||||
|
|
|
@ -1,160 +0,0 @@
|
|||
<template>
|
||||
<div :class="formContainerClass">
|
||||
<a-row>
|
||||
<a-col v-for="(item, index) in schemas" :key="index" :span="getItemSpan(item)">
|
||||
<div class="detail-item">
|
||||
<div class="item-title" :title="item.label"> {{ item.label }}: </div>
|
||||
<div class="item-content" v-if="item.isHtml" v-html="detailFormData[item.field]"></div>
|
||||
<div class="item-content" v-else-if="item.isImage">
|
||||
<div class="ant-upload-list ant-upload-list-picture-card">
|
||||
<template v-for="url in detailFormData[item.field]">
|
||||
<div class="ant-upload-list-picture-card-container" style="margin-top: 8px">
|
||||
<span>
|
||||
<div class="ant-upload-list-item ant-upload-list-item-done ant-upload-list-item-list-type-picture-card" data-has-actions="true">
|
||||
<div class="ant-upload-list-item-info">
|
||||
<img :src="url" alt="图片不存在" class="ant-upload-list-item-image" />
|
||||
</div>
|
||||
<span class="ant-upload-list-item-actions">
|
||||
<download-outlined @click="handleDownloadFile(url)" />
|
||||
<eye-outlined @click="handleViewImage(item.field)" />
|
||||
</span>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-content" v-else-if="item.isFile">
|
||||
<div class="ant-upload-list ant-upload-list-text">
|
||||
<template v-for="url in detailFormData[item.field]">
|
||||
<div class="">
|
||||
<span>
|
||||
<div class="ant-upload-list-item ant-upload-list-item-done ant-upload-list-item-list-type-text">
|
||||
<div class="ant-upload-list-item-info">
|
||||
<span>
|
||||
<paper-clip-outlined />
|
||||
<a :href="url" target="_blank" rel="noopener noreferrer" class="ant-upload-list-item-name ant-upload-list-item-name-icon-count-1">
|
||||
{{ getFilename(url) }}
|
||||
</a>
|
||||
<span class="ant-upload-list-item-card-actions">
|
||||
<download-outlined @click="handleDownloadFile(url)" />
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="item-content">
|
||||
{{ detailFormData[item.field] }}
|
||||
</div>
|
||||
</div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { propTypes } from '/@/utils/propTypes';
|
||||
import { useDetailForm } from '../hooks/useDetailForm';
|
||||
import { DownloadOutlined, EyeOutlined, PaperClipOutlined } from '@ant-design/icons-vue';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'DetailForm',
|
||||
components: {
|
||||
DownloadOutlined,
|
||||
EyeOutlined,
|
||||
PaperClipOutlined,
|
||||
},
|
||||
props: {
|
||||
span: propTypes.number.def(24),
|
||||
//表单配置
|
||||
schemas: propTypes.array.def([]),
|
||||
//表单数据
|
||||
data: propTypes.object.def({}),
|
||||
containerClass: propTypes.string.def(''),
|
||||
},
|
||||
setup(props) {
|
||||
const { formContainerClass, detailFormData, getItemSpan, handleDownloadFile, handleViewImage, getFilename } = useDetailForm(props);
|
||||
return {
|
||||
formContainerClass,
|
||||
detailFormData,
|
||||
getItemSpan,
|
||||
handleDownloadFile,
|
||||
handleViewImage,
|
||||
getFilename,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.jeecg-detail-form {
|
||||
border: 1px solid #f0f0f0;
|
||||
border-left: none;
|
||||
border-bottom: none;
|
||||
.detail-item {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: stretch;
|
||||
line-height: 24px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
height: 100%;
|
||||
.item-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
flex-shrink: 0;
|
||||
flex-grow: 0;
|
||||
min-width: 100px;
|
||||
width: 20%;
|
||||
max-width: 220px;
|
||||
background-color: #fafafa;
|
||||
border-right: 1px solid #f0f0f0;
|
||||
/* border-left: 1px solid #f0f0f0;*/
|
||||
padding: 10px 0;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
.item-content {
|
||||
border-right: 1px solid #f0f0f0;
|
||||
flex-grow: 1;
|
||||
padding-left: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
.anticon {
|
||||
&:hover {
|
||||
color: #40a9ff;
|
||||
}
|
||||
}
|
||||
|
||||
.detail-image-container {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: #000000d9;
|
||||
font-size: 14px;
|
||||
font-variant: tabular-nums;
|
||||
list-style: none;
|
||||
font-feature-settings: 'tnum';
|
||||
line-height: 1.5715;
|
||||
.image-item {
|
||||
display: inline-block;
|
||||
width: 104px;
|
||||
height: 104px;
|
||||
margin: 5px;
|
||||
border: 1px solid #f0f0f0;
|
||||
vertical-align: top;
|
||||
img {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,542 +0,0 @@
|
|||
import { FormSchema, RenderCallbackParams } from '/@/components/Form';
|
||||
import { computed, ref, watch } from 'vue';
|
||||
import { getDictItemsByCode } from '/@/utils/dict';
|
||||
import { filterMultiDictText } from '/@/utils/dict/JDictSelectUtil';
|
||||
import { initDictOptions } from '/@/utils/dict/index';
|
||||
import { loadDictItem, queryDepartTreeSync, getUserList } from '/@/api/common/api';
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { FieldExtends } from '/@/views/super/online/cgform/types/onlineRender';
|
||||
import { getAreaTextByCode } from '/@/components/Form/src/utils/Area';
|
||||
import { JVxeTableInstance } from '/@/components/jeecg/JVxeTable/types';
|
||||
import { handleLinkDown, LINK_DOWN, OnlSubTab, useOnlineVxeTableColumns } from '/@/views/super/online/cgform/hooks/auto/useAutoForm';
|
||||
import { pick } from 'lodash-es';
|
||||
import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
|
||||
import { createImgPreview } from '/@/components/Preview/index';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
export interface DetailFormSchema {
|
||||
field: string;
|
||||
label: string;
|
||||
span?: number;
|
||||
view?: string;
|
||||
isHtml?: boolean;
|
||||
isImage?: boolean;
|
||||
isFile?: boolean;
|
||||
order?: any;
|
||||
dictTable?: string;
|
||||
dictText?: string;
|
||||
dictCode?: string;
|
||||
dict?: string;
|
||||
fieldExtendJson?: string;
|
||||
ifShow?: boolean | ((renderCallbackParams: RenderCallbackParams) => boolean);
|
||||
}
|
||||
|
||||
/*interface DetailFormProps {
|
||||
span?: number;
|
||||
schemas?: DetailFormSchema[];
|
||||
data?: any;
|
||||
containerClass?: string;
|
||||
}*/
|
||||
|
||||
export function useDetailForm(props: any) {
|
||||
console.log(props);
|
||||
const dictOptionsMap = {};
|
||||
const currentLinkFields: string[] = [];
|
||||
const detailFormData = ref({});
|
||||
const { createMessage } = useMessage();
|
||||
|
||||
const formContainerClass = computed(() => {
|
||||
if (props.containerClass) {
|
||||
return `jeecg-detail-form ${props.containerClass}`;
|
||||
} else {
|
||||
return 'jeecg-detail-form';
|
||||
}
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.data,
|
||||
async (formData) => {
|
||||
if (formData) {
|
||||
let arr = props.schemas;
|
||||
let temp = {};
|
||||
if (arr && arr.length > 0) {
|
||||
for (let item of arr) {
|
||||
let field = item.field;
|
||||
try {
|
||||
temp[field] = await getItemContent(item);
|
||||
} catch (e) {
|
||||
console.error('字段【' + field + '】文本获取失败', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
detailFormData.value = temp;
|
||||
console.log('23345', detailFormData.value);
|
||||
}
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
);
|
||||
|
||||
async function getItemContent(item) {
|
||||
let formData = props.data;
|
||||
if (formData) {
|
||||
let value = formData[item.field];
|
||||
if (!value && value !== '0' && value !== 0) {
|
||||
return '';
|
||||
}
|
||||
let str = value;
|
||||
let view = item.view;
|
||||
if (view == 'list' || view == 'radio' || view == 'checkbox' || view == 'list_multi') {
|
||||
str = await getSelectText(item, formData);
|
||||
} else if (view == 'sel_search') {
|
||||
str = await getTableDataText(item, formData);
|
||||
} else if (view == 'cat_tree') {
|
||||
//分类字典树
|
||||
str = await getCategoryDataText(item, formData);
|
||||
} else if (view == 'sel_depart') {
|
||||
//部门选择
|
||||
str = await getDepartDataText(item, formData);
|
||||
} else if (view == 'sel_user') {
|
||||
// 用户选择
|
||||
str = await getUserDataText(item, formData);
|
||||
} else if (view == 'pca') {
|
||||
//省市区
|
||||
str = getAreaTextByCode(value);
|
||||
} else if (view == 'link_down') {
|
||||
//联动组件
|
||||
str = await getLinkDownDataText(item, formData);
|
||||
} else if (view == 'sel_tree') {
|
||||
//自定义树控件
|
||||
str = await getTreeDataText(item, formData);
|
||||
} else if (view == 'switch') {
|
||||
//开关组件
|
||||
str = await getSwitchDataText(item, formData);
|
||||
} else if (view == 'image' || view == 'file') {
|
||||
str = getFileList(item, formData);
|
||||
} else {
|
||||
if (currentLinkFields.indexOf(item.field) >= 0) {
|
||||
let arr = dictOptionsMap[item.field];
|
||||
if (arr && arr.length > 0) {
|
||||
str = filterMultiDictText(arr, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
// 数据字典/表字典
|
||||
async function getSelectText(item, formData) {
|
||||
// 先从缓存取
|
||||
let dictCode = getRequestDictCode(item);
|
||||
let value = formData[item.field];
|
||||
if (!dictCode) {
|
||||
return value;
|
||||
}
|
||||
let options = getDictItemsByCode(dictCode);
|
||||
if (options && options.length > 0) {
|
||||
return filterMultiDictText(options, value);
|
||||
} else {
|
||||
let dictRes = [];
|
||||
if (dictOptionsMap[dictCode]) {
|
||||
dictRes = dictOptionsMap[dictCode];
|
||||
} else {
|
||||
//取不到再请求
|
||||
dictRes = (await initDictOptions(dictCode)) || [];
|
||||
}
|
||||
if (dictRes && dictRes.length > 0) {
|
||||
dictOptionsMap[dictCode] = dictRes;
|
||||
return filterMultiDictText(dictRes, value);
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
function getRequestDictCode(item) {
|
||||
let temp = '';
|
||||
let { dictCode, dictTable, dictText } = item;
|
||||
if (!dictTable) {
|
||||
temp = dictCode;
|
||||
} else {
|
||||
temp = `${dictTable},${dictText},${dictCode}`;
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
// 表字典-下拉搜索
|
||||
async function getTableDataText(item, formData) {
|
||||
let dictCode = getRequestDictCode(item);
|
||||
let value = formData[item.field];
|
||||
if (!value) {
|
||||
return '';
|
||||
}
|
||||
|
||||
let arr: any[] = [];
|
||||
if (dictOptionsMap[dictCode + value]) {
|
||||
arr = dictOptionsMap[dictCode + value];
|
||||
} else {
|
||||
//取不到再请求
|
||||
arr = (await defHttp.get({ url: `/sys/dict/loadDictItem/${dictCode}`, params: { key: value } })) || [];
|
||||
}
|
||||
if (arr && arr.length > 0) {
|
||||
dictOptionsMap[dictCode + value] = arr;
|
||||
return arr.join(',');
|
||||
//return filterMultiDictText(arr, value);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
// 分类字典
|
||||
async function getCategoryDataText(item, formData) {
|
||||
let value = formData[item.field];
|
||||
if (!value) {
|
||||
return '';
|
||||
}
|
||||
let arr = (await loadDictItem({ ids: value })) || [];
|
||||
if (arr && arr.length > 0) {
|
||||
return arr.join(',');
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
// 部门数据
|
||||
async function getDepartDataText(item, formData) {
|
||||
let value = formData[item.field];
|
||||
if (!value) {
|
||||
return '';
|
||||
}
|
||||
let extend = getExtendConfig(item);
|
||||
let storeField = extend.store || 'id';
|
||||
let arr = (await queryDepartTreeSync({ ids: value, primaryKey: storeField })) || [];
|
||||
if (arr && arr.length > 0) {
|
||||
let temp: string[] = [];
|
||||
for (let item of arr) {
|
||||
temp.push(item.title);
|
||||
}
|
||||
return temp.join(',');
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
//用户数据
|
||||
async function getUserDataText(item, formData) {
|
||||
let value = formData[item.field];
|
||||
if (!value) {
|
||||
return '';
|
||||
}
|
||||
let extend = getExtendConfig(item);
|
||||
let storeField = extend.store || 'username';
|
||||
let params = {
|
||||
[storeField]: value,
|
||||
};
|
||||
let res = (await getUserList(params)) || {};
|
||||
let arr = res.records || [];
|
||||
if (arr && arr.length > 0) {
|
||||
let temp: string[] = [];
|
||||
console.log('getUserDataText', arr);
|
||||
let textField = extend.text || 'realname';
|
||||
for (let item of arr) {
|
||||
temp.push(item[textField]);
|
||||
}
|
||||
return temp.join(',');
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
function getExtendConfig(item) {
|
||||
let extend: FieldExtends = {};
|
||||
let { fieldExtendJson } = item;
|
||||
if (fieldExtendJson) {
|
||||
if (typeof fieldExtendJson == 'string') {
|
||||
try {
|
||||
let json = JSON.parse(fieldExtendJson);
|
||||
extend = { ...json };
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return extend;
|
||||
}
|
||||
|
||||
// 联动组件
|
||||
async function getLinkDownDataText(item, formData) {
|
||||
let { dictTable, field } = item;
|
||||
let arr: any[] = [];
|
||||
if (dictOptionsMap[field]) {
|
||||
arr = dictOptionsMap[field];
|
||||
} else {
|
||||
if (dictTable) {
|
||||
let json = JSON.parse(dictTable);
|
||||
if (json) {
|
||||
let { table, txt, key, linkField } = json;
|
||||
let dictCode = `${table},${txt},${key}`;
|
||||
let temp: any[] = (await initDictOptions(dictCode)) || [];
|
||||
arr = [...temp];
|
||||
if (arr && arr.length > 0) {
|
||||
dictOptionsMap[field] = arr;
|
||||
if (linkField) {
|
||||
let fieldArray = linkField.split(',');
|
||||
for (let item of fieldArray) {
|
||||
dictOptionsMap[item] = arr;
|
||||
currentLinkFields.push(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (arr && arr.length > 0) {
|
||||
let value = formData[field];
|
||||
return filterMultiDictText(arr, value);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
//自定义树
|
||||
async function getTreeDataText(item, formData) {
|
||||
let { dict, field } = item;
|
||||
let arr = [];
|
||||
if (dictOptionsMap[field]) {
|
||||
arr = dictOptionsMap[field];
|
||||
} else {
|
||||
if (dict) {
|
||||
arr = await initDictOptions(dict);
|
||||
}
|
||||
}
|
||||
if (arr && arr.length > 0) {
|
||||
let value = formData[field];
|
||||
return filterMultiDictText(arr, value);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
//开关
|
||||
async function getSwitchDataText(item, formData) {
|
||||
let { fieldExtendJson, field } = item;
|
||||
let options = ['Y', 'N'];
|
||||
if (fieldExtendJson) {
|
||||
options = JSON.parse(fieldExtendJson);
|
||||
}
|
||||
let arr: any[] = [
|
||||
{ value: options[0], text: '是' },
|
||||
{ value: options[1], text: '否' },
|
||||
];
|
||||
let value = formData[field];
|
||||
return filterMultiDictText(arr, value);
|
||||
}
|
||||
|
||||
function getItemSpan(item) {
|
||||
if (item.span) {
|
||||
return item.span;
|
||||
}
|
||||
return props.span;
|
||||
}
|
||||
|
||||
function getFileList(item, formData) {
|
||||
let str = formData[item.field];
|
||||
if (!str) {
|
||||
return [];
|
||||
}
|
||||
let arr = str.split(',');
|
||||
let result: string[] = [];
|
||||
for (let item of arr) {
|
||||
let src = getFileAccessHttpUrl(item) || '';
|
||||
if (src) {
|
||||
result.push(src);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function handleDownloadFile(url) {
|
||||
if (url) {
|
||||
window.open(url);
|
||||
}
|
||||
}
|
||||
|
||||
function handleViewImage(field) {
|
||||
let values = detailFormData.value[field];
|
||||
if (!values || values.length == 0) {
|
||||
createMessage.warning('无图片!');
|
||||
return;
|
||||
}
|
||||
createImgPreview({ imageList: values });
|
||||
}
|
||||
|
||||
function getFilename(url) {
|
||||
if (!url) {
|
||||
return '';
|
||||
}
|
||||
return url.substring(url.lastIndexOf('/') + 1);
|
||||
}
|
||||
|
||||
return {
|
||||
formContainerClass,
|
||||
detailFormData,
|
||||
getItemSpan,
|
||||
handleDownloadFile,
|
||||
handleViewImage,
|
||||
getFilename,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 DetailFormSchema[online用]
|
||||
*/
|
||||
export function getDetailFormSchemas(props) {
|
||||
const detailFormSchemas = ref<DetailFormSchema[]>([]);
|
||||
const refMap = {};
|
||||
const hasSubTable = ref(false);
|
||||
const subTabInfo = ref<OnlSubTab[]>([]);
|
||||
const subDataSource = ref({});
|
||||
const formSpan = computed(() => {
|
||||
let temp = props.formTemplate;
|
||||
if (temp == '2') {
|
||||
return 12;
|
||||
} else if (temp == '3') {
|
||||
return 8;
|
||||
} else if (temp == '4') {
|
||||
return 6;
|
||||
} else {
|
||||
return 24;
|
||||
}
|
||||
});
|
||||
|
||||
function createFormSchemas(properties: any[]) {
|
||||
//let properties:any[] = result.schema.properties
|
||||
let subInfo: OnlSubTab[] = [];
|
||||
console.log('111', properties);
|
||||
let arr: DetailFormSchema[] = [];
|
||||
let dataSourceObj = {};
|
||||
Object.keys(properties).map((key) => {
|
||||
const item = properties[key];
|
||||
// uiSchema 无用
|
||||
//const uiItem = this.uiSchema[key];// method、formTemplate、url
|
||||
if (item.view == 'tab') {
|
||||
hasSubTable.value = true;
|
||||
let temp: OnlSubTab = {
|
||||
key,
|
||||
// 这个foreignKey是主表的字段
|
||||
foreignKey: item['foreignKey'],
|
||||
describe: item.describe,
|
||||
relationType: item.relationType,
|
||||
requiredFields: item.required || [],
|
||||
order: item.order,
|
||||
};
|
||||
if (item.relationType == 1) {
|
||||
refMap[key] = ref(null);
|
||||
temp['properties'] = item.properties;
|
||||
} else {
|
||||
dealSubProerties(item);
|
||||
refMap[key] = ref<JVxeTableInstance>();
|
||||
temp['columns'] = item.columns;
|
||||
dataSourceObj[key] = [];
|
||||
}
|
||||
subInfo.push(temp);
|
||||
} else {
|
||||
if (item.view === LINK_DOWN) {
|
||||
let array = handleLinkDown(item, key);
|
||||
for (let linkDownItem of array) {
|
||||
let tempIndex = getFieldIndex(arr, linkDownItem.key);
|
||||
let temp = {
|
||||
field: linkDownItem.key,
|
||||
label: linkDownItem.title,
|
||||
view: linkDownItem.view,
|
||||
order: linkDownItem.order,
|
||||
};
|
||||
if (tempIndex == -1) {
|
||||
arr.push(temp);
|
||||
} else {
|
||||
arr[tempIndex] = temp;
|
||||
}
|
||||
}
|
||||
} else if (item.view == 'hidden') {
|
||||
//隐藏的不处理
|
||||
} else {
|
||||
let tempIndex = getFieldIndex(arr, key);
|
||||
if (tempIndex == -1) {
|
||||
let temp = Object.assign(
|
||||
{
|
||||
field: key,
|
||||
label: item.title,
|
||||
},
|
||||
pick(item, ['view', 'order', 'fieldExtendJson', 'dictTable', 'dictText', 'dictCode', 'dict'])
|
||||
);
|
||||
if (item.view == 'file') {
|
||||
temp['span'] = 24;
|
||||
temp['isFile'] = true;
|
||||
}
|
||||
if (item.view == 'image') {
|
||||
temp['span'] = 24;
|
||||
temp['isImage'] = true;
|
||||
}
|
||||
if (item.view == 'umeditor' || item.view == 'markdown') {
|
||||
temp['isHtml'] = true;
|
||||
temp['span'] = 24;
|
||||
}
|
||||
arr.push(temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
// 1.对arr排序
|
||||
arr.sort(function (a, b) {
|
||||
return a.order - b.order;
|
||||
});
|
||||
// 2.对子表排序
|
||||
subInfo.sort(function (a, b) {
|
||||
return a.order - b.order;
|
||||
});
|
||||
subTabInfo.value = subInfo;
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
let temp = arr[i];
|
||||
if (temp.isFile === true || temp.isImage === true || temp.isHtml === true) {
|
||||
if (i > 0) {
|
||||
let last = arr[i - 1];
|
||||
let span = last.span || formSpan.value;
|
||||
last.span = span;
|
||||
}
|
||||
}
|
||||
}
|
||||
detailFormSchemas.value = arr;
|
||||
subDataSource.value = dataSourceObj;
|
||||
console.log('adadad', arr);
|
||||
}
|
||||
|
||||
function dealSubProerties(subInfo) {
|
||||
useOnlineVxeTableColumns(subInfo);
|
||||
}
|
||||
|
||||
function getFieldIndex(arr: DetailFormSchema[], key: string) {
|
||||
let index = -1;
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
let item = arr[i];
|
||||
if (item.field === key) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
return {
|
||||
detailFormSchemas,
|
||||
hasSubTable,
|
||||
subTabInfo,
|
||||
refMap,
|
||||
createFormSchemas,
|
||||
formSpan,
|
||||
subDataSource,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO 尚未实现
|
||||
* 获取 DetailFormSchema[自定义开发用]
|
||||
*/
|
||||
export function transDetailFormSchemas(formSchemas: FormSchema[]) {
|
||||
const detailFormSchemas = ref<DetailFormSchema[]>([]);
|
||||
console.log(formSchemas);
|
||||
return detailFormSchemas;
|
||||
}
|
|
@ -5,7 +5,7 @@ import { useMessage } from '/@/hooks/web/useMessage';
|
|||
import { Modal } from 'ant-design-vue';
|
||||
import { createLocalStorage } from '/@/utils/cache';
|
||||
import { useRoute } from 'vue-router';
|
||||
import FormSchemaFactory from '/@/views/super/online/cgform/auto/comp/factory/FormSchemaFactory';
|
||||
|
||||
/**
|
||||
* 表单类型转换成查询类型
|
||||
* 普通查询和高级查询组件区别 :高级查询不支持联动组件
|
||||
|
@ -180,7 +180,7 @@ export function useSuperQuery() {
|
|||
// 如果出现查询条件联动组件出来的场景,请跟踪此处
|
||||
prop.view = view2QueryViewMap[prop.view];
|
||||
}
|
||||
let temp = FormSchemaFactory.createFormSchema(item.field, prop);
|
||||
let temp;
|
||||
// temp.setFormRef(formRef)
|
||||
temp.noChange();
|
||||
// 查询条件中的 下拉框popContainer为parentNode
|
||||
|
|
|
@ -1,64 +0,0 @@
|
|||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" width="40%" title="详情" :showOkBtn="false" cancelText="关闭">
|
||||
<detail-form :schemas="detailFormSchemas" :data="formData" :span="12"></detail-form>
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { getDemoById } from './demo.api';
|
||||
import DetailForm from '/@/components/Form/src/components/DetailForm.vue';
|
||||
|
||||
// 声明Emits
|
||||
const emit = defineEmits(['register']);
|
||||
//表单数据
|
||||
const formData = ref({});
|
||||
//表单配置
|
||||
const detailFormSchemas = [
|
||||
{
|
||||
field: 'name',
|
||||
label: '名字',
|
||||
},
|
||||
{
|
||||
field: 'keyWord',
|
||||
label: '关键词',
|
||||
},
|
||||
{
|
||||
field: 'punchTime',
|
||||
label: '打卡时间',
|
||||
},
|
||||
{
|
||||
field: 'salaryMoney',
|
||||
label: '工资',
|
||||
},
|
||||
{
|
||||
field: 'sex',
|
||||
label: '性别',
|
||||
view: 'list',
|
||||
dictCode: 'sex',
|
||||
},
|
||||
{
|
||||
field: 'age',
|
||||
label: '年龄',
|
||||
},
|
||||
{
|
||||
field: 'birthday',
|
||||
label: '生日',
|
||||
},
|
||||
{
|
||||
field: 'email',
|
||||
label: '邮箱',
|
||||
},
|
||||
{
|
||||
field: 'content',
|
||||
label: '个人简介',
|
||||
span: 24,
|
||||
},
|
||||
];
|
||||
|
||||
//表单赋值
|
||||
const [registerModal, { setModalProps }] = useModalInner(async (data) => {
|
||||
setModalProps({ confirmLoading: false });
|
||||
formData.value = await getDemoById({ id: data.record.id });
|
||||
});
|
||||
</script>
|
|
@ -80,7 +80,6 @@
|
|||
</template>
|
||||
</BasicTable>
|
||||
<DemoModal @register="registerModal" @success="reload" />
|
||||
<DemoDetailModal @register="registerDetailModal" />
|
||||
<JImportModal @register="registerModal1" :url="getImportUrl" online />
|
||||
</div>
|
||||
</template>
|
||||
|
@ -98,7 +97,6 @@
|
|||
import { useGo } from '/@/hooks/web/usePage';
|
||||
import { router } from '/@/router';
|
||||
import { filterObj } from '/@/utils/common/compUtils';
|
||||
import DemoDetailModal from './DemoDetailModal.vue';
|
||||
import SuperQuery from '/@/components/jeecg/super/superquery/SuperQuery.vue';
|
||||
|
||||
const go = useGo();
|
||||
|
|
Loading…
Reference in New Issue