修改预览信息跳转切代码合并

main
于阔 9 months ago
commit 81d4a9693f

@ -49,8 +49,8 @@ export const exportExcelApi = (params: any) => {
return request.doExport({ url: '/RepIndexSet/sdi/dataset/RepIndexSet/RepIndexSetExportXls', params });
};
/** 获取某个字典 */
export const getCsckCheckType = ({ paramName, systemCode }): Promise<IResponse> => {
/** 获取参数 */
export const getIndexType = ({ paramName, systemCode }): Promise<IResponse> => {
return request.postJson({
url: '/param/spi/param/systemparam',
data: {

@ -0,0 +1,63 @@
import request from '@/config/axios';
import type { TableData } from './types';
/** 获取表格数据 */
export const getRepStoreListApi = (data: any) => {
return request.postJson({ url: '/RepStore/spi/dataset/RepStore/RepStoreQueryPage', data });
};
/** 批量删除 */
export const delRepStoreListApi = (list: string[] | number[]): Promise<IResponse> => {
const _list = list.map(v => {
return {
modelCode: v.modelCode,
beginDate: v.beginDate,
endDate: v.endDate,
ruleId: v.ruleId,
};
});
return request.postJson({
url: '/RepStore/spi/dataset/RepStore/RepStoreBatchDelete',
data: {
list: _list,
},
});
};
/** 删除 */
export const delRepStoreApi = (modelCode?: string, beginDate?: string, endDate?: string, ruleId?: string): Promise<IResponse> => {
return request.postJson({ url: '/RepStore/spi/dataset/RepStore/RepStoreDelete', data: { modelCode, beginDate, endDate, ruleId } });
};
/** 保存 */
export const saveRepStoreApi = (data: Partial<TableData>): Promise<IResponse> => {
return request.postJson({ url: '/RepStore/spi/dataset/RepStore/RepStoreSave', data });
};
/** 查询单条数据 */
export const queryRepStoreApi = (modelCode?: string, beginDate?: string, endDate?: string, ruleId?: string): Promise<IResponse> => {
return request.postJson({ url: '/RepStore/spi/dataset/RepStore/RepStoreQueryOne', data: { modelCode, beginDate, endDate, ruleId } });
};
/** 同步导入 */
export const importExcelApiUrl = '/RepStore/sui/dataset/RepStore/RepStoreImportExcel';
/** 异步导入 */
export const importExcelAsyncApiUrl = '/RepStore/sui/dataset/RepStore/RepStoreImportAsyncExcel';
/** 导出 */
export const exportExcelApi = (params: any) => {
return request.doExport({ url: '/RepStore/sdi/dataset/RepStore/RepStoreExportXls', params });
};
/** 获取某个字典 */
export const getCsckCheckType = ({ paramName, systemCode }): Promise<IResponse> => {
return request.postJson({
url: '/param/spi/param/systemparam',
data: {
paramName: paramName,
systemCode: systemCode,
},
});
};

@ -0,0 +1,64 @@
/* eslint-disable lines-around-comment */
export type TableData = {
/** 模型编码 */
modelCode?: string
/** 开始日期 */
beginDate?: string
/** 结束日期 */
endDate?: string
/** 数据源 */
dscode?: string
/** 规则类型 */
storeType?: string
/** 规则内容 */
storeContent?: string
/** 操作类型 */
storeOperateType?: string
/** 存储规则id */
ruleId?: string
/** 数据库用户 */
scheme?: string
/** 表名 */
tableName?: string
/** 校验结果表的表名 */
validateResultTable?: string
/** 数据规则 */
dataRule?: string
/** 备份数据源 */
redscode?: string
}
export interface DictItem {
dictId: string;
dictName: string;
}
export type FormModel = {
/** 模型编码 */
modelCode?: string
/** 开始日期 */
beginDate?: string
/** 结束日期 */
endDate?: string
/** 数据源 */
dscode?: string
/** 规则类型 */
storeType?: string
/** 规则内容 */
storeContent?: string
/** 操作类型 */
storeOperateType?: string
/** 存储规则id */
ruleId?: string
/** 数据库用户 */
scheme?: string
/** 表名 */
tableName?: string
/** 校验结果表的表名 */
validateResultTable?: string
/** 数据规则 */
dataRule?: string
/** 备份数据源 */
redscode?: string
}

@ -0,0 +1,155 @@
<script setup lang="ts">
import {renderAsync,renderDocument} from 'docx-preview';
import { ref } from "vue";
import { useRoute } from 'vue-router';
import { ElMessage } from 'element-plus';
import {queryFileFlowRepTemplateApi,exportTemplateApi} from '@/api/reporting/RepTemplate/RepTemplate';
const route = useRoute();
// 线
//
const pageQuery = ref(route || null);
const fileData = pageQuery.value?.query?.fileData;
//
const downLoadErrorMsg = {
"1001":"预览失败,文件路径不存在",
"1002":"预览失败,未找到文件信息",
"1003":"预览失败,请联系管理员",
}
const docxContainer = ref(null);
// DOCX ArrayBuffer
const fetchDocFile = async () => {
// API DOCX ArrayBuffer
const response = await queryFileFlowRepTemplateApi(fileData);
console.log(response,"response文件流信息");
const { data, headers } = response;
if(headers['status'] == 500){// WARNERROR
const code = headers['error']?headers['error'].substring(headers['error'].length-4):'1003';
console.log(code)
switch(code){
case "1001":
case "1002":
ElMessage.error(downLoadErrorMsg[code]);
break;
default:
ElMessage.error(downLoadErrorMsg['1003']);
break;
}
return;
}
const arrayBuffer = await new File([data], 'document.docx', { type: data.type }).arrayBuffer();
return arrayBuffer;
};
//
const filterEmptyPages = (pages) => {
console.log(pages,"获取到的pages");
return pages.filter(page => {
// page DOM textContent
if (page && page.textContent) {
return page.textContent.trim() !== '';
}
return false;
});
};
//
const addPageNumbers = (pages) => {
pages.forEach((page, index) => {
const pageNumberElement = document.createElement('div');
pageNumberElement.className = 'page-number';
pageNumberElement.textContent = `${index + 1}`;
page.appendChild(pageNumberElement);
});
};
// CSS
const adjustStyles = (container: HTMLElement) => {
// z-index
container.querySelectorAll('img').forEach(img => {
img.style.position = 'relative';
img.style.zIndex = '1';
// img.style.top = '-30px';
});
// z-index
container.querySelectorAll('p, span, div').forEach(textElement => {
textElement.style.position = 'relative';
textElement.style.zIndex = '2';
});
};
//
const downloadFile = () => {
exportTemplateApi({pId:fileData});
};
/**
* 异步函数用于获取并处理DOC文件流
* 此函数首先调用API获取DOC文件流然后根据响应头处理可能的错误情况
* 如果文件流有效它将被转换为ArrayBuffer类型并用于渲染文档
*/
const init = async ()=>{
try {
// DOCX ArrayBuffer
const arrayBuffer = await fetchDocFile();
// APIDOC
if (!(arrayBuffer instanceof ArrayBuffer)) {
throw new Error('Invalid arrayBuffer type');
}
// DOCX
const pages = await renderAsync(arrayBuffer, docxContainer.value);
adjustStyles(docxContainer.value);
// pages
const pagesArray = Array.isArray(pages) ? pages : [pages];
//
const filteredPages = filterEmptyPages(pagesArray);
//
addPageNumbers(filteredPages);
} catch (error) {
console.error('Error rendering DOCX file:', error);
}
}
init();
</script>
<template>
<div class="wrap">
<div class="fixedToolBar">
<!-- 其中包含的功能有分页页数跳转文件下载 -->
<i @click="downloadFile" class="fa fa-download cursor-pointer download" hover-color="var(--el-color-primary)"></i>
</div>
<div id="docx-container" ref="docxContainer"></div>
</div>
</template>
<style scoped>
.fixedToolBar{
position: fixed;
top: 0;
left: 0;
width:100%;
height:50px;
line-height:50px;
background-color: #635f5f;
color:#fff;
z-index:999;
}
.download{
position: absolute;
font-size:1.3rem;
top:13px;
right:15px;
}
#docx-container {
height: 100vh;
overflow: auto;
background-color: #fff;
padding:50px;
}
</style>

@ -0,0 +1,238 @@
<script setup lang="ts">
import mammoth from 'mammoth';
import { reactive,ref } from "vue";
import { useRoute } from 'vue-router';
import { ElMessage } from 'element-plus';
import {queryFileFlowRepTemplateApi,exportTemplateApi} from '@/api/reporting/RepTemplate/RepTemplate';
const route = useRoute();
// 线
//
const pageQuery = ref(route || null);
const fileData = pageQuery.value?.query?.fileData;
//
let htmlContent = ref("");
const downLoadErrorMsg = {
"1001":"预览失败,文件路径不存在",
"1002":"预览失败,未找到文件信息",
"1003":"预览失败,请联系管理员",
}
const fetchDocFile = async ()=>{
try {
// APIDOC
const response = await queryFileFlowRepTemplateApi(fileData);
const { data, headers } = response;
if(headers['status'] == 500){// WARNERROR
const code = headers['error']?headers['error'].substring(headers['error'].length-4):'1003';
console.log(code)
switch(code){
case "1001":
case "1002":
ElMessage.error(downLoadErrorMsg[code]);
break;
default:
ElMessage.error(downLoadErrorMsg['1003']);
break;
}
return;
}
const arrayBuffer = await new File([data], 'document.docx', { type: data.type }).arrayBuffer();
if (!(arrayBuffer instanceof ArrayBuffer)) {
throw new Error('Invalid arrayBuffer type');
}
dealWithFile(arrayBuffer);
} catch (error) {
console.error('Error fetching or converting DOC file:', error);
}
}
// fetchDocFile();
//
const dealWithFile = async (arrayBuffer)=>{
console.log(arrayBuffer);
// styleMap
// const styleMap = `
// p[style-name='Heading 1'] => h1:fresh
// p[style-name='Heading 2'] => h2:fresh
// p[style-name='Heading 3'] => h3:fresh
// table => table
// tr => tr
// td => td
// p[style-name='Normal'] => p
// p[style-name='List Paragraph'] => ul > li:fresh
// header => div.header
// footer => div.footer
// `;
const styleMap = `
p:style-name => p
p:Heading1 => h1
p:Heading2 => h2
p:Heading3 => h3
p:Heading4 => h4
p:Heading5 => h5
p:Heading6 => h6
p:Normal => p
p:Title => h1.title
p:Subtitle => h2.subtitle
p:Quote => blockquote
p:Code => pre
p:ListParagraph => li
r:Emphasis => em
r:Strong => strong
r:Underline => u
r:Strikethrough => del
r:Hyperlink => a
p:style-name => p style="text-align: center;"
r:style-name => span style="color: red;"
p:style-name => p.class-name
r:style-name => span.class-name
p:style-name => p#id
r:style-name => span#id
p:style-name => p.class-name#id
r:style-name => span.class-name#id
table => table
tr => tr
td => td
p[style-name='Normal'] => h6
p[style-name='List Paragraph'] => ul > li:fresh
header => div.header
footer => div.footer
`;
let result;
try {
result = await mammoth.convertToHtml({
arrayBuffer,
styleMap,
includeDefaultStyleMap: true,
extractImages: {
//
getAltText: (image) => {
return image.contentId; // alt
},
getImageUrl: (image) => {
// base64 URL
const contentType = image.contentType;
const base64Data = Buffer.from(image.data).toString('base64');
return `data:${contentType};base64,${base64Data}`;
}
},
convertImage:mammothImages,
transformDocument: (document) => {
//
const headers = document.children.filter(child => child.type === 'header');
const footers = document.children.filter(child => child.type === 'footer');
//
headers.forEach(header => {
document.children.push({
type: 'custom',
name: 'div',
attributes: { class: 'header' },
children: header.children
});
});
footers.forEach(footer => {
document.children.push({
type: 'custom',
name: 'div',
attributes: { class: 'footer' },
children: footer.children
});
});
return document;
},
});
} catch (convertError) {
console.error('Error converting DOC file to HTML:', convertError);
throw convertError;
}
console.log(result,"result信息");
// 线CSS
const cssStyles = `
<style>
table {
border-collapse: collapse;
width: 100%;
}
th, td {
border: 1px solid black;
padding: 8px;
}
</style>
`;
// HTMLhtmlContent
htmlContent.value = `${cssStyles}${result.value}`; // result.value HTML
// 使 result.messages
}
//
const mammothImages = (image) => {
return mammoth.images.imgElement(image);
}
//
const insertPageBreaks = (html) => {
// 500
const pageSize = 500;
let pagedHtml = '';
for (let i = 0; i < html.length; i += pageSize) {
pagedHtml += html.slice(i, i + pageSize) + '<div class="page-break"></div>';
}
return pagedHtml;
}
const handleFileChange = async (event) => {
const file = event.target.files[0];
if (!file) return;
const arrayBuffer = await file.arrayBuffer();
dealWithFile(arrayBuffer);
};
//
const downloadFile = () => {
exportTemplateApi({pId:fileData});
};
</script>
<template>
<div class="wrap">
<div class="fixedToolBar">
<!-- 其中包含的功能有分页页数跳转文件下载 -->
<i @click="downloadFile" class="fa fa-download cursor-pointer download" hover-color="var(--el-color-primary)"></i>
</div>
<input type="file" @change="handleFileChange" accept=".docx" style="margin-top:60px;" />
<div v-html="htmlContent" class="htmlContent"></div>
</div>
</template>
<style scoped>
.fixedToolBar{
position: fixed;
top: 0;
left: 0;
width:100%;
height:50px;
line-height:50px;
background-color: #635f5f;
color:#fff;
}
.download{
position: absolute;
font-size:1.3rem;
top:13px;
right:15px;
}
.htmlContent {
height: 100vh;
overflow: auto;
background-color: #fff;
padding:50px;
}
</style>

@ -1939,7 +1939,19 @@ export const asyncRouterMap: AppRouteRecordRaw[] = [
type:"ybt",
sort:12,
}
}
},
{
path: 'repStore',
component: () => import('@/views/dataset/RepStore/RepStore.vue'),
name: 'repStore',
menuId: 'repStore',
meta: {
title: '模型规则',
alwaysShow: true,
type:"ybt",
sort:13,
}
},
]
},
{

@ -79,7 +79,7 @@ const tableColumns = reactive<TableColumn[]>([
field: 'indexcalType',
label: '指标计算类型'
},
{
field: 'indexdataType',
label: '指标数据类型'
@ -123,7 +123,7 @@ const tableColumns = reactive<TableColumn[]>([
<ElLink type="primary" underline={false} onClick={() => action(data.row, 'ruleconfig')}>
{'配置'}
</ElLink>
</>
)
}
@ -144,12 +144,6 @@ const searchSchema = reactive<FormSchema[]>([
componentProps: {},
component: 'Input'
},
{
field: 'indexType',
label: '指标类型',
componentProps: {},
component: 'Select'
},
{
field: 'indexDate',
label: '日期范围',

@ -22,8 +22,10 @@ import { Dialog } from '@/components/Dialog'
import { getWidth } from '@/utils';
import Detail from './components/Detail.vue'
import { Upload } from '@/components/Upload'
import { useRoute } from 'vue-router';
import { useRoute,useRouter } from 'vue-router';
const route = useRoute();
const router = useRouter();
const pageQuery = ref(route || null);
const modelCode = pageQuery.value?.query?.modelCode;
const { t } = useI18n()
@ -85,12 +87,15 @@ const tableColumns = reactive<TableColumn[]>([
{
field: 'action',
label: t('tableDemo.action'),
width: 160,
width: 200,
fixed: 'right',
slots: {
default: (data: any) => {
return (
<>
<ElLink type="primary" underline={false} onClick={() => getModelRule(data.row)}>
增加规则
</ElLink>
<ElLink type="primary" underline={false} onClick={() => action(data.row, 'edit')}>
{t('tableDemo.edit')}
</ElLink>
@ -131,18 +136,13 @@ const searchSchema = reactive<FormSchema[]>([
componentProps: {},
component: 'Input'
},
{
field: 'organCode',
label: '用户所属机构',
componentProps: {},
component: 'Select'
},
{
field: 'createDate',
label: '创建日期',
componentProps: {},
component: 'DatePicker'
}
{
field: 'modelName',
label: '描述',
componentProps: {},
component: 'Input'
}
])
const searchParams = ref({})
@ -179,6 +179,17 @@ const action = async (row: TableData, type: string) => {
}
}
/** 数据模型新增规则 **/
const getModelRule = (data)=>{
console.log(data);
router.push({
name:'repStore',
query:{
modelCode:data.modelCode,
}
})
}
const AddAction = () => {
dialogTitle.value = t('tableDemo.add')
currentRow.value = undefined
@ -210,8 +221,8 @@ const delLoading = ref(false)
/** 批量删除 **/
const delDataBatch = async () => {
const elTableExpose = await getElTableExpose()
ids.value = elTableExpose?.getSelectionRows().map((v: TableData) => { v.modelCode }) || []
const elTableExpose = await getElTableExpose();
ids.value = elTableExpose?.getSelectionRows().map((v: TableData) => { return v.modelCode }) || []
delLoading.value = true
await delList(unref(ids).length).finally(() => {
delLoading.value = false
@ -235,12 +246,17 @@ const delData = async (row: TableData) => {
const disabled = ref(true)
const onSelectionChange = (selection: TableData[]) => {
console.log(selection,"selection的信息");
disabled.value = selection.length === 0
}
/** 导出Excel */
const exportExcel = async () => {
const data = { ...unref(searchParams) }
const data = { ...unref(searchParams) };
const elTableExpose = await getElTableExpose();
const list = elTableExpose?.getSelectionRows();
data['list'] = list;
console.log(data,"导出的参数信息");
await exportExcelApi(data)
}
</script>
@ -267,7 +283,7 @@ const exportExcel = async () => {
<template #buttons>
<ElButton type="primary" @click="AddAction">{{ t('tableDemo.add') }}</ElButton>
<Upload :url="importExcelApiUrl" :callback="getList"> <ElButton type="primary">导入</ElButton> </Upload>
<ElButton type="primary" @click="exportExcel()"></ElButton>
<ElButton type="primary" @click="exportExcel()" :disabled="disabled"></ElButton>
<ElButton :loading="delLoading" type="primary" :disabled="disabled" @click="delDataBatch()">
{{ t('tableDemo.del') }}
</ElButton>

@ -5,6 +5,7 @@ import { PropType, reactive, watch } from 'vue'
import { useValidator } from '@/hooks/web/useValidator'
import dayjs from 'dayjs'
const { required } = useValidator()
const props = defineProps({

@ -9,6 +9,7 @@ import {
importExcelApiUrl,
exportExcelApi
} from '@/api/dataset/RepIndexSet'
import { TableData } from '@/api/dataset/RepIndexSet/types'
import { useTable } from '@/hooks/web/useTable'
import { useI18n } from '@/hooks/web/useI18n'
@ -23,11 +24,21 @@ import { getWidth } from '@/utils';
import Detail from './components/Detail.vue'
import { Upload } from '@/components/Upload'
import { useRouter } from 'vue-router'
import { getIndexType } from '@/api/dataset/RepIndexSet';
import { transfDictList } from '@/utils';
const router = useRouter();
const { t } = useI18n()
const ids = ref<string[]>([])
let indexType_param_LIST = ref([]);
let frequency_param_LIST = ref([]);
//
const getDictInfoList = async ()=>{
const res = await getIndexType({ paramName: 'frequency_param', systemCode: 'ordb' });
frequency_param_LIST = transfDictList(res.body.result);
}
getDictInfoList();
const { tableRegister, tableState, tableMethods } = useTable({
fetchDataApi: async () => {
@ -79,7 +90,13 @@ const tableColumns = reactive<TableColumn[]>([
},
{
field: 'frequency',
label: '频度'
label: '频度',
slots:{
default:(data)=>{
console.log(data.row.frequency,frequency_param_LIST[data.row.frequency].label);
return <span>{frequency_param_LIST[data.row.frequency].label}</span>
}
}
},
{
field: 'description',
@ -87,7 +104,12 @@ const tableColumns = reactive<TableColumn[]>([
},
{
field: 'indexsetType',
label: '指标集类型'
label: '指标集类型',
slots:{
default:(data)=>{
return <span>{indexType_param_LIST[parseInt(data.row.indexsetType) - 1]?.label}</span>
}
}
},
{
field: 'modelCode',
@ -148,28 +170,15 @@ const searchSchema = reactive<FormSchema[]>([
componentProps: {},
component: 'Input'
},
{
field: 'indexsetName',
label: '指标集名称',
componentProps: {},
component: 'Input'
},
{
field: 'frequency',
label: '频度',
componentProps: {},
component: 'Select'
},
{
field: 'indexsetType',
label: '指标集类型',
componentProps: {},
component: 'Select'
},
{
field: 'modelCode',
label: '数据模型编码',
componentProps: {},
optionApi: async () => {
const res = await getIndexType({ paramName: 'indexType_param', systemCode: 'ordb' });
indexType_param_LIST = transfDictList(res.body.result);
return indexType_param_LIST;
},
value: '1',
component: 'Select'
}
])

@ -3,6 +3,8 @@ import { Form, FormSchema } from '@/components/Form'
import { useForm } from '@/hooks/web/useForm'
import { PropType, reactive, watch } from 'vue'
import { useValidator } from '@/hooks/web/useValidator'
import { getIndexType } from '@/api/dataset/RepIndexSet';
import { transfDictList } from '@/utils';
const { required } = useValidator()
@ -64,10 +66,12 @@ const formSchema = reactive<FormSchema[]>([
{
field: 'frequency',
label: '频度',
component: 'Select',
componentProps: {
},
optionApi: async () => {
const res = await getIndexType({ paramName: 'frequency_param', systemCode: 'ordb' });
return transfDictList(res.body.result);
},
value: '1',
component: 'Select'
},
{
field: 'description',
@ -80,15 +84,17 @@ const formSchema = reactive<FormSchema[]>([
{
field: 'indexsetType',
label: '指标集类型',
component: 'Select',
componentProps: {
optionApi: async () => {
const res = await getIndexType({ paramName: 'indexType_param', systemCode: 'ordb' });
return transfDictList(res.body.result);
},
value: '1',
component: 'Select'
},
{
field: 'modelCode',
label: '数据模型编码',
component: 'Select',
component: 'Input',
componentProps: {
},

@ -172,7 +172,7 @@ const tableColumns = reactive<TableColumn[]>([
const searchSchema = reactive<FormSchema[]>([
{
field: 'ruleCode',
label: '指标集规则清单编码',
label: '规则编码',
componentProps: {},
component: 'Input'
},
@ -182,18 +182,6 @@ const searchSchema = reactive<FormSchema[]>([
componentProps: {},
component: 'Input'
},
{
field: 'ruleClass',
label: '规则分类',
componentProps: {},
component: 'Select'
},
{
field: 'startDate',
label: '启用日期',
componentProps: {},
component: 'DatePicker'
},
{
field: 'itemId',
label: '指标代码',

@ -0,0 +1,329 @@
<script setup lang="tsx">
import { reactive, ref, unref } from 'vue'
import {
getRepStoreListApi,
saveRepStoreApi,
delRepStoreListApi,
delRepStoreApi,
queryRepStoreApi,
importExcelApiUrl,
exportExcelApi
} from '@/api/dataset/RepStore'
import { TableData } from '@/api/dataset/RepStore/types'
import { useTable } from '@/hooks/web/useTable'
import { useI18n } from '@/hooks/web/useI18n'
import { Table, TableColumn } from '@/components/Table'
import { ElButton, ElLink, ElLoading, ElPopconfirm, ElMessage } from 'element-plus'
import { Search } from '@/components/Search'
import { FormSchema } from '@/components/Form'
import { ContentWrap } from '@/components/ContentWrap'
import Write from './components/Write.vue'
import { Dialog } from '@/components/Dialog'
import { getWidth } from '@/utils';
import { Upload } from '@/components/Upload'
import {useRoute,useRouter} from "vue-router"
const route = useRoute();
const pageQuery = ref(route || null);
const modelCode = pageQuery.value?.query?.modelCode;
import { OPERATION_TYPE_LIST,RULE_TYPE_LIST } from './constants';
const router = useRouter();
const { t } = useI18n()
const ids = ref<string[]>([])
const { tableRegister, tableState, tableMethods } = useTable({
fetchDataApi: async () => {
const { currentPage, pageSize } = tableState
const res = await getRepStoreListApi({
pageIndex: unref(currentPage),
pageSize: unref(pageSize),
...unref(searchParams)
})
return {
list: res.body.list,
total: res.body.total
}
},
fetchDelApi: async () => {
const res = await delRepStoreListApi(unref(ids));
return !!res;
},
})
const { loading, dataList, total, currentPage, pageSize } = tableState
const { getList, getElTableExpose, delList, refresh } = tableMethods
const tableColumns = reactive<TableColumn[]>([
{
field: 'selection',
type: 'selection',
fixed: true
},
{
field: 'modelCode',
label: '模型编码 '
},
{
field: 'beginDate',
label: '开始日期'
},
{
field: 'endDate',
label: '结束日期'
},
{
field: 'dscode',
label: '数据源'
},
{
field: 'storeType',
label: '规则类型',
slots:{
default:(data:any)=>{
return <span>{RULE_TYPE_LIST[data.row.storeType -1]?.label}</span>
}
}
},
{
field: 'storeContent',
label: '规则内容'
},
{
field: 'storeOperateType',
label: '操作类型',
slots:{
default:(data:any)=>{
return <span>{OPERATION_TYPE_LIST[data.row.storeOperateType -1]?.label}</span>
}
}
},
{
field: 'action',
label: t('tableDemo.action'),
width: 240,
fixed: 'right',
slots: {
default: (data: any) => {
return (
<>
<ElLink type="primary" underline={false} onClick={() => getModelParam(data.row)}>
映射
</ElLink>
<ElLink type="primary" underline={false} onClick={() => getModelMapping(data.row)}>
参数
</ElLink>
<ElLink type="primary" underline={false} onClick={() => action(data.row, 'edit')}>
{t('tableDemo.edit')}
</ElLink>
<ElPopconfirm
title={t('common.delTableMsg')}
width={200}
v-slots={{
reference: () => {
return (
<>
<ElLink type="primary" underline={false}>
{t('tableDemo.del')}
</ElLink>
</>
)
}
}}
onConfirm={() => delData(data.row)}
></ElPopconfirm>
</>
)
}
}
}
].map(item => ({ minWidth: item.label ? getWidth(item.label) : 120, ...item }) as TableColumn))
const searchSchema = reactive<FormSchema[]>([
{
field: 'modelCode',
label: '模型编码 ',
componentProps: {},
component: 'Input',
value:modelCode
},
{
field: 'tableName',
label: '表名',
componentProps: {},
component: 'Input'
}
])
const searchParams = ref({})
const setSearchParams = (data: any) => {
searchParams.value = data
getList()
}
setSearchParams({modelCode:modelCode})
const dialogVisible = ref(false)
const dialogTitle = ref('')
const currentRow = ref()
const actionType = ref('')
const writeRef = ref<ComponentRef<typeof Write>>()
/**单行查询**/
const action = async (row: TableData, type: string) => {
let detailLoading = ElLoading.service({
background: 'rgba(0, 0, 0, 0.7)'
})
const res = await queryRepStoreApi(row.modelCode, row.beginDate, row.endDate, row.ruleId)
.catch(() => {})
.finally(() => {
detailLoading.close()
})
detailLoading.close()
if (res) {
const data = res.body.result
dialogTitle.value = t(type === 'edit' ? 'tableDemo.edit' : 'tableDemo.detail')
actionType.value = type
currentRow.value = data
dialogVisible.value = true
}
}
/** 数据模型规则 **/
const getModelParam = (data)=>{
console.log(data);
router.push({
name:'repStoreParameter',
query:{
modelCode:data.modelCode,
}
})
}
/** 数据模型映射 **/
const getModelMapping = (data)=>{
console.log(data);
router.push({
name:'repStoreMapping',
query:{
modelCode:data.modelCode,
}
})
}
const AddAction = () => {
dialogTitle.value = t('tableDemo.add')
currentRow.value = undefined
dialogVisible.value = true
actionType.value = 'add'
}
const saveLoading = ref(false)
/** 保存 **/
const save = async () => {
const write = unref(writeRef)
const formData = await write?.submit()
if (formData) {
saveLoading.value = true
const res = await saveRepStoreApi(formData)
.catch(() => {})
.finally(() => {
saveLoading.value = false
})
if (res) {
dialogVisible.value = false
currentPage.value = 1
getList()
}
}
}
const delLoading = ref(false)
/** 批量删除 **/
const delDataBatch = async () => {
const elTableExpose = await getElTableExpose()
ids.value = elTableExpose?.getSelectionRows().map((v: TableData) => { v.modelCode, v.beginDate, v.endDate, v.ruleId }) || []
delLoading.value = true
await delList(unref(ids).length).finally(() => {
delLoading.value = false
})
}
/** 单行删除 */
const delData = async (row: TableData) => {
const res = await delRepStoreApi(row.modelCode, row.beginDate, row.endDate, row.ruleId)
if (res) {
const { code, errMsg } = res.head
if (code === '0') {
ElMessage.success('删除成功!')
getList()
} else {
ElMessage.error(errMsg || '删除失败!')
}
}
}
const disabled = ref(true)
const onSelectionChange = (selection: TableData[]) => {
disabled.value = selection.length === 0
}
/** 导出Excel */
const exportExcel = async () => {
const data = { ...unref(searchParams) }
await exportExcelApi(data)
}
</script>
<template>
<ContentWrap>
<Search :schema="searchSchema" @reset="setSearchParams" @search="setSearchParams" />
<Table
:columns="tableColumns"
v-model:pageSize="pageSize"
v-model:currentPage="currentPage"
default-expand-all
:data="dataList"
:loading="loading"
:pagination="{
total
}"
@selection-change="onSelectionChange"
@register="tableRegister"
@refresh="refresh"
>
<template #buttons>
<ElButton type="primary" @click="AddAction">{{ t('tableDemo.add') }}</ElButton>
<Upload :url="importExcelApiUrl" :callback="getList"> <ElButton type="primary">导入</ElButton> </Upload>
<ElButton type="primary" @click="exportExcel()"></ElButton>
<ElButton :loading="delLoading" type="primary" :disabled="disabled" @click="delDataBatch()">
{{ t('tableDemo.del') }}
</ElButton>
</template>
</Table>
</ContentWrap>
<Dialog v-model="dialogVisible" :title="dialogTitle">
<Write
v-if="actionType !== 'detail'"
ref="writeRef"
:current-row="currentRow"
:action-type="actionType"
/>
<Detail v-if="actionType === 'detail'" :current-row="currentRow" />
<template #footer>
<ElButton v-if="actionType !== 'detail'" type="primary" :loading="saveLoading" @click="save">
{{ t('dialogDemo.save') }}
</ElButton>
<ElButton @click="dialogVisible = false">{{ t('dialogDemo.close') }}</ElButton>
</template>
</Dialog>
</template>

@ -0,0 +1,71 @@
<script setup lang="tsx">
import { PropType, ref } from 'vue'
import { TableData } from '@/api/dataset/RepStore/types'
import { Descriptions, DescriptionsSchema } from '@/components/Descriptions'
const detailSchema = ref<DescriptionsSchema[]>([
{
field: 'modelCode',
label: '模型编码 '
},
{
field: 'beginDate',
label: '开始日期'
},
{
field: 'endDate',
label: '结束日期'
},
{
field: 'dscode',
label: '数据源'
},
{
field: 'storeType',
label: '规则类型'
},
{
field: 'storeContent',
label: '规则内容'
},
{
field: 'storeOperateType',
label: '操作类型'
},
{
field: 'ruleId',
label: '存储规则id'
},
{
field: 'scheme',
label: '数据库用户'
},
{
field: 'tableName',
label: '表名'
},
{
field: 'validateResultTable',
label: '校验结果表的表名'
},
{
field: 'dataRule',
label: '数据规则'
},
{
field: 'redscode',
label: '备份数据源'
}
])
defineProps({
currentRow: {
type: Object as PropType<TableData>,
default: () => {}
}
})
</script>
<template>
<Descriptions :schema="detailSchema" :data="currentRow || {}" />
</template>

@ -0,0 +1,171 @@
<script setup lang="tsx">
import { Form, FormSchema } from '@/components/Form'
import { useForm } from '@/hooks/web/useForm'
import { PropType, reactive, watch } from 'vue'
import { useValidator } from '@/hooks/web/useValidator'
import { OPERATION_TYPE_LIST,RULE_TYPE_LIST } from '../constants';
const { required } = useValidator()
const props = defineProps({
currentRow: {
type: Object as PropType<any>,
default: () => null
},
actionType: {
type: String,
default: 'add'
}
})
const { formRegister, formMethods } = useForm()
const { setValues, getFormData, getElFormExpose } = formMethods
const formSchema = reactive<FormSchema[]>([
{
field: 'modelCode',
label: '模型编码 ',
component: 'Input',
componentProps: {
},
},
{
field: 'beginDate',
label: '开始日期',
component: 'Input',
componentProps: {
},
},
{
field: 'endDate',
label: '结束日期',
component: 'Input',
componentProps: {
},
},
{
field: 'dscode',
label: '数据源',
component: 'Input',
componentProps: {
},
},
{
field: 'storeType',
label: '规则类型',
component: 'Select',
componentProps: {
options:RULE_TYPE_LIST
},
value:'1'
},
{
field: 'storeContent',
label: '规则内容',
component: 'Input',
componentProps: {
},
},
{
field: 'storeOperateType',
label: '操作类型',
component: 'Select',
componentProps: {
options:OPERATION_TYPE_LIST
},
value:'1'
},
{
field: 'ruleId',
label: '存储规则id',
component: 'Input',
componentProps: {
},
},
{
field: 'scheme',
label: '数据库用户',
component: 'Input',
componentProps: {
},
},
{
field: 'tableName',
label: '表名',
component: 'Input',
componentProps: {
},
},
{
field: 'validateResultTable',
label: '校验结果表的表名',
component: 'Input',
componentProps: {
},
},
{
field: 'dataRule',
label: '数据规则',
component: 'Input',
componentProps: {
},
},
{
field: 'redscode',
label: '备份数据源',
component: 'Input',
componentProps: {
},
}
])
const rules = reactive({
modelCode: [required()],
beginDate: [required()],
endDate: [required()],
ruleId: [required()],
})
const submit = async () => {
const elForm = await getElFormExpose()
const valid = await elForm?.validate().catch((err) => {
console.log(err)
})
if (valid) {
const formData = await getFormData()
return formData
}
}
watch(
() => props.currentRow,
(currentRow) => {
if (!currentRow) return
setValues(currentRow)
},
{
deep: true,
immediate: true
}
)
defineExpose({
submit
})
</script>
<template>
<Form :rules="rules" @register="formRegister" :schema="formSchema" />
</template>

@ -0,0 +1,21 @@
export const OPERATION_TYPE_LIST = [//操作类型1表2sql
{
value:"1",
label:"表"
},
{
value:"2",
label:"sql"
}
]
export const RULE_TYPE_LIST = [//规则类型 1只读2读写
{
value:"1",
label:"只读"
},
{
value:"2",
label:"读写"
}
]

@ -22,6 +22,11 @@ import { Dialog } from '@/components/Dialog'
import { getWidth } from '@/utils';
import Detail from './components/Detail.vue'
import { Upload } from '@/components/Upload'
import { WHETHER_UUID_LIST,WHETHER_UNITEDKEY_LIST } from './constants'
import {useRoute} from "vue-router"
const route = useRoute();
const pageQuery = ref(route || null);
const modelCode = pageQuery.value?.query?.modelCode;
const { t } = useI18n()
@ -73,7 +78,7 @@ const tableColumns = reactive<TableColumn[]>([
},
{
field: 'mappingName',
label: '映射目标列名称'
label: '映射目标列名称'
},
{
field: 'mappingCol',
@ -93,7 +98,12 @@ const tableColumns = reactive<TableColumn[]>([
},
{
field: 'primarykey',
label: '组成联合主键'
label: '组成联合主键',
slots:{
default:(data:any)=>{
return <span>{WHETHER_UNITEDKEY_LIST[data.row.primarykey]?.label}</span>
}
}
},
{
field: 'primaryKeyNum',
@ -101,7 +111,12 @@ const tableColumns = reactive<TableColumn[]>([
},
{
field: 'uuid',
label: '标识是否为uuid'
label: '标识是否为uuid',
slots:{
default:(data:any)=>{
return <span>{WHETHER_UUID_LIST[data.row.uuid]?.label}</span>
}
}
},
{
field: 'action',
@ -143,7 +158,8 @@ const searchSchema = reactive<FormSchema[]>([
field: 'modelCode',
label: '数据模型编码',
componentProps: {},
component: 'Input'
component: 'Input',
value:modelCode
},
{
field: 'ruleId',
@ -159,7 +175,7 @@ const searchSchema = reactive<FormSchema[]>([
},
{
field: 'mappingName',
label: '映射目标列名称',
label: '映射目标列名称',
componentProps: {},
component: 'Input'
}
@ -171,6 +187,8 @@ const setSearchParams = (data: any) => {
getList()
}
setSearchParams({modelCode:modelCode})
const dialogVisible = ref(false)
const dialogTitle = ref('')

@ -2,7 +2,10 @@
import { Form, FormSchema } from '@/components/Form'
import { useForm } from '@/hooks/web/useForm'
import { PropType, reactive, watch } from 'vue'
import { WHETHER_UUID_LIST,WHETHER_UNITEDKEY_LIST } from '../constants'
import { useValidator } from '@/hooks/web/useValidator'
import { ElButton, ElMessage, ElMessageBox } from 'element-plus';
const { required } = useValidator()
@ -55,7 +58,7 @@ const formSchema = reactive<FormSchema[]>([
},
{
field: 'mappingName',
label: '映射目标列名称',
label: '映射目标列名称',
component: 'Input',
componentProps: {
@ -96,10 +99,14 @@ const formSchema = reactive<FormSchema[]>([
{
field: 'primarykey',
label: '组成联合主键',
component: 'Input',
component: 'Select',
componentProps: {
options:WHETHER_UNITEDKEY_LIST
},
value:'0',
formItemProps: {
rules: [required()],
}
},
{
field: 'primaryKeyNum',
@ -112,10 +119,14 @@ const formSchema = reactive<FormSchema[]>([
{
field: 'uuid',
label: '标识是否为uuid',
component: 'Input',
component: 'Select',
componentProps: {
options:WHETHER_UUID_LIST
},
value:'0',
formItemProps: {
rules: [required()],
}
}
])

@ -0,0 +1,21 @@
export const WHETHER_UUID_LIST = [//标识是否是uuid0不是1是
{
value:"0",
label:"不是"
},
{
value:"1",
label:"是"
}
]
export const WHETHER_UNITEDKEY_LIST = [//组成联合主键 0:否 1:是
{
value:"0",
label:"否"
},
{
value:"1",
label:"是"
}
]

@ -22,10 +22,13 @@ import { Dialog } from '@/components/Dialog'
import { getWidth } from '@/utils';
import Detail from './components/Detail.vue'
import { Upload } from '@/components/Upload'
const { t } = useI18n()
const ids = ref<string[]>([])
import {useRoute} from "vue-router"
const route = useRoute();
const pageQuery = ref(route || null);
const modelCode = pageQuery.value?.query?.modelCode;
const { tableRegister, tableState, tableMethods } = useTable({
fetchDataApi: async () => {
@ -120,29 +123,18 @@ const tableColumns = reactive<TableColumn[]>([
const searchSchema = reactive<FormSchema[]>([
{
field: 'modelCode',
label: '模型编码',
componentProps: {},
component: 'Input'
},
{
field: 'ruleId',
label: '规则编码',
componentProps: {},
component: 'Input'
},
{
field: 'name',
label: '名称',
componentProps: {},
component: 'Input'
},
{
field: 'paramType',
label: '参数类型',
componentProps: {},
component: 'Select'
}
field: 'modelCode',
label: '模型编码',
componentProps: {},
component: 'Input',
value:modelCode
},
{
field: 'name',
label: '模型名称',
componentProps: {},
component: 'Input'
}
])
const searchParams = ref({})
@ -150,6 +142,7 @@ const setSearchParams = (data: any) => {
searchParams.value = data
getList()
}
setSearchParams({modelCode:modelCode})
const dialogVisible = ref(false)
const dialogTitle = ref('')

@ -203,20 +203,13 @@ const action = async (row: TableData, type: string) => {
}
/** 预览 **/
const ShowPreViewFile = (data)=>{
console.log(data);
router.push({
const routeData = router.resolve({
name:'PreViewFile',
query:{
fileData:data.pId,
}
})
// const routeData = router.resolve({
// name:'PreViewFile',
// query:{
// fileData:JSON.stringify(data),
// }
// })
// window.open(routeData.href,'_blank')
window.open(routeData.href,'_blank')
}
const AddAction = () => {

@ -120,9 +120,6 @@ const tableColumns = reactive<TableColumn[]>([
default: (data: any) => {
return (
<>
<ElLink type="primary" underline={false} onClick={() => ShowPreViewFile(data.row)}>
预览
</ElLink>
<ElLink type="primary" underline={false} onClick={() => action(data.row, 'edit')}>
{t('tableDemo.edit')}
</ElLink>
@ -180,20 +177,6 @@ const searchSchema = reactive<FormSchema[]>([
component: 'DatePicker'
}
])
/** 预览 **/
const ShowPreViewFile = (data)=>{
const routeData = router.resolve({
name:'PreViewFile',
query:{
fileData:data.fileFlow,
}
})
router.push({name:'PreViewFile',
query:{
fileData:data.fileFlow,
}});
// window.open(routeData.href,'_blank')
}
const searchParams = ref({})
const setSearchParams = (data: any) => {
searchParams.value = data

Loading…
Cancel
Save