1879 lines
56 KiB
Vue
1879 lines
56 KiB
Vue
<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 size="small" @click="getHTMLValuea">保存配置</el-button>
|
||
<el-button size="small" @click="savePdf">保存pdf并上传</el-button>
|
||
<el-button size="small" @click="confShow = !confShow">显示/隐藏</el-button>
|
||
<el-button size="small" @click="getShow">预览/配置</el-button>
|
||
<!-- <el-button size="small" @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="格式刷(双击可连续使用)" @click="painterDom" @dblclick="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="图片">{{ count }}</i>
|
||
<input @change.stop="selectImage" type="file" id="image" accept=".png, .jpg, .jpeg, .svg, .gif">
|
||
</div>
|
||
<!-- <div class="menu-item__code" @click="getSelectQrCode">
|
||
<i title="二维码"></i>
|
||
<input @change="selectQrCode" type="file" id="qrCode" 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 id="editor" 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" @click="pageModeDomShow">
|
||
<i title="页面模式(分页、连页)"></i>
|
||
<div class="options">
|
||
<ul>
|
||
<li data-page-mode="paging" class="active" @click="executePageMode">分页</li>
|
||
<li data-page-mode="continuity" @click="executePageMode">连页</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="编辑模式(编辑、清洁、只读、表单)" @click="executeMode">编辑模式</div>
|
||
<div>
|
||
<div class="page-scale-minus" title="缩小(Ctrl+-)" @click="executePageScaleMinus">
|
||
<i></i>
|
||
</div>
|
||
<span class="page-scale-percentage" title="显示比例(点击可复原Ctrl+0)"
|
||
@click="executePageScaleRecovery">100%</span>
|
||
<div class="page-scale-add" title="放大(Ctrl+=)" @click="executePageScaleAdd">
|
||
<i></i>
|
||
</div>
|
||
<div class="paper-size" @click="paperSizeDomOptionsShow">
|
||
<i title="纸张类型"></i>
|
||
<div class="options">
|
||
<ul>
|
||
<li data-paper-size="794*1123" class="active" @click="executePaperSize">A4</li>
|
||
<li data-paper-size="1593*2251" @click="executePaperSize">A2</li>
|
||
<li data-paper-size="1125*1593" @click="executePaperSize">A3</li>
|
||
<li data-paper-size="565*796" @click="executePaperSize">A5</li>
|
||
<li data-paper-size="412*488" @click="executePaperSize">5号信封</li>
|
||
<li data-paper-size="450*866" @click="executePaperSize">6号信封</li>
|
||
<li data-paper-size="609*862" @click="executePaperSize">7号信封</li>
|
||
<li data-paper-size="862*1221" @click="executePaperSize">9号信封</li>
|
||
<li data-paper-size="813*1266" @click="executePaperSize">法律用纸</li>
|
||
<li data-paper-size="813*1054" @click="executePaperSize">信纸</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
<div class="paper-direction" @click="paperDirectionDomOptionsDomShow">
|
||
<i title="纸张方向"></i>
|
||
<div class="options">
|
||
<ul>
|
||
<li data-paper-direction="vertical" class="active" @click="executePaperDirection">纵向
|
||
</li>
|
||
<li data-paper-direction="horizontal" @click="executePaperDirection">横向</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
<div class="paper-margin" title="页边距" @click="executeSetPaperMargin">
|
||
<i></i>
|
||
</div>
|
||
<div class="fullscreen" title="全屏显示" @click="fullscreen">
|
||
<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 ref="myDiv" id="imgCode" style="display:none"></div>
|
||
|
||
<div v-if="confShow" class="main_search_left">
|
||
<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 './editor'//'@hufe921/canvas-editor'
|
||
import axios from 'axios'
|
||
import { ElMessage } from 'element-plus'
|
||
import { Dialog } from './components/dialog/Dialog'
|
||
import jsPDF from 'jspdf'
|
||
import { debounce, nextTick, scrollIntoView } from './utils'
|
||
import { BrowserQRCodeReader, BrowserQRCodeSvgWriter } from '@zxing/browser'
|
||
import { EncodeHintType } from '@zxing/library'
|
||
import JsBarcode from 'jsbarcode'
|
||
export default {
|
||
data() {
|
||
return {
|
||
count: '',
|
||
fieldArr: [],
|
||
confShow: false,
|
||
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,
|
||
orderType: 0,
|
||
modeIndex: 0,
|
||
imageType: '',
|
||
id: 0,
|
||
code: '',
|
||
flag: false,
|
||
options: {
|
||
margins: [100, 120, 100, 120],
|
||
watermark: {
|
||
data: 'rrrtr',
|
||
size: 120
|
||
},
|
||
pageNumber: {
|
||
format: '第{pageNo}页/共{pageCount}页'
|
||
},
|
||
placeholder: {
|
||
data: '请输入正文'
|
||
},
|
||
maskMargin: [60, 0, 30, 0] // 菜单栏高度60,底部工具栏30为遮盖层
|
||
}
|
||
}
|
||
},
|
||
mounted() {
|
||
this.login()
|
||
this.createBarCode()
|
||
},
|
||
methods: {
|
||
savePdf() {
|
||
const element = document.querySelector('.editor').getElementsByTagName('canvas')//document.getElementsByTagName('canvas')
|
||
this.htmlToPDF(element[0], 'a11a')
|
||
},
|
||
htmlToPDF(canvas, pdfName) {
|
||
const pdf = new jsPDF('p', 'mm', 'a4')
|
||
// 将Canvas转换为图片 landscape
|
||
const imgData = canvas.toDataURL('image/png')
|
||
// 计算图片尺寸以适应PDF
|
||
const imgProps = pdf.getImageProperties(imgData)
|
||
const pdfWidth = pdf.internal.pageSize.getWidth()
|
||
const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width
|
||
const imgWidth = pdfWidth
|
||
const imgHeight = pdfHeight
|
||
// 将图片添加到PDF中
|
||
const x = 0;
|
||
const y = 0;
|
||
const options = {
|
||
width: imgWidth,
|
||
height: imgHeight,
|
||
}
|
||
pdf.addImage(imgData, 'PNG', x, y, options.width, options.height)
|
||
// 保存生成的PDF
|
||
const blob = pdf.output("blob")
|
||
this.uploadFile(blob)
|
||
pdf.save(pdfName + '.pdf')
|
||
},
|
||
uploadFile(blob) {
|
||
const formData = new FormData()
|
||
//formData.append('file', blob, 'myPDF.pdf')
|
||
let api = '/api/Administrator/file/upload'
|
||
formData.append('files', blob, 'myPDF.pdf');
|
||
|
||
// 使用fetch API上传文件到服务器
|
||
fetch(api, {
|
||
method: 'POST',
|
||
body: formData
|
||
})
|
||
.then(response => response.json())
|
||
.then(data => {
|
||
ElMessage({
|
||
message: data.msg,
|
||
type: data.code == 1 ? 'success' : 'error',
|
||
plain: true,
|
||
})
|
||
})
|
||
.catch(error => console.error(error))
|
||
},
|
||
createBarCode() {//条形码
|
||
const svgElement = document.createElement('svg')
|
||
// 解析一维码
|
||
let content = '1234567788'
|
||
let options = {
|
||
'lineColor': 'red'
|
||
}//JsBarcode.Options
|
||
console.log(options)
|
||
//options['lineColor'] = 'red'
|
||
JsBarcode(svgElement, content, options)
|
||
let base64Image = this.convertSvgElementToBase64(svgElement)
|
||
console.log('条形码: ', base64Image)
|
||
|
||
},
|
||
handleGeneratebak(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, // 二维码高度
|
||
});
|
||
}
|
||
},
|
||
handleGenerate(orderId = '') {
|
||
const codeWriter = new BrowserQRCodeSvgWriter()
|
||
const content = 'https://www.baihand.com?order_id=' + orderId
|
||
//MARGIN
|
||
let hints = new Map()
|
||
hints.set(EncodeHintType.MARGIN, 0)
|
||
const svgElement = codeWriter.write(content, 200, 200, hints)
|
||
svgElement.setAttribute('xmlns', 'http://www.w3.org/2000/svg')
|
||
return this.convertSvgElementToBase64(svgElement)
|
||
},
|
||
convertSvgElementToBase64(svgElement) {
|
||
return `data:image/svg+xml;base64,${btoa(
|
||
decodeURIComponent(svgElement.outerHTML)
|
||
)}`
|
||
},
|
||
copy(value) {
|
||
if (navigator.clipboard && window.isSecureContext) {
|
||
navigator.clipboard.writeText(value).then(function () {
|
||
console.log('复制成功');
|
||
}).catch(function (error) {
|
||
console.error('复制失败', error);
|
||
})
|
||
} else {
|
||
const textArea = document.createElement('textarea');
|
||
textArea.value = value;
|
||
document.body.appendChild(textArea);
|
||
textArea.select();
|
||
document.execCommand('copy');
|
||
textArea.remove();
|
||
}
|
||
},
|
||
getShow() {
|
||
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'] }
|
||
this.getGongXu(item, k)
|
||
}
|
||
|
||
this.searchList = data.data.searchExt
|
||
let order_id = data.data.searchExt['order_id']
|
||
this.orderType = data.data.searchExt['order_type_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
|
||
}
|
||
|
||
this.init()
|
||
}))
|
||
},
|
||
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 editorOption = this.instance.command.getOptions()
|
||
console.log(editorOption)
|
||
const html = this.instance.command.getHTML()
|
||
//let str = html.main
|
||
//console.log(html)
|
||
//str = str.replace(/"/g, "'")
|
||
//console.log(str)
|
||
const ccc = this.instance.command.getValue()
|
||
console.log(ccc.data)
|
||
const aaa = this.instance.command.getText()
|
||
if (aaa.main.indexOf('{') == -1) {
|
||
ElMessage({
|
||
message: '预览模式不可保存设置',
|
||
type: 'error',
|
||
plain: true,
|
||
})
|
||
return false
|
||
}
|
||
|
||
//localStorage.setItem('word_data', JSON.stringify(ccc.data))
|
||
return false
|
||
let saveData = { 'id': this.id, 'type': this.orderType, 'field_style': ccc.data }
|
||
let api = '/api/Administrator/OrderFieldStyle/save'
|
||
axios.post(api, saveData).then((res) => {
|
||
ElMessage({
|
||
message: res.data.msg,
|
||
type: res.data.code == 1 ? 'success' : 'error',
|
||
plain: true,
|
||
})
|
||
})
|
||
|
||
//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
|
||
},
|
||
getFieldValues(field) {
|
||
let value = ''
|
||
for (let i = 0; i < this.orderData.length; i++) {
|
||
const element = this.orderData[i]
|
||
if (value == '') {
|
||
value = element[field]
|
||
} else {
|
||
value += ',' + element[field]
|
||
}
|
||
}
|
||
return value
|
||
},
|
||
replaceData(value) {
|
||
///console.log('value', value)
|
||
let start = value.indexOf('{')
|
||
if (start == -1) {
|
||
return value
|
||
}
|
||
let end = value.indexOf('}')
|
||
if(end == -1) return value
|
||
let fieldKey = value.substring(start + 1, end)
|
||
let field = this.searchNameField[fieldKey]
|
||
let newValue = ''
|
||
if (field == undefined) {
|
||
field = this.nameField[fieldKey]
|
||
newValue = this.getFieldValues(field)
|
||
} else {
|
||
newValue = this.searchList[field]
|
||
}
|
||
value = value.replace('{' + fieldKey + '}', newValue)
|
||
return this.replaceData(value)
|
||
},
|
||
chkTdList(tdList) {
|
||
for (let i = 0; i < tdList.length; i++) {
|
||
const element = tdList[i];
|
||
if (element.value.length == 0) {
|
||
continue
|
||
}
|
||
let value = element.value[0].value
|
||
if (value.indexOf("{") != -1) {
|
||
return true //需要循环数据
|
||
}
|
||
}
|
||
return false //不需要循环数据
|
||
},
|
||
handlerMergeTable(list, order) {
|
||
let trList = JSON.parse(JSON.stringify(list))
|
||
for (let i = 0; i < trList.tdList.length; i++) {
|
||
let tdListItem = trList.tdList[i];
|
||
if (tdListItem.value.length == 0) {
|
||
continue
|
||
}
|
||
for (let j = 0; j < tdListItem.value.length; j++) {
|
||
let tdValue = tdListItem.value[j].value
|
||
tdListItem.value[j].value = this.getFieldValue(tdValue, order)
|
||
}
|
||
}
|
||
return trList
|
||
},
|
||
fillData(data) {
|
||
let config = JSON.parse(data)
|
||
let res = []
|
||
//let code = this.getImage('imgCode')
|
||
for (let i = 0; i < config.length; i++) {
|
||
let configItem = JSON.stringify(config[i])//
|
||
configItem = JSON.parse(configItem)
|
||
if (configItem.hasOwnProperty('type') && configItem['type'] == 'table') {
|
||
let trList = JSON.stringify(configItem.trList)
|
||
trList = JSON.parse(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 = JSON.stringify(trList[j])//
|
||
trListItem = JSON.parse(trListItem)
|
||
let tdList = JSON.stringify(trListItem.tdList)
|
||
tdList = JSON.parse(tdList)
|
||
let chkRes = this.chkTdList(tdList)
|
||
if (chkRes == false) {
|
||
temTrList.trList.push(trListItem)
|
||
continue
|
||
}
|
||
trListItem.tdList = []
|
||
for (let k = 0; k < this.orderData.length; k++) {
|
||
let tempTdList = []
|
||
let order = this.orderData[k]
|
||
let hasMergeTable = false
|
||
for (let l = 0; l < tdList.length; l++) {
|
||
let tdListItem = JSON.stringify(tdList[l])
|
||
tdListItem = JSON.parse(tdListItem)
|
||
if (tdListItem.rowspan > 1) {//处理合并的单元格行
|
||
hasMergeTable = true
|
||
let tempTrList = trList.slice(j, j + tdListItem.rowspan)
|
||
for (let g = 0; g < tempTrList.length; g++) {
|
||
const element = tempTrList[g]
|
||
let packeTrItem = this.handlerMergeTable(element, order)
|
||
temTrList.trList.push(packeTrItem)
|
||
}
|
||
if (k + 1 == this.orderData.length) {//当前合并单元格行数处理完k索引加单元格行数-1 本身循环有++操作
|
||
j += tdListItem.rowspan - 1
|
||
}
|
||
break
|
||
}
|
||
let item = {
|
||
'colspan': tdListItem.colspan,
|
||
'rowspan': tdListItem.rowspan,
|
||
'value': []
|
||
}
|
||
if (tdListItem.slashTypes != undefined) {
|
||
item.slashTypes = tdListItem.slashTypes
|
||
}
|
||
if (tdListItem.value.length == 0) {
|
||
tempTdList.push(item)
|
||
continue
|
||
}
|
||
|
||
let tempItem = this.handlerTdListItem(tdListItem, order)
|
||
/* let tdValue = tdListItem.value[0].value
|
||
let newValue = this.getFieldValue(tdValue, order)
|
||
let tempItem = { 'value': newValue, 'size': tdListItem.value[0].size }
|
||
console.log(tempItem) */
|
||
//item.value.push(tempItem)
|
||
item['value'] = tempItem['value']
|
||
tempTdList.push(item)
|
||
}
|
||
if (hasMergeTable == false) {//不是合并单元格
|
||
let tempTr = {
|
||
'height': trListItem.height,
|
||
'tdList': [],
|
||
'minHeight': trListItem.minHeight ? trListItem.minHeight : trListItem.height
|
||
}
|
||
tempTr.tdList = tempTdList
|
||
temTrList.trList.push(tempTr)
|
||
}
|
||
}
|
||
}
|
||
res.push(temTrList)
|
||
} else if (configItem.hasOwnProperty('type') && configItem['type'] == 'image') {
|
||
//console.log(configItem)
|
||
if (configItem.hasOwnProperty('field') && configItem['field'] == 'code') {
|
||
|
||
configItem.value = this.handleGenerate()
|
||
}
|
||
res.push(configItem)
|
||
|
||
} else {
|
||
let value = configItem.value
|
||
configItem.value = this.replaceData(value)
|
||
res.push(configItem)
|
||
}
|
||
}
|
||
//.log('config', config)
|
||
//console.log('res',res)
|
||
return res
|
||
},
|
||
handlerTdListItem(tdItem, order) {
|
||
let list = JSON.stringify(tdItem)
|
||
list = JSON.parse(list)
|
||
for (let i = 0; i < list['value'].length; i++) {
|
||
let item = list['value'][i];
|
||
let tdValue = item['value']
|
||
let newValue = this.getFieldValue(tdValue, order)
|
||
item['value'] = newValue
|
||
}
|
||
return list
|
||
},
|
||
getFieldValue(value, orderData) {
|
||
if (value == '') return ''
|
||
let start = value.indexOf('{')
|
||
if (start != -1) {
|
||
let end = value.indexOf('}')
|
||
if(end == -1) return value
|
||
let keyStr = value.substring(start + 1, end)
|
||
let fieldKey = this.nameField[keyStr]
|
||
value = value.replace('{' + keyStr + '}', orderData[fieldKey])
|
||
return this.getFieldValue(value, orderData)
|
||
}
|
||
return value
|
||
},
|
||
|
||
init() {
|
||
if (Object.keys(this.doc).length > 0) {
|
||
let tempDoc = JSON.stringify(this.doc)
|
||
tempDoc = JSON.parse(tempDoc)
|
||
this.initDoc(tempDoc)
|
||
return false
|
||
}
|
||
let _this = this
|
||
let api = '/api/Administrator/OrderFieldStyle/getUserConfig?type=' + this.orderType
|
||
axios.get(api).then((res) => {
|
||
res = JSON.parse(JSON.stringify(res))
|
||
let doc = {}
|
||
if (res.data.code == 1) {
|
||
doc = res.data.data.field_style
|
||
let tempDoc = JSON.stringify(doc)
|
||
|
||
///console.log(doc)
|
||
|
||
tempDoc = JSON.parse(tempDoc)
|
||
_this.doc = tempDoc
|
||
_this.id = res.data.data.id
|
||
}
|
||
_this.initDoc(doc)
|
||
})
|
||
|
||
},
|
||
initDoc(showData) {
|
||
//showData = localStorage.getItem('word_data')
|
||
//showData = JSON.parse(showData)
|
||
console.log(showData)
|
||
if (Object.keys(showData).length === 0) {
|
||
showData = {
|
||
header: [],
|
||
main: [],
|
||
footer: [
|
||
{
|
||
value: '',
|
||
size: 12
|
||
}
|
||
]
|
||
}
|
||
}
|
||
if (this.updateStatus) {
|
||
let data = JSON.stringify(showData.main)
|
||
showData.main = this.fillData(data)
|
||
}
|
||
if (this.instance != null) {
|
||
this.instance.destroy()
|
||
}
|
||
|
||
this.instance = new Editor(
|
||
document.querySelector('.editor'),
|
||
showData,
|
||
this.options
|
||
)
|
||
//this.use(barcode2DPlugin, {})
|
||
this.updateStatus = !this.updateStatus
|
||
this.handleContentChange()
|
||
this.editorLisener()
|
||
},
|
||
|
||
getSelectImage() {
|
||
//const imageFileDom = document.querySelector('#image')
|
||
//imageFileDom.click()
|
||
if (this.flag == true) return
|
||
let _this = this
|
||
new Dialog({
|
||
title: '图片类型',
|
||
data: [
|
||
{
|
||
type: 'select',
|
||
label: '类型',
|
||
name: 'type',
|
||
value: 'image',
|
||
required: true,
|
||
options: [
|
||
{
|
||
label: '静态图片',
|
||
value: 'image'
|
||
},
|
||
{
|
||
label: '二维码',
|
||
value: 'code'
|
||
},
|
||
{
|
||
label: '实时渲染图片',
|
||
value: 'dynamics'
|
||
}
|
||
]
|
||
}
|
||
],
|
||
onConfirm: payload => {
|
||
_this.flag = true
|
||
const type = payload.find(p => p.name === 'type')?.value
|
||
_this.imageType = type
|
||
_this.gageImage()
|
||
}
|
||
})
|
||
|
||
},
|
||
gageImage() {
|
||
const imageFileDom = document.querySelector('#image')
|
||
imageFileDom.click()
|
||
},
|
||
|
||
selectImage(event) {
|
||
event.stopPropagation()
|
||
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,
|
||
field: _this.imageType
|
||
})
|
||
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
|
||
|
||
},
|
||
executePageScaleMinus() {
|
||
this.instance.command.executePageScaleMinus()
|
||
},
|
||
executePageScaleAdd() {
|
||
this.instance.command.executePageScaleAdd()
|
||
},
|
||
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()
|
||
}
|
||
|
||
},
|
||
executePageScaleRecovery() {
|
||
this.instance.command.executePageScaleRecovery()
|
||
},
|
||
paperSizeDomOptionsShow() {
|
||
const paperSizeDom = document.querySelector('.paper-size')
|
||
const paperSizeDomOptionsDom = paperSizeDom.querySelector('.options')
|
||
paperSizeDomOptionsDom.classList.toggle('visible')
|
||
},
|
||
executePaperSize(evt) {
|
||
const paperSizeDom = document.querySelector('.paper-size')
|
||
const paperSizeDomOptionsDom = paperSizeDom.querySelector('.options')
|
||
const li = evt.target
|
||
const paperType = li.dataset.paperSize
|
||
const [width, height] = paperType.split('*').map(Number)
|
||
this.instance.command.executePaperSize(width, height)
|
||
// 纸张状态回显
|
||
paperSizeDomOptionsDom.querySelectorAll('li')
|
||
.forEach(child => child.classList.remove('active'))
|
||
li.classList.add('active')
|
||
},
|
||
paperDirectionDomOptionsDomShow() {
|
||
const paperDirectionDom = document.querySelector('.paper-direction')
|
||
const paperDirectionDomOptionsDom = paperDirectionDom.querySelector('.options')
|
||
paperDirectionDomOptionsDom.classList.toggle('visible')
|
||
},
|
||
executePaperDirection(evt) {
|
||
const paperDirectionDom = document.querySelector('.paper-direction')
|
||
const paperDirectionDomOptionsDom = paperDirectionDom.querySelector('.options')
|
||
const li = evt.target
|
||
const paperDirection = li.dataset.paperDirection
|
||
this.instance.command.executePaperDirection(paperDirection)
|
||
// 纸张方向状态回显
|
||
paperDirectionDomOptionsDom
|
||
.querySelectorAll('li')
|
||
.forEach(child => child.classList.remove('active'))
|
||
li.classList.add('active')
|
||
},
|
||
executeSetPaperMargin() {
|
||
const [topMargin, rightMargin, bottomMargin, leftMargin] = this.instance.command.getPaperMargin()
|
||
let _this = this
|
||
new Dialog({
|
||
title: '页边距',
|
||
data: [
|
||
{
|
||
type: 'text',
|
||
label: '上边距',
|
||
name: 'top',
|
||
required: true,
|
||
value: `${topMargin}`,
|
||
placeholder: '请输入上边距'
|
||
},
|
||
{
|
||
type: 'text',
|
||
label: '下边距',
|
||
name: 'bottom',
|
||
required: true,
|
||
value: `${bottomMargin}`,
|
||
placeholder: '请输入下边距'
|
||
},
|
||
{
|
||
type: 'text',
|
||
label: '左边距',
|
||
name: 'left',
|
||
required: true,
|
||
value: `${leftMargin}`,
|
||
placeholder: '请输入左边距'
|
||
},
|
||
{
|
||
type: 'text',
|
||
label: '右边距',
|
||
name: 'right',
|
||
required: true,
|
||
value: `${rightMargin}`,
|
||
placeholder: '请输入右边距'
|
||
}
|
||
],
|
||
onConfirm: payload => {
|
||
const top = payload.find(p => p.name === 'top')?.value
|
||
if (!top) return
|
||
const bottom = payload.find(p => p.name === 'bottom')?.value
|
||
if (!bottom) return
|
||
const left = payload.find(p => p.name === 'left')?.value
|
||
if (!left) return
|
||
const right = payload.find(p => p.name === 'right')?.value
|
||
if (!right) return
|
||
_this.instance.command.executeSetPaperMargin([
|
||
Number(top),
|
||
Number(right),
|
||
Number(bottom),
|
||
Number(left)
|
||
])
|
||
}
|
||
})
|
||
|
||
},
|
||
fullscreen() {
|
||
this.toggleFullscreen()
|
||
},
|
||
toggleFullscreen() {
|
||
const fullscreenDom = document.querySelector('.fullscreen')
|
||
fullscreenDom.classList.toggle('exist')
|
||
if (!document.fullscreenElement) {
|
||
document.documentElement.requestFullscreen()
|
||
} else {
|
||
document.exitFullscreen()
|
||
}
|
||
},
|
||
executeMode() {
|
||
const modeList = [
|
||
{
|
||
mode: EditorMode.EDIT,
|
||
name: '编辑模式'
|
||
},
|
||
{
|
||
mode: EditorMode.CLEAN,
|
||
name: '清洁模式'
|
||
},
|
||
{
|
||
mode: EditorMode.READONLY,
|
||
name: '只读模式'
|
||
},
|
||
{
|
||
mode: EditorMode.FORM,
|
||
name: '表单模式'
|
||
},
|
||
{
|
||
mode: EditorMode.PRINT,
|
||
name: '打印模式'
|
||
}
|
||
]
|
||
this.modeIndex === modeList.length - 1 ? (this.modeIndex = 0) : this.modeIndex++
|
||
// 设置模式
|
||
const { name, mode } = modeList[this.modeIndex]
|
||
const modeElement = document.querySelector('.editor-mode')
|
||
modeElement.innerText = name
|
||
this.instance.command.executeMode(mode)
|
||
// 设置菜单栏权限视觉反馈
|
||
const isReadonly = mode === EditorMode.READONLY
|
||
const enableMenuList = ['search', 'print']
|
||
document.querySelectorAll('.menu-item>div').forEach(dom => {
|
||
const menu = dom.dataset.menu
|
||
isReadonly && (!menu || !enableMenuList.includes(menu))
|
||
? dom.classList.add('disable')
|
||
: dom.classList.remove('disable')
|
||
})
|
||
},
|
||
async handleContentChange() {
|
||
const wordCount = await this.instance.command.getWordCount()
|
||
document.querySelector('.word-count').innerText = `${wordCount || 0
|
||
}`
|
||
// 目录
|
||
/* if (isCatalogShow) {
|
||
nextTick(() => {
|
||
updateCatalog()
|
||
})
|
||
}
|
||
// 批注
|
||
nextTick(() => {
|
||
updateComment()
|
||
}) */
|
||
},
|
||
pageModeDomShow() {
|
||
const pageModeDom = document.querySelector('.page-mode')
|
||
const pageModeOptionsDom = pageModeDom.querySelector('.options')
|
||
pageModeOptionsDom.classList.toggle('visible')
|
||
},
|
||
executePageMode(evt) {
|
||
const li = evt.target
|
||
this.instance.command.executePageMode(li.dataset.pageMode)
|
||
},
|
||
editorLisener() {
|
||
this.instance.listener.visiblePageNoListChange = function (payload) {
|
||
const text = payload.map(i => i + 1).join('、')
|
||
document.querySelector('.page-no-list').innerText = text
|
||
}
|
||
this.instance.listener.intersectionPageNoChange = function (payload) {
|
||
document.querySelector('.page-no').innerText = `${payload + 1}`
|
||
}
|
||
this.instance.listener.pageSizeChange = function (payload) {
|
||
document.querySelector('.page-size').innerText = `${payload}`
|
||
}
|
||
this.instance.listener.contentChange = debounce(this.handleContentChange, 200)
|
||
|
||
this.instance.listener.pageScaleChange = function (payload) {
|
||
document.querySelector('.page-scale-percentage').innerText = `${Math.floor(payload * 10 * 10)}%`
|
||
}
|
||
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'
|
||
}
|
||
const painterDom = document.querySelector('.menu-item__painter')
|
||
payload.painter
|
||
? painterDom.classList.add('active')
|
||
: painterDom.classList.remove('active')
|
||
}
|
||
},
|
||
|
||
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>
|