修改模版

dev
suixy 1 month ago
parent 834ed22f5b
commit 386d30737c

@ -74,3 +74,11 @@ export function getBaseTemplateVariableList (query) {
params: query
});
};
export function templateAssign(query) {
return request({
url: '/oa/base/templateVariable/assign',
method: 'post',
data: query
});
};

@ -29,16 +29,7 @@ const template = ref({});
const editorRef = ref();
const fieldList = ref([
{
name: '字段1',
value: '${ziduan1}'
},
{
name: '字段2',
value: '${ziduan2}'
}
]);
const fieldList = ref([]);
const templateData = {
data0: '合计-1',
@ -102,7 +93,7 @@ const options = ref({
},
autoSave: {
enabled: true,
interval: 300000
interval: 1000 * 60 * 5
}
},
page: {
@ -119,7 +110,7 @@ const options = ref({
}
});
const renderTemplate = (str, data) => {
return str.replace(/&\{(.*?)\}/g, (_, path) => {
return str.replace(/#\{(.*?)\}/g, (_, path) => {
// console.log(path.split('.').reduce((o, k) => o?.[k], data) ?? '');
return path.split('.').reduce((o, k) => o?.[k], data) ?? '';
});
@ -207,10 +198,15 @@ const fillData = (e) => {
const insertText = (e) => {
const editor = editorRef.value;
editor.insertContent({
type: 'text',
text: e.varName
});
editor.insertContent(
{
type: 'text',
text: e.varName
},
{
updateSelection: false
}
);
};
onMounted(async () => {
getPrintTemplate(route.query.templateId).then((e) => {

@ -0,0 +1,228 @@
<template>
<div>
<div style="width: 100%; display: inline-block; vertical-align: top; height: calc(100vh - 50px - 34px)">
<umo-editor v-bind="options" ref="editorRef" />
</div>
</div>
</template>
<script setup>
import { UmoEditor } from '@umoteam/editor';
import { getPrintTemplate, updatePrintTemplate } from '@/api/oa/base/printTemplate';
import router from '@/router/index.js';
import { useRoute } from 'vue-router';
import { getBaseTemplateVariableList, templateAssign } from '@/api/oa/base/templateVariable/index.js';
const route = useRoute();
const template = ref({});
const editorRef = ref();
const fieldList = ref([]);
let templateData = {};
const options = ref({
document: {
title: '',
content: {
type: 'doc',
content: []
},
placeholder: {
en_US: 'Please enter the document content...',
zh_CN: '请输入文档内容...'
},
enableSpellcheck: true,
enableMarkdown: false,
enableBubbleMenu: true,
enableBlockMenu: true,
readOnly: false,
autofocus: true,
characterLimit: 0,
typographyRules: {
emDash: false
},
editorProps: {},
parseOptions: {
preserveWhitespace: 'full'
},
autoSave: {
enabled: true,
interval: 1000 * 60 * 5
}
},
page: {
showBreakMarks: false
},
onSave: async (e) => {
return true;
}
});
//
const renderTemplate = (str, data) => {
return str.replace(/#\{(.*?)\}/g, (_, path) => {
return path.split('.').reduce((o, k) => o?.[k], data) ?? '';
});
};
//
const rowRenderTemplate = (str, index) => {
return str.replace(/\^\{(.*?)\}/g, (_, path) => {
return templateData[path][index] || ' ';
});
};
//
const hasCaretPattern = (arr) => {
// ^{xxx}
const regex = /\^\{.*?\}/;
let length = 0;
let res = false;
function traverse(items) {
for (const item of items) {
if (item.text && regex.test(item.text)) {
length = Math.max(length, templateData[extractPlaceholders(item.text)].length || 0);
res = true; //
}
if (item.content && Array.isArray(item.content)) {
traverse(item.content);
}
}
}
traverse(arr);
return [res, length];
};
// ;
const fillRowData = (e, index) => {
if (Array.isArray(e.content)) {
e.content.map((item) => {
return fillRowData(item, index);
});
} else {
e.text = rowRenderTemplate(e.text || '', index);
}
console.log(e);
return e;
};
//
const tableTemplate = (table) => {
let data = JSON.parse(JSON.stringify(table));
let arr = [];
data.forEach((item) => {
let [bol, length] = hasCaretPattern(JSON.parse(JSON.stringify(item.content)));
if (bol) {
let obj = JSON.parse(JSON.stringify(item));
Array(length)
.fill(0)
.forEach((_, index) => {
arr.push(fillRowData(obj, index));
});
// arr.push(fillRowData(JSON.parse(JSON.stringify({ ...item, content: row })), requestData[key]));
} else {
arr.push(fillData(item));
}
});
return arr.filter((item) => item);
};
//
const fillData = (e) => {
if (e.type === 'table') {
e.content = tableTemplate(e.content);
} else {
if (Array.isArray(e.content)) {
e.content.map((item) => {
return fillData(item);
});
} else {
e.text = renderTemplate(e.text || '', templateData);
}
}
return e;
};
const insertText = (e) => {
const editor = editorRef.value;
editor.insertContent(
{
type: 'text',
text: e.varName
},
{
updateSelection: false
}
);
};
function extractPlaceholders(str) {
const regex = /[#\^]\{([^}]+)\}/g; // #{...} ^{...}
const result = [];
let match;
while ((match = regex.exec(str)) !== null) {
result.push(match[1]);
}
return result;
}
onMounted(async () => {
const { data: assignData } = await templateAssign({ templateType: 1, contractId: route.query.contractId });
templateData = {};
assignData.forEach((item) => {
templateData[extractPlaceholders(item.varName)] = item.varValue;
});
// console.log(templateData);
getPrintTemplate(route.query.templateId).then((e) => {
template.value = e.data;
const editor = editorRef.value;
let docData = JSON.parse(e.data.templateData || '{}');
let data = fillData(docData);
// console.log(data);
// console.log(JSON.parse(e.data.templateData || '{}'));
// editor.setContent(JSON.parse(e.data.templateData || '{}'));
editor.setContent(data);
});
});
</script>
<style scoped>
.title {
width: 100%;
line-height: 40px;
font-size: 14px;
color: #666;
text-align: center;
}
.fieldList {
width: 100%;
height: calc(100vh - 50px - 34px - 40px);
overflow-y: auto;
.fieldItem {
width: 80%;
font-size: 12px;
padding-left: 15px;
color: #333;
cursor: pointer;
.btn {
padding: 10px;
&:hover {
background-color: #eee;
border-radius: 10px;
}
}
}
}
</style>
<style>
.umo-footer {
position: sticky;
bottom: 0px;
}
</style>

@ -163,9 +163,12 @@
</el-table-column>
<el-table-column label="操作" align="center" width="150" fixed="right" class-name="small-padding fixed-width">
<template #default="scope">
<el-tooltip content="查看" placement="top" v-if="scope.row.contractStatus !== '1'">
<el-tooltip content="查看" placement="top" v-if="scope.row.contractStatus !== '1'">
<el-button link type="info" icon="DocumentChecked" @click="handleView(scope.row)"></el-button>
</el-tooltip>
<el-tooltip content="查看合同" placement="top" v-if="scope.row.contractStatus !== '1'">
<el-button link type="info" icon="Reading" @click="contractView(scope.row)"></el-button>
</el-tooltip>
<el-tooltip content="修改" placement="top" v-if="scope.row.contractStatus === '1'">
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['oa/erp:contractInfo:edit']"></el-button>
</el-tooltip>
@ -436,4 +439,10 @@ const downloadFinalContract = (ossId: string | number) => {
const handleApprovalRecord = (row: ContractInfoVO) => {
approvalRecordRef.value?.init(row.contractId);
};
//
const contractView = (e) => {
console.log(e);
router.push({ path: '/contract/contractView', query: { templateId: e.templateId, contractId: e.contractId } });
};
</script>

Loading…
Cancel
Save