word/src/App.vue
2024-07-09 15:03:32 +08:00

1396 lines
41 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup>
import HelloWorld from './components/HelloWorld.vue'
import TheWelcome from './components/TheWelcome.vue'
</script>
<template>
<div class="Cityk-common-layout">
<div>
<div class="menu" editor-component="menu">
<el-button @click="getHTMLValuea">保存配置</el-button>
<el-button @click="getShow">预览</el-button>
<el-button @click="changeConfig">切换配置</el-button>
<!-- <el-button @click="getHTMLValue">保存样式</el-button> -->
<div class="menu-item">
<div class="menu-item__undo" @click="executeUndo">
<i></i>
</div>
<div class="menu-item__redo" @click="executeRedo">
<i></i>
</div>
<div class="menu-item__painter" title="格式刷(双击可连续使用)" @lclick="painterDom" @dbclick="dbPainterDom">
<i></i>
</div>
<div class="menu-item__format" title="清除格式" @click="executeFormat">
<i></i>
</div>
</div>
<div class="menu-divider"></div>
<div class="menu-item">
<div class="menu-item__font" @click="clickHandle2">
<span class="select" title="字体">微软雅黑</span>
<div class="options" @click="clickHandle3">
<ul>
<li data-family="Microsoft YaHei" style="font-family:'Microsoft YaHei';">微软雅黑</li>
<li data-family="宋体" style="font-family:'宋体';">宋体</li>
<li data-family="黑体" style="font-family:'黑体';">黑体</li>
<li data-family="仿宋" style="font-family:'仿宋';">仿宋</li>
<li data-family="楷体" style="font-family:'楷体';">楷体</li>
<li data-family="等线" style="font-family:'等线';">等线</li>
<li data-family="华文琥珀" style="font-family:'华文琥珀';">华文琥珀</li>
<li data-family="华文楷体" style="font-family:'华文楷体';">华文楷体</li>
<li data-family="华文隶书" style="font-family:'华文隶书';">华文隶书</li>
<li data-family="华文新魏" style="font-family:'华文新魏';">华文新魏</li>
<li data-family="华文行楷" style="font-family:'华文行楷';">华文行楷</li>
<li data-family="华文中宋" style="font-family:'华文中宋';">华文中宋</li>
<li data-family="华文彩云" style="font-family:'华文彩云';">华文彩云</li>
<li data-family="Arial" style="font-family:'Arial';">Arial</li>
<li data-family="Segoe UI" style="font-family:'Segoe UI';">Segoe UI</li>
<li data-family="Ink Free" style="font-family:'Ink Free';">Ink Free</li>
<li data-family="Fantasy" style="font-family:'Fantasy';">Fantasy</li>
</ul>
</div>
</div>
<div class="menu-item__size" @click="clickHandle4">
<span class="select" title="字体">小四</span>
<div class="options" @click="clickHandle5">
<ul>
<li data-size="56">初号</li>
<li data-size="48">小初</li>
<li data-size="34">一号</li>
<li data-size="32">小一</li>
<li data-size="29">二号</li>
<li data-size="24">小二</li>
<li data-size="21">三号</li>
<li data-size="20">小三</li>
<li data-size="18">四号</li>
<li data-size="16">小四</li>
<li data-size="14">五号</li>
<li data-size="12">小五</li>
<li data-size="10">六号</li>
<li data-size="8">小六</li>
<li data-size="7">七号</li>
<li data-size="6">八号</li>
</ul>
</div>
</div>
<div class="menu-item__size-add" @click="executeSizeAdd">
<i></i>
</div>
<div class="menu-item__size-minus" @click="executeSizeMinus">
<i></i>
</div>
<div class="menu-item__bold" @click="executeBold">
<i></i>
</div>
<div class="menu-item__italic" @click="executeItalic">
<i></i>
</div>
<div class="menu-item__underline" @click="executeUnderline">
<i></i>
<span class="select"></span>
<div class="options">
<ul>
<li data-decoration-style='solid'>
<i></i>
</li>
<li data-decoration-style='double'>
<i></i>
</li>
<li data-decoration-style='dashed'>
<i></i>
</li>
<li data-decoration-style='dotted'>
<i></i>
</li>
<li data-decoration-style='wavy'>
<i></i>
</li>
</ul>
</div>
</div>
<div class="menu-item__strikeout" title="删除线(Ctrl+Shift+X)" @click="executeStrikeout">
<i></i>
</div>
<div class="menu-item__superscript" @click="executeSuperscript">
<i></i>
</div>
<div class="menu-item__subscript" @click="executeSubscript">
<i></i>
</div>
<div class="menu-item__color" title="字体颜色" @click="selectColor">
<i></i>
<span></span>
<input type="color" id="color" />
</div>
<div class="menu-item__highlight" title="高亮" @click="highlight">
<i></i>
<span></span>
<input type="color" id="highlight">
</div>
</div>
<div class="menu-divider"></div>
<div class="menu-item">
<div class="menu-item__title" @click="isShow = !isShow">
<i></i>
<span class="select" title="切换标题">正文</span>
<div class="options" :class="{ visible: isShow }">
<ul>
<li style="font-size:16px;">正文</li>
<li @click="executeTitle($event)" data-level="first" style="font-size:26px;">标题1
</li>
<li @click="executeTitle($event)" data-level="second" style="font-size:24px;">标题2
</li>
<li @click="executeTitle($event)" data-level="third" style="font-size:22px;">标题3
</li>
<li @click="executeTitle($event)" data-level="fourth" style="font-size:20px;">标题4
</li>
<li @click="executeTitle($event)" data-level="fifth" style="font-size:18px;">标题5
</li>
<li @click="executeTitle($event)" data-level="sixth" style="font-size:16px;">标题6
</li>
</ul>
</div>
</div>
<div class="menu-item__left" @click="rowFlexLeft">
<i></i>
</div>
<div class="menu-item__center" @click="rowFlexCenter">
<i></i>
</div>
<div class="menu-item__right" @click="rowFlexRight">
<i></i>
</div>
<div class="menu-item__alignment" @click="rowFlexAlignment">
<i></i>
</div>
<!--<div class="menu-item__justify">
<i></i>
</div>-->
<div class="menu-item__row-margin" @click="rowMargin">
<i title="行间距"></i>
<div class="options">
<ul>
<li data-rowmargin='1' @click="setRowMargin">1</li>
<li data-rowmargin="1.25" @click="setRowMargin">1.25</li>
<li data-rowmargin="1.5" @click="setRowMargin">1.5</li>
<li data-rowmargin="1.75" @click="setRowMargin">1.75</li>
<li data-rowmargin="2" @click="setRowMargin">2</li>
<li data-rowmargin="2.5" @click="setRowMargin">2.5</li>
<li data-rowmargin="3" @click="setRowMargin">3</li>
</ul>
</div>
</div>
<div class="menu-item__list" @click="menuList">
<i></i>
<div class="options">
<ul>
<!-- <li>
<label>取消列表</label>
</li> -->
<li data-list-type="ol" data-list-style='decimal' @click="setMenuList">
<label>有序列表</label>
<ol>
<li>________</li>
</ol>
</li>
<li data-list-type="ul" data-list-style='checkbox' @click="setMenuList">
<label>复选框列表</label>
<ul style="list-style-type: '☑️ ';">
<li>________</li>
</ul>
</li>
<li data-list-type="ul" data-list-style='disc' @click="setMenuList">
<label>实心圆点列表</label>
<ul style="list-style-type: disc;">
<li>________</li>
</ul>
</li>
<li data-list-type="ul" data-list-style='circle' @click="setMenuList">
<label>空心圆点列表</label>
<ul style="list-style-type: circle;">
<li>________</li>
</ul>
</li>
<li data-list-type="ul" data-list-style='square' @click="setMenuList">
<label>空心方块列表</label>
<ul style="list-style-type: square;">
<li>________</li>
</ul>
</li>
</ul>
</div>
</div>
</div>
<div class="menu-divider"></div>
<div class="menu-item">
<div class="menu-item__table" @click="clickHandle7">
<i title="表格"></i>
</div>
<div class="menu-item__table__collapse">
<div class="table-close" @click="tableClose">×</div>
<div class="table-title">
<span class="table-select">插入</span>
<span>表格</span>
</div>
<div class="table-panel" @click="tablePanel" @mousemove="ceshi"></div>
</div>
<div class="menu-item__image" @click="getSelectImage">
<i title="图片"></i>
<input @change="selectImage" type="file" id="image" accept=".png, .jpg, .jpeg, .svg, .gif">
</div>
<div class="menu-item__hyperlink" @click="executeHyperlink">
<i title="超链接"></i>
</div>
<div class="menu-item__separator" @click="separatorDom">
<i title="分割线"></i>
<div class="options">
<ul>
<li data-separator='0,0' @click="insertSeparator">
<i></i>
</li>
<li data-separator="1,1" @click="insertSeparator">
<i></i>
</li>
<li data-separator="3,1" @click="insertSeparator">
<i></i>
</li>
<li data-separator="4,4" @click="insertSeparator">
<i></i>
</li>
<li data-separator="7,3,3,3" @click="insertSeparator">
<i></i>
</li>
<li data-separator="6,2,2,2,2,2" @click="insertSeparator">
<i></i>
</li>
</ul>
</div>
</div>
<div class="menu-item__watermark" @click="waterMark">
<i title="水印(添加、删除)"></i>
<div class="options">
<ul>
<li data-menu="add" @click="setWaterMark">添加水印</li>
<li data-menu="delete" @click="setWaterMark">删除水印</li>
</ul>
</div>
</div>
<!-- <div class="menu-item__codeblock" title="代码块">
<i></i>
</div> -->
<div class="menu-item__page-break" title="分页符" @click="executePageBreak">
<i></i>
</div>
<!-- <div class="menu-item__control">
<i title="控件"></i>
<div class="options">
<ul>
<li data-control='text'>文本</li>
<li data-control="select">列举</li>
<li data-control="checkbox">复选框</li>
<li data-control="radio">单选框</li>
</ul>
</div>
</div> -->
<div class="menu-item__checkbox" title="复选框" @click="executeInsertElementList">
<i></i>
</div>
<!---<div class="menu-item__radio" title="单选框">
<i></i>
</div>
<div class="menu-item__latex" title="LateX">
<i></i>
</div>-->
<div class="menu-item__date" @click="executeDate">
<i title="日期"></i>
<div class="options">
<ul>
<li data-format="yyyy-MM-dd" @click="executeSetDate"></li>
<li data-format="yyyy-MM-dd hh:mm:ss" @click="executeSetDate"></li>
</ul>
</div>
</div>
<div class="menu-item__block" title="内容块" @click="executeBlock">
<i></i>
</div>
</div>
<div class="menu-divider"></div>
<div class="menu-item">
<!-- <div class="menu-item__search" data-menu="search">
<i></i>
</div>
<div class="menu-item__search__collapse" data-menu="search">
<div class="menu-item__search__collapse__search">
<input type="text" />
<label class="search-result"></label>
<div class="arrow-left">
<i></i>
</div>
<div class="arrow-right">
<i></i>
</div>
<span>×</span>
</div>
<div class="menu-item__search__collapse__replace">
<input type="text">
<button>替换</button>
</div>
</div>-->
<div class="menu-item__print" @click="executePrint" data-menu="print">
<i></i>
</div>
</div>
</div>
<!-- <div class="catalog" editor-component="catalog">
<div class="catalog__header">
<span>目录</span>
<div class="catalog__header__close">
<i></i>
</div>
</div>
<div class="catalog__main"></div>
</div> -->
<div class="editor"></div>
<div class="comment" editor-component="comment"></div>
<div class="footer" editor-component="footer">
<div>
<div class="catalog-mode" title="目录">
<i></i>
</div>
<div class="page-mode">
<i title="页面模式(分页、连页)"></i>
<div class="options">
<ul>
<li data-page-mode="paging" class="active">分页</li>
<li data-page-mode="continuity">连页</li>
</ul>
</div>
</div>
<span>可见页码<span class="page-no-list">1</span></span>
<span>页面<span class="page-no">1</span>/<span class="page-size">1</span></span>
<span>字数<span class="word-count">0</span></span>
</div>
<div class="editor-mode" title="编辑模式(编辑、清洁、只读、表单)">编辑模式</div>
<div>
<div class="page-scale-minus" title="缩小(Ctrl+-)">
<i></i>
</div>
<span class="page-scale-percentage" title="显示比例(点击可复原Ctrl+0)">100%</span>
<div class="page-scale-add" title="放大(Ctrl+=)">
<i></i>
</div>
<div class="paper-size">
<i title="纸张类型"></i>
<div class="options">
<ul>
<li data-paper-size="794*1123" class="active">A4</li>
<li data-paper-size="1593*2251">A2</li>
<li data-paper-size="1125*1593">A3</li>
<li data-paper-size="565*796">A5</li>
<li data-paper-size="412*488">5号信封</li>
<li data-paper-size="450*866">6号信封</li>
<li data-paper-size="609*862">7号信封</li>
<li data-paper-size="862*1221">9号信封</li>
<li data-paper-size="813*1266">法律用纸</li>
<li data-paper-size="813*1054">信纸</li>
</ul>
</div>
</div>
<div class="paper-direction">
<i title="纸张方向"></i>
<div class="options">
<ul>
<li data-paper-direction="vertical" class="active">纵向</li>
<li data-paper-direction="horizontal">横向</li>
</ul>
</div>
</div>
<div class="paper-margin" title="页边距">
<i></i>
</div>
<div class="fullscreen" title="全屏显示">
<i></i>
</div>
<!--<div class="editor-option" title="编辑器设置">
<i></i>
</div>-->
</div>
</div>
<div v-if="confShow" class="main_right">
<el-form ref="form" label-width="120px">
<div v-for="(item, index) in orderData" :key="index">
<div>订单信息{{ index }}:</div>
<div v-for="(value, key, index) in field">
<div v-if="nameField.hasOwnProperty(field[key])">
<el-form-item :label="field[key]" style="margin-bottom: 0;">
<el-input @input="isUpdate" v-model="item[key]" size="small"></el-input>
</el-form-item>
</div>
</div>
<hr>
</div>
</el-form>
</div>
<div v-if="confShow" class="main_left">
<el-form ref="form" label-width="120px">
<el-form-item label="" style="margin-bottom: 0;">
单击即复制成功
</el-form-item>
<div v-for="(value, key, index) in field">
<el-form-item :label="field[key]" @click="copy(field[key])" style="margin-bottom: 0;">
<span @click.stop="copy('{' + field[key] + '}')">{{ '{' + field[key] + '}' }}</span>
</el-form-item>
</div>
</el-form>
</div>
<div v-if="confShow" class="main_search_right">
<el-form ref="form" label-width="100px">
<div v-for="(value, key, index) in searchList" :key="index">
<el-form-item v-if="key != 'id'" :label="searchField[key]" style="margin-bottom: 0;">
<el-input @input="isUpdate" v-model="searchList[key]" size="small"></el-input>
</el-form-item>
</div>
</el-form>
</div>
<div v-if="confShow" class="main_search_left">
<!-- <button type="primary" @click="handleGenerate('imgCode', 'dfdfdfdf')">点击生成二维码</button> -->
<div ref="myDiv" id="imgCode" style="display:none"></div>
<el-form ref="form" label-width="100px">
<el-form-item label="" style="margin-bottom: 0;">
单击即复制成功
</el-form-item>
<div v-for="(value, key, index) in searchField">
<el-form-item :label="searchField[key]" @click="copy(searchField[key])" style="margin-bottom: 0;">
<span @click.stop="copy('{' + searchField[key] + '}')">{{ '{' + searchField[key] + '}' }}</span>
</el-form-item>
</div>
</el-form>
</div>
<!--<div class="canvas-editor" style="height:1000px;width:1000px;margin:0 auto"></div>-->
</div>
</div>
</template>
<script>
import Editor, {
BlockType,
Command,
ControlType,
EditorMode,
EditorZone,
ElementType,
KeyMap,
ListStyle,
ListType,
PageMode,
PaperDirection,
RowFlex,
TitleLevel
} from '@hufe921/canvas-editor'
import axios from 'axios'
import draggable from "vuedraggable"
import QRCode from 'qrcodejs2-fix'
import { Dialog } from './components/dialog/Dialog'
export default {
data() {
return {
fieldArr: [],
confShow: true,
tableCol: 4,
isShow: false,
instance: null,
tableCellList: [],
colIndex: 10,
rowIndex: 10,
orderData: {},
field: {},
nameField: {},
saveData: {},
updateStatus: false,
showObj: {},
config: {},
tableHeight: 42,
tableWidth: 556,
aRow: {},
searchNameField:{},
searchList:{},
searchField:{},
doc:{},
myDiv: null
}
},
mounted() {
this.login()
},
methods: {
handleGenerate(idName, name) {
// 采集二维码:路径
const url = 'https://www.baihand.com?order_id=' + name//`${getIPAddress}?companyId=80&saleId=${name}`;
// 获取二维码码 div 上的 id
const qrCodeElement = document.getElementById(idName);
if (qrCodeElement) {
qrCodeElement.innerHTML = '';
new QRCode(qrCodeElement, {
text: url || '',
width: 100, // 二维码宽度
height: 100, // 二维码高度
});
}
},
copy(value) {
const textArea = document.createElement('textarea');
textArea.value = value;
document.body.appendChild(textArea);
textArea.select();
document.execCommand('copy');
textArea.remove();
console.log(value);
},
getShow() {
this.updateStatus = true
this.init([])
},
isUpdate() {
if (this.tableCol == '' || this.tableCol == '0') {
return false
}
this.updateStatus = true
this.init([])
},
changeConfig() {
this.updateStatus = false
this.init([])
},
login() {
//https://test.yqt.com/
let api = '/api/Administrator/Public/loginJson'
let param = { username: '15238311624', userpwd: '1624' }
let headers = {
'Content-Type': 'application/x-www-form-urlencoded'
}
axios.post(api, param, { headers: headers }).then(res => {
this.getApiField()
})
},
getApiField() {
let api = '/api/Administrator/ProductColConfig/getUserConfig'
axios.get(api).then(res => {
//let field = res.data
let fieldArr = res.data.data
let fieldObj = {}
let nameField = {}
let showObj = {}
let aRow = {}
for (let i = 0; i < fieldArr.length; i++) {
let key = fieldArr[i].field
fieldObj[key] = fieldArr[i].name
showObj[key] = true
aRow[key] = false
nameField[fieldArr[i].name] = key
}
this.nameField = nameField
this.showObj = showObj
this.field = fieldObj
this.fieldArr = fieldArr
this.getApiData()
})
},
getApiData() {
let api = '/api/Administrator/InquiryOrder/getOrderInfo?order_id=E2024060509560254698592'
let api3 ='/api/Administrator/InquirySearchConfig/getUserConfig'
const request1 = axios.get(api)
//const request2 = axios.get(api2)
const request3 = axios.get(api3)
axios.all([request1, request3]).then(axios.spread((response1, response3) => {
//.log(response1, response2)
let data = response1.data
let orderList = data.data.orderExt.productList
let proIdData = [];
for (let k = 0; k < orderList.length; k++) {
const element = orderList[k]
let item = {'proid': element['pid'], 'prolistid': element['plid']}
proIdData.push(item)
}
this.searchList = data.data.searchExt
let order_id = data.data.searchExt['order_id']
this.handleGenerate('imgCode', order_id)
let orderData = data.data.orderExt.productList
let data3 = response3.data
this.orderData = orderData
if(data3.code == 1) {
this.searchConfig = data3.data
let searchNameField = {}
let searchField = {}
searchField['order_id'] = '订单号'
searchNameField['订单号'] = 'order_id'
for (let i = 0; i < data3.data.length; i++) {
let key = data3.data[i].name
searchNameField[key] = data3.data[i].field
searchField[data3.data[i].field] = key
}
this.searchNameField = searchNameField
this.searchField = searchField
}
for (let l = 0; l < proIdData.length; l++) {
const element = proIdData[l];
this.getGongXu(element, l)
}
this.init(orderData)
}))
},
async getGongXu(data, i){
let api = '/api/Administrator/FnProList/getCustomField'
const resData = await axios.post(api, data)
for(let key in resData.data.data.data) {
this.orderData[i][key] = resData.data.data.data[key]
}
let field = resData.data.data.field
let nameField = resData.data.data.name_field
this.field = Object.assign({}, this.field, field)
this.nameField = Object.assign({}, this.nameField, nameField)
},
getHTMLValuea() {
const ccc = this.instance.command.getValue()
//console.log(ccc)
localStorage.setItem('word_data', JSON.stringify(ccc.data))
let saveData = {'type':1, 'field_style':ccc.data}
let api = '/api/Administrator/OrderFieldStyle/save'
axios.post(api, saveData).then((res) => {
})
//this.getTest(ccc.data.main[2].value)
},
getHTMLValue() {
//const aaa = this.instance.command.getHTML()
//const bbb = this.instance.command.getText()
let ccc = this.instance.command.getValue()
//console.log(ccc)
//console.log(this.nameField)
let data = ccc.data.main[0].trList
let flag = 1
let saveData = []
let tempFile = []
let tempData = {}
let isBreak = false
for (let i = 0; i < data.length; i++) {
if (flag % 2 == 1) {
if (data[i].tdList.length > 1) {
for (let j = 0; j < data[i].tdList.length; j++) {
let name = data[i].tdList[j].value[0].value
let style = data[i].tdList[j].value[0]
delete style.value
if (this.nameField.hasOwnProperty(name)) {
let fieldKey = this.nameField[name]
if (tempData.hasOwnProperty(fieldKey)) {
isBreak = true
break
}
tempData[fieldKey] = { 'field_style': style, 'type': 1, 'field': fieldKey }
tempFile.push(fieldKey)
}
}
flag++
}
} else {
if (isBreak) {
break
}
for (let j = 0; j < data[i].tdList.length; j++) {
let fieldKey = tempFile[j]
if (typeof fieldKey === 'undefined') continue
let style = data[i].tdList[j].value[0]
delete style.value
tempData[fieldKey]['value_style'] = style
}
tempFile = []
flag++
}
}
for (let key in tempData) {
saveData.push(tempData[key])
}
//.log(saveData)
return false
let api = '/api/Administrator/OrderFieldStyle/save'
axios.post(api, saveData).then((res) => {
})
},
getImage(ele){
const imgElement = document.querySelector(`#${ele} img`)
const srcValue = imgElement.src
return srcValue
},
replaceData(value) {
///console.log('value', value)
let start = value.indexOf('{')
if(start == -1) {
return value
}
let end = value.indexOf('}')
let fieldKey = value.substring(start + 1, end)
let field = this.searchNameField[fieldKey]
let newValue = this.searchList[field]
value = value.replace('{'+ fieldKey +'}', newValue)
return this.replaceData(value)
},
fillData(config) {
let res = []
let code = this.getImage('imgCode')
for (let i = 0; i < config.length; i++) {
let configItem = config[i]//JSON.parse(JSON.stringify(config[i]))
if(configItem.hasOwnProperty('type') && configItem['type'] == 'table') {
let trList = configItem.trList
let temTrList = {
'colgroup': configItem.colgroup,
'height': configItem.height,
'type': configItem.type,
'width': configItem.width,
'value': configItem.value,
'trList': []
}
for (let j = 0; j < trList.length; j++) {
let trListItem = trList[j]//JSON.parse(JSON.stringify(trList[j]))
let tdList = trListItem.tdList
let title = tdList[0].value[0].value
if(title.indexOf('{') != -1) {
trListItem.tdList = []
for (let k = 0; k < this.orderData.length; k++) {
let tempTdList = []
let order = this.orderData[k];
for (let l = 0; l < tdList.length; l++) {
let tdListItem = tdList[l]//JSON.parse(JSON.stringify(tdList[l]))
let tdValue = tdListItem.value[0].value
let newValue = this.getFieldValue(tdValue, order)
let wocao = {
'colspan': tdListItem.colspan,
'rowspan': tdListItem.rowspan,
'value': [
{
'value': newValue,
'size': tdListItem.value[0].size
}
]
}
tempTdList.push(wocao)
}
let tempTr = {
'height':trListItem.height,
'minHeight':trListItem.minHeight ? trListItem.minHeight : trListItem.height,
'tdList':[]
}
tempTr.tdList = tempTdList
temTrList.trList.push(tempTr)
}
}else{
temTrList.trList.push(trListItem)
continue
}
}
res.push(temTrList)
}else if(configItem.hasOwnProperty('type') && configItem['type'] == 'image'){
configItem.value = code
res.push(configItem)
}else{
let value = configItem.value
configItem.value = this.replaceData(value)
res.push(configItem)
}
}
//console.log('res',res)
return res
},
getFieldValue(value, orderData) {
if(value == '') return ''
let start = value.indexOf('{')
if (start != -1) {
let end = value.indexOf('}')
let keyStr = value.substring(start + 1, end)
let fieldKey = this.nameField[keyStr]
return value.replace('{'+ keyStr +'}', orderData[fieldKey])
}
return value
},
init(showData) {
let _this = this
let api = '/api/Administrator/OrderFieldStyle/getUserConfig?type=1'
const res = axios.get(api).then((res) => {
let doc = {}
if(res.data.code == 1) {
doc = res.data.data.field_style
_this.doc = doc
}
_this.initDoc(doc)
})
},
initDoc(showData) {
if (Object.keys(showData).length === 0) {
showData = {
header: [],
main: [],
footer: [
{
value: '',
size: 12
}
]
}
}
if (this.updateStatus) {
showData.main = this.fillData(showData.main)
}
if(this.instance != null) {
this.instance.destroy()
}
this.instance = new Editor(
document.querySelector('.editor'),
showData,
{}
)
this.editorLisener()
},
getSelectImage() {
const imageFileDom = document.querySelector('#image')
imageFileDom.click()
},
selectImage(event) {
let _this = this
//console.log(event.target.files[0])
const imageFileDom = document.querySelector('#image')
const file = event.target.files[0]//imageFileDom.files![0]!
const fileReader = new FileReader()
fileReader.readAsDataURL(file)
fileReader.onload = function () {
// 计算宽高
const image = new Image()
const value = fileReader.result
image.src = value
image.onload = function () {
_this.instance.command.executeImage({
value,
width: image.width,
height: image.height
})
imageFileDom.value = ''
}
}
},
executeInsertElementList() {
this.instance.command.executeInsertElementList([
{
type: ElementType.CHECKBOX,
value: ''
}
])
},
executeHyperlink() {
let _this = this
new Dialog({
title: '超链接',
data: [
{
type: 'text',
label: '文本',
name: 'name',
required: true,
placeholder: '请输入文本'
},
{
type: 'text',
label: '链接',
name: 'url',
required: true,
placeholder: '请输入链接'
}
],
onConfirm: payload => {
const name = payload.find(p => p.name === 'name')?.value
if (!name) return
const url = payload.find(p => p.name === 'url')?.value
if (!url) return
this.instance.command.executeHyperlink({
type: ElementType.HYPERLINK,
value: '',
url,
valueList: name.split('').map(n => ({
value: n,
size: 16
}))
})
}
})
},
executePageBreak() {
this.instance.command.executePageBreak()
},
executeBlock() {
let _this = this
new Dialog({
title: '内容块',
data: [
{
type: 'select',
label: '类型',
name: 'type',
value: 'iframe',
required: true,
options: [
{
label: '网址',
value: 'iframe'
},
{
label: '视频',
value: 'video'
}
]
},
{
type: 'number',
label: '宽度',
name: 'width',
placeholder: '请输入宽度(默认页面内宽度)'
},
{
type: 'number',
label: '高度',
name: 'height',
required: true,
placeholder: '请输入高度'
},
{
type: 'textarea',
label: '地址',
height: 100,
name: 'value',
required: true,
placeholder: '请输入地址'
}
],
onConfirm: payload => {
const type = payload.find(p => p.name === 'type')?.value
if (!type) return
const value = payload.find(p => p.name === 'value')?.value
if (!value) return
const width = payload.find(p => p.name === 'width')?.value
const height = payload.find(p => p.name === 'height')?.value
if (!height) return
const block = {
type: type
}
if (block.type === BlockType.IFRAME) {
block.iframeBlock = {
src: value
}
} else if (block.type === BlockType.VIDEO) {
block.videoBlock = {
src: value
}
}
const blockElement = {
type: ElementType.BLOCK,
value: '',
height: Number(height),
block
}
if (width) {
blockElement.width = Number(width)
}
_this.instance.command.executeInsertElementList([blockElement])
}
})
},
executeUndo() {//撤销
this.instance.command.executeUndo()
},
executeRedo() {//重做 反撤销
this.instance.command.executeRedo()
},
painterDom() {//格式刷(双击可连续使用)
this.instance.command.executePainter({
isDblclick: false
})
},
dbPainterDom() {
this.instance.command.executePainter({
isDblclick: true
})
},
executeFormat() {//清除格式
this.instance.command.executeFormat()
},
executeSizeAdd() {//增大字号
this.instance.command.executeSizeAdd()
},
executeSizeMinus() {//减小字号
this.instance.command.executeSizeMinus()
},
executeBold() {//加粗
this.instance.command.executeBold()
},
executeItalic() {//斜体
this.instance.command.executeItalic()
},
executePrint() {
this.instance.command.executePrint()
},
executeUnderline() {//下划线
this.instance.command.executeUnderline()
},
executeUnderline() {
this.instance.command.executeUnderline()
},
executeStrikeout() {
this.instance.command.executeStrikeout()
},
executeSuperscript() {
this.instance.command.executeSuperscript()
},
executeSubscript() {
this.instance.command.executeSubscript()
},
executeTitle(event) {
const li = event.target;
// 获取元素的属性值
const level = li.getAttribute('data-level')
this.instance.command.executeTitle(level || null)
},
rowFlexLeft() {
this.instance.command.executeRowFlex(RowFlex.LEFT)
},
rowFlexCenter() {
this.instance.command.executeRowFlex(RowFlex.CENTER)
},
rowFlexRight() {
this.instance.command.executeRowFlex(RowFlex.RIGHT)
},
rowFlexAlignment() {
this.instance.command.executeRowFlex(RowFlex.ALIGNMENT)
},
executeSetDate(evt) {
const dateDom = document.querySelector('.menu-item__date')
const dateDomOptionDom = dateDom.querySelector('.options')
const li = evt.target
const dateFormat = li.dataset.format
dateDomOptionDom.classList.toggle('visible')
this.instance.command.executeInsertElementList([
{
type: ElementType.DATE,
value: '',
dateFormat,
valueList: [
{
value: li.innerText.trim()
}
]
}
])
},
executeDate(){
const dateDom = document.querySelector('.menu-item__date')
const dateDomOptionDom = dateDom.querySelector('.options')
dateDomOptionDom.classList.toggle('visible')
// 定位调整
const bodyRect = document.body.getBoundingClientRect()
const dateDomOptionRect = dateDomOptionDom.getBoundingClientRect()
if (dateDomOptionRect.left + dateDomOptionRect.width > bodyRect.width) {
dateDomOptionDom.style.right = '0px'
dateDomOptionDom.style.left = 'unset'
} else {
dateDomOptionDom.style.right = 'unset'
dateDomOptionDom.style.left = '0px'
}
// 当前日期
const date = new Date()
const year = date.getFullYear().toString()
const month = (date.getMonth() + 1).toString().padStart(2, '0')
const day = date.getDate().toString().padStart(2, '0')
const hour = date.getHours().toString().padStart(2, '0')
const minute = date.getMinutes().toString().padStart(2, '0')
const second = date.getSeconds().toString().padStart(2, '0')
const dateString = `${year}-${month}-${day}`
const dateTimeString = `${dateString} ${hour}:${minute}:${second}`
dateDomOptionDom.querySelector('li:first-child').innerText =dateString
dateDomOptionDom.querySelector('li:last-child').innerText =dateTimeString
},
separatorDom() {
const separatorDom = document.querySelector('.menu-item__separator')
const separatorOptionDom = separatorDom.querySelector('.options')
separatorOptionDom.classList.toggle('visible')
},
insertSeparator(evt) {
let payload = []
const li = evt.target
const separatorDash = li.dataset.separator?.split(',').map(Number)
if (separatorDash) {
const isSingleLine = separatorDash.every(d => d === 0)
if (!isSingleLine) {
payload = separatorDash
}
}
this.instance.command.executeSeparator(payload)
},
selectColor () {
const colorControlDom = document.querySelector('#color')
const colorDom = document.querySelector('.menu-item__color')
colorControlDom.click()
let _this = this
colorControlDom.oninput = function () {
_this.instance.command.executeColor(colorControlDom.value)
}
},
highlight () {
const highlightControlDom = document.querySelector('#highlight')
const highlightDom = document.querySelector('.menu-item__highlight')
highlightControlDom?.click()
let _this = this
highlightControlDom.oninput = function () {
_this.instance.command.executeHighlight(highlightControlDom.value)
}
//const highlightSpanDom = highlightDom.querySelector('span')
},
rowMargin() {
const rowMarginDom = document.querySelector('.menu-item__row-margin')
const rowOptionDom = rowMarginDom.querySelector('.options')
rowOptionDom.classList.toggle('visible')
},
setRowMargin(evt) {
const li = evt.target
const rowMargin = li.dataset.rowmargin
this.instance.command.executeRowMargin(Number(rowMargin))
},
menuList() {
const listDom = document.querySelector('.menu-item__list')
listDom.title = `列表(Ctrl+Shift+U)`
const listOptionDom = listDom.querySelector('.options')
listOptionDom.classList.toggle('visible')
},
setMenuList(evt){
const li = evt.target
const listType = li.dataset.listType || null
const listStyle = (li.dataset.listStyle)
this.instance.command.executeList(listType, listStyle)
},
waterMark () {
const watermarkDom = document.querySelector('.menu-item__watermark')
const watermarkOptionDom = watermarkDom.querySelector('.options')
watermarkOptionDom.classList.toggle('visible')
},
setWaterMark(evt) {
const watermarkDom = document.querySelector('.menu-item__watermark')
const watermarkOptionDom = watermarkDom.querySelector('.options')
const li = evt.target
const menu = li.dataset.menu
watermarkOptionDom.classList.toggle('visible')
let _this = this
if (menu === 'add') {
new Dialog({
title: '水印',
data: [
{
type: 'text',
label: '内容',
name: 'data',
required: true,
placeholder: '请输入内容'
},
{
type: 'color',
label: '颜色',
name: 'color',
required: true,
value: '#AEB5C0'
},
{
type: 'number',
label: '字体大小',
name: 'size',
required: true,
value: '120'
}
],
onConfirm: payload => {
const nullableIndex = payload.findIndex(p => !p.value)
if (~nullableIndex) return
const watermark = payload.reduce((pre, cur) => {
pre[cur.name] = cur.value
return pre
},{})
_this.instance.command.executeAddWatermark({
data: watermark.data,
color: watermark.color,
size: Number(watermark.size)
})
}
})
} else {
this.instance.command.executeDeleteWatermark()
}
},
editorLisener(){
this.instance.listener.rangeStyleChange = function (payload) {
//console.log(payload)
const colorControlDom = document.querySelector('#color')
const colorDom = document.querySelector('.menu-item__color')
const colorSpanDom = colorDom.querySelector('span')
if (payload.color) {
colorDom.classList.add('active')
colorControlDom.value = payload.color
colorSpanDom.style.backgroundColor = payload.color
} else {
colorDom.classList.remove('active')
colorControlDom.value = '#000000'
colorSpanDom.style.backgroundColor = '#000000'
}
}
},
clickHandle2() {
const fontDom = document.querySelector('.menu-item__font')
const fontOptionDom = fontDom.querySelector('.options')
fontOptionDom.classList.toggle('visible')
},
clickHandle3(evt) {
if (evt.target && evt.target.matches('li')) {
// 获取data-family属性注意在JavaScript中不需要使用!来断言非空)
const family = evt.target.dataset.family
if (family) {
// 确保family存在
// 假设instance和它的command属性以及executeFont方法都已经被正确定义和初始化
this.instance.command.executeFont(family)
}
}
},
clickHandle4() {
const sizeSetDom = document.querySelector('.menu-item__size')
const sizeOptionDom = sizeSetDom.querySelector('.options')
sizeOptionDom.classList.toggle('visible')
},
clickHandle5(evt) {
const li = evt.target
this.instance.command.executeSize(li.dataset.size)
},
clickHandle7() {
const tablePanel = document.querySelector('.table-panel')
// 绘制行列
console.log('clickHandle7 方法被调用了!')
for (let i = 0; i < 10; i++) {
const tr = document.createElement('tr')
tr.classList.add('table-row')
const trCellList = []
for (let j = 0; j < 10; j++) {
const td = document.createElement('td')
td.classList.add('table-cel')
tr.append(td)
trCellList.push(td)
}
tablePanel.append(tr)
this.tableCellList.push(trCellList)
this.colIndex = 0
this.rowIndex = 0
}
// 显示表格
const elements = document.querySelectorAll('.table-cel')
elements.forEach(element => {
element.style.width = '16px'
element.style.height = '16px'
//element.style.border = '1px solid #000'
})
const tablePanelContainer = document.querySelector('.menu-item__table__collapse')
tablePanelContainer.style.display = 'block'
},
// 移除所有格选择
removeAllTableCellSelect() {
this.tableCellList.forEach(tr => {
tr.forEach(td => td.classList.remove('active'))
})
},
// 设置标题内容
setTableTitle(payload) {
const tableTitle = document.querySelector('.table-select')
tableTitle.innerText = payload
},
// 恢复初始状态
recoveryTable() {
const tablePanelContainer = document.querySelector('.menu-item__table__collapse')
// 还原选择样式、标题、选择行列
this.removeAllTableCellSelect()
this.setTableTitle('插入')
this.colIndex = 0
this.rowIndex = 0
// 隐藏panel
tablePanelContainer.style.display = 'none'
},
ceshi(evt) {
const celSize = 16
const rowMarginTop = 10
const celMarginRight = 6
const { offsetX, offsetY } = evt
// 移除所有选择
this.removeAllTableCellSelect()
this.colIndex = Math.ceil(offsetX / (celSize + celMarginRight)) || 1
this.rowIndex = Math.ceil(offsetY / (celSize + rowMarginTop)) || 1
// 改变选择样式
this.tableCellList.forEach((tr, trIndex) => {
tr.forEach((td, tdIndex) => {
if (tdIndex < this.colIndex && trIndex < this.rowIndex) {
td.classList.add('active')
}
})
})
// 改变表格标题
this.setTableTitle(`${this.rowIndex}×${this.colIndex}`)
},
tableClose() {
this.recoveryTable()
},
tablePanel() {
// 应用选择
this.instance.command.executeInsertTable(this.rowIndex, this.colIndex)
this.recoveryTable()
},
}
}
</script>
<style scoped>
@import url('./components/dialog/dialog.css');
@import url('./components/signature/signature.css');
</style>