拖拽盖章处理
进行元素拖拽:同类章替换、删除已盖章
1.复制对应元素,在onmousemove中left和top一直在变化
2.onmouseup时,计算出在pdf显示区域内的left,top,removeChild删除原先复制的元素,再appendChild到pdf显示区域的父元素中。再次移动onmousedown绑定对应事件
效果图
主要代码文件如下,重点在于_signPic内的坐标获取处理
<template>
<div
class="app-container"
v-loading.fullscreen="listLoading"
element-loading-text="加载中"
>
<el-header class="headerBox flex">
<div class="doc-title-list">
<div class="active-doc">{{ activeDoc.signDocumentTitle }}</div>
</div>
<!-- 发起签署 -->
<div class="sign-btn">
<el-button size="small" type="primary" @click="submitSign"
>确认签署</el-button
>
</div>
</el-header>
<!-- 主题内容 -->
<div class="cont">
<!-- 中间区域 -->
<div id="pageContent" class="viewerContainer">
<!-- 左边区域 -->
<div class="left-area-container">
<!-- 坐标签未预设位置,需要拖拽盖章 -->
<DragSeal
v-if="signType == 1"
:sealList="sealList"
@drag="_signPic"
/>
<!-- 关键字签0&&坐标签已预设位置2,无需拖拽盖章,只需选择印章 -->
<KeySeal v-else :sealList="sealList" @select="_select" />
</div>
<div class="pdfContent_1PW2f">
<div class="pdf-header">
<div class="block">
<span class="demonstration">{{ scale * 100 }}%</span>
<div class="slider">
<!-- @change="handleChange" -->
<el-slider
v-model="scale"
:min="0.5"
:max="2"
:step="0.25"
disabled
></el-slider>
</div>
</div>
<div class="input">
<span
>Page:
<input
type="text"
class="input-text"
v-model="page_num"
placeholder="1"
/>
/ {{ page_count }}</span
>
<el-button @click="jump" type="text">跳转</el-button>
</div>
</div>
<div
class="pdf-container"
ref="pdfBox"
v-loading="!isShow"
element-loading-text="拼命加载中"
element-loading-spinner="el-icon-loading"
element-loading-background="rgba(0, 0, 0, 0.1)"
>
<div
class="pdf-box"
:style="{
width: maxPdfWidth + 'px',
left: '',
}"
>
<div
v-for="page in page_count"
:key="page"
class="pdfPage_1yRne"
:style="{
width: pdfInfo[page].pdfWidth + 'px',
height: pdfInfo[page].pdfHeight + 'px',
}"
>
<canvas class="pdf-item" :id="'the-canvas' + page"></canvas>
<div class="dragLayer_3ccsq" :id="'can' + page"></div>
</div>
</div>
</div>
</div>
</div>
<!-- 右边区域 -->
<div class="right-area-container">
<ShowSeal
:sealList="sealList"
@delete="deleteSign"
:selPosList="currentDocPosList"
:signType="signType"
/>
</div>
</div>
<!-- 替换印章 -->
<ReplaceSeal
v-if="replaceVisible"
:dialogVisible="replaceVisible"
:sealList="sealList"
:sealId="selectSeal.sealId"
@confirm="_confirmReplace"
/>
</div>
</template>
<script>
import { selectSignInfoH5Sign, sign } from "@/api/sign";
const ReplaceSeal = () => import("./components/ReplaceSeal.vue");
import common from "./model/common";
import DragSeal from "./components/DragSeal.vue";
import KeySeal from "./components/KeySeal.vue";
import ShowSeal from "./components/ShowSeal.vue";
export default {
name: "companySign",
components: { DragSeal, KeySeal, ShowSeal, ReplaceSeal },
data() {
return {
isShow: false,
listLoading: false,
currentDocPosList: [],
docPosList: {}, //每个文档的印章坐标
userData: {},
activeDoc: {},
AuthDialogVisible: false, // 认证弹窗控制器
certInfo: {},
verifyInfoList: [], //认证列表
signType: 0, //1坐标签未预设位置,0关键字签,2坐标签已预设位置
signPosJson: [], //印章回显坐标信息
replaceVisible: false,
selectSeal: {
sealType: "",
domId: "",
sealId: "",
},
signerInfo: {}, //签署人信息
pdfInfo: {
0: {
pdfHeight: 0,
pdfWidth: 0,
},
},
};
},
mixins: [common],
methods: {
// 计算已添加印章项
handlePos() {
this.sealList = this.sealList.map((item) => {
return { ...item, num: 0 };
});
this.currentDocPosList.map((item) => {
for (let i = 0; i < this.sealList.length; i++) {
const element = this.sealList[i];
if (element.code == item.code) {
this.sealList[i].num += 1;
}
}
});
},
// 检查是否加盖可用印章(除时间章)
checkSealDate() {
let checkRes = true;
// 查找是否有加盖印章(只存在时间章的不可以)
const hasSeal = this.currentDocPosList.find((item) => {
return item.isSealDate == 0;
});
checkRes = hasSeal ? true : false;
if (!checkRes) {
this.$message.error("未加盖印章,请先拖拽盖章!");
}
return checkRes;
},
// 删除全部印章
delAllSeal() {
const sealPosList = [...this.currentDocPosList];
for (let i = 0; i < sealPosList.length; i++) {
const element = sealPosList[i];
this.deleteSign(element);
}
},
// 认证成功并提交
async _submitSign() {
this._cancelAuth();
this.listLoading = true;
let sealPosList = [];
if (this.signType == 0) {
// 关键字签无需传坐标
sealPosList = this.currentDocPosList.map((item) => {
return {
sealId: item.code,
};
});
} else {
//坐标签需传坐标
const docSeal = this.currentDocPosList.find((item) => {
return item.isSealDate == 0;
});
sealPosList = this.currentDocPosList.map((item) => {
const sealId = item.isSealDate == 1 ? docSeal.sealId : item.sealId;
return {
sealId,
x: item.posX,
y: item.posY,
pageNo: item.posPage,
isSealDate: item.isSealDate,
};
});
}
const formData = {
signBatchId: this.userData.signBatchId,
userType: 1,
userId: this.userData.userId,
companyId: this.userData.companyId,
signDocumentId: this.userData.signDocumentId,
sealPosList,
verifyType: "",
signPdfUrl: this.activeDoc.signCurrentUrl,
};
console.log(formData, 789789);
if (this.handleCurrentSigner()) {
const { data: res } = await sign(formData);
console.log(res, 2525);
if (res.code == 0) {
this.listLoading = false;
this.$message.success(res.msg);
this.$router.push({
path: "/Previewpdf",
query: {
signBatchId: this.userData.signBatchId,
signDocumentId: this.userData.signDocumentId,
},
});
} else {
this.listLoading = false;
this.$message.warning(res.msg);
if (res.msg == "该文档已被另一方签署,请刷新页面后重试") {
// 重新获取文档信息
this.selectSignInfo("reload");
}
}
} else {
this.listLoading = false;
}
},
// 删除印章
deleteSign(seal) {
let pic = document.querySelector("#" + seal.domId);
pic.parentNode.removeChild(pic);
let index = this.currentDocPosList.findIndex((i) => {
return i.domId == seal.domId;
});
if (index > -1) {
//大于0 代表存在,
this.currentDocPosList.splice(index, 1); //存在就删除
this.handlePos();
}
},
// 印象回显处理
_select(value) {
console.log(value, 3636);
if (this.currentDocPosList.length > 0) {
this.delAllSeal();
}
this.handlePos();
const sealList = this.signPosJson.map((item, index) => {
return {
...value[0],
domId: "dom-" + value[0].code + index,
posPage: item.pageNo || item.posPage,
posX: item.centerX || item.posX,
posY: item.centerY || item.posY,
};
});
let _sealList = [];
if (this.signType == 0) {
// 关键字签署类型
switch (this.signerInfo.keywordSignType) {
case 0: //首个
_sealList = [sealList[0]];
break;
case 1: //倒数第一个
_sealList = [sealList[sealList.length - 1]];
break;
case 2: //全部
_sealList = sealList;
break;
}
} else {
_sealList = sealList;
}
this.currentDocPosList = [..._sealList];
this.showBackSeal();
this.handlePos();
},
//印章回显
showBackSeal() {
for (let i = 0; i < this.currentDocPosList.length; i++) {
const element = this.currentDocPosList[i];
console.log(element, 45454);
const _box = document.getElementById(element.domId);
// 如果已存在就不用添加了
if (_box) break;
const dom = document.createElement("div");
dom.className = `sign-img back-seal drag-img`;
dom.id = element.domId;
dom.style.width = this.scale * element.seal_W + "px";
dom.style.height = this.scale * element.seal_H + "px";
dom.style["line-height"] = this.scale * 50 + "px";
const wh = (this.scale * element.seal_W) / 2;
dom.style.left = Number(element.posX) * this.scale - wh + "px";
dom.style.bottom = Number(element.posY) * this.scale - wh + "px";
dom.style["background-image"] = `url(${element.sealImg})`;
dom.title = element.sealTypeName;
dom.style["background-repeat"] = `no-repeat`;
dom.style["background-size"] = `contain`;
// 坐标签已预设位置的,印章回显后可进行印章替换操作
if (this.signType == 2) {
dom.onclick = this.changeBg;
}
dom.style.cursor = "pointer";
document.querySelector("#can" + element.posPage).appendChild(dom);
}
},
// 打开替换弹窗
changeBg(e) {
const _id = e.currentTarget.id;
const isDom = this.currentDocPosList.find((item) => {
return item.domId == _id;
});
this.selectSeal = {
sealType: isDom.sealType,
domId: isDom.domId,
sealId: isDom.sealId,
};
this.replaceVisible = true;
},
// 印章替换处理
_confirmReplace(visible, value) {
this.replaceVisible = false;
// 替换印章
if (visible) {
const dom = document.getElementById(this.selectSeal.domId);
dom.style.backgroundImage = "url(" + value.sealImg + ")";
const signedPicList = this.currentDocPosList.map((item) => {
const isDom = item.domId == this.selectSeal.domId;
let query = {
...item,
};
if (isDom) {
query = { ...item, ...value, domId: this.selectSeal.domId };
}
return query;
});
this.currentDocPosList = [...signedPicList];
}
},
_getPageIndex(y, dom) {
let maxH = 0;
let index = 1;
let pdfHeight = 0;
let _y = y || 0;
let pdfWidth = 0;
let margin = 0;
let _space = 0;
let pdfH = [];
for (const key in this.pdfInfo) {
if (_y < 0) {
break;
}
const element = this.pdfInfo[key];
pdfH.push(element.pdfHeight);
if (element.index > 1) {
// 外边距为10
margin = (element.index - 1) * 10;
}
// 高度累计
const _maxH = pdfH.reduce((last, i) => {
return last + i;
}, 0);
maxH = _maxH + margin;
// 当前页
pdfWidth = element.pdfWidth;
index = element.index;
// 判断是处于空白区域(外边距)top为负数
if (y > maxH && y < _space && element.index > 1) {
_y = maxH - y + margin;
break;
}
if (y < maxH) {
if (element.index > 1) {
_y = maxH - y - element.pdfHeight;
}
pdfHeight = element.pdfHeight - Math.abs(_y);
break;
}
_space = maxH + margin;
}
return {
index,
top: Math.abs(_y),
bottom: pdfHeight - dom.clientHeight,
pdfWidth,
};
},
// ed.clientX:鼠标焦点距离浏览器右侧的距离
// dom.clientWidth / 2:印章图片宽度的一半
// isMove:是否是再次移动的
_getPageNum(ed, dom, isMove) {
let isOver = true;
const _clientWidth = parseInt(dom.clientWidth / 2);
const _clientHeight = parseInt(dom.clientHeight / 2);
const _left = ed.clientX - _clientWidth;
const _top = ed.clientY - _clientHeight;
// pdf展示区域距离左侧的距离+横向滚动条
const _pdfBox = document.querySelector(".pdf-box");
// 拿到左边坐标
const _xLeft = _left + this.$refs.pdfBox.scrollLeft - _pdfBox.offsetLeft;
const _yTop = _top + this.$refs.pdfBox.scrollTop - _pdfBox.offsetTop;
const _index = this._getPageIndex(_yTop, dom);
const _xRight = _index.pdfWidth - _xLeft - parseInt(dom.clientWidth);
if (
_xLeft >= 0 &&
_index.bottom >= 0 &&
_index.top >= 0 &&
_xRight >= 0
) {
isOver = true;
} else {
isOver = false;
}
// 判断再次移动的时候是否出界
if (isMove) {
const _clientHeight = document.querySelector(
"#can" + _index.index
).clientHeight;
const _distance = _clientHeight - dom.clientHeight - _index.bottom;
isOver = _distance > 0 ? isOver && true : false;
}
return {
isOver,
top: _index.top,
left: _xLeft,
index: _index.index,
bottom: _index.bottom,
posX: (_xLeft + _clientWidth) / this.scale,
posY: (_index.bottom + _clientHeight) / this.scale,
};
},
// 坐标签拖拽处理
_signPic(e, seal) {
let checkRes = true;
// 判断是否已加盖印章
if (seal.sealType == "DATE_SEAL") {
checkRes = this.checkSealDate();
}
if (!checkRes) return;
// 印章的唯一标识
const timerCount = new Date().getTime() + "";
this.count++;
let dom = document.createElement("div");
dom.style.left = 0 + "px";
dom.style.top = e.clientY + 1.5 * dom.clientHeight + "px";
if (seal.sealType == "DATE_SEAL") {
dom.style.height = this.scale * 16 + "px";
dom.style.width = this.scale * 105 + "px";
const getNowFormatDate = this.getNowFormatDate();
dom.innerHTML = `<div class="delete" @click.stop="deleteIt">删除</div><span style="font-weight:bolder">${getNowFormatDate}</span>`;
} else {
dom.style.width = this.scale * seal.seal_W + "px";
dom.style.height = this.scale * seal.seal_H + "px";
dom.style["background-image"] = `url(${seal.sealImg})`;
dom.innerHTML = `<div class="delete" @click.stop="deleteIt">删除</div>`;
}
dom.className = `sign-img drag-img`;
const signDocumentId = this.activeDoc.signDocumentId.slice(
this.activeDoc.signDocumentId.length - 6,
this.activeDoc.signDocumentId.length
);
const domId = seal.sealType + signDocumentId + timerCount;
dom.id = domId;
document.querySelector("#pageContent").appendChild(dom);
document.onmousemove = (e) => {
dom.style.left = e.clientX - parseInt(dom.clientWidth / 2) + "px";
dom.style.top = e.clientY - parseInt(dom.clientHeight / 2) + "px";
};
// 鼠标抬开
document.onmouseup = (e) => {
// 判断是否越界,未越界测返回坐标
const _dom = this._getPageNum(e, dom);
document.querySelector("#pageContent").removeChild(dom);
if (!_dom.isOver) {
document.onmousemove = null;
document.onmouseup = null;
this.$message.error("请将印章拖拽到合同区域");
return;
} else {
dom.style.left = _dom.left + "px";
dom.style.top = _dom.top + "px";
document.querySelector("#can" + _dom.index).appendChild(dom);
let docId = this.activeDoc.signDocumentId;
// 若为加盖时间印章,则该时间印章的sealId、sealType拿可用印章第一个印章
let selectSeal = this.sealList[0];
let sealId =
seal.sealType == "DATE_SEAL" ? selectSeal.sealId : seal.sealId;
let sealType =
seal.sealType == "DATE_SEAL" ? selectSeal.sealType : seal.sealType;
let pos = {
domId: domId,
left: _dom.left * this.scale,
top: _dom.top * this.scale,
posX: _dom.posX,
posY: _dom.posY,
posPage: _dom.index,
signDocumentId: docId,
...seal,
sealId,
sealType,
};
this.currentDocPosList.push(pos);
this.handlePos();
}
document.onmousemove = null;
document.onmouseup = null;
dom.onmouseenter = this.mouseenter;
dom.onmouseleave = this.mouseleave;
dom.onmousedown = this.moveTo;
dom.childNodes[0].onclick = this.deleteIt;
};
},
moveTo(e) {
let odiv = e.currentTarget; //获取目标元素
const _domId = this.currentDocPosList.find((item) => {
return item.domId == odiv.id;
});
let dragDom = "";
document.onmousemove = (e) => {
dragDom = this._getPageNum(e, odiv, true);
odiv.style.left = dragDom.left + "px";
odiv.style.top = dragDom.top + "px";
};
document.onmouseup = (e) => {
document.onmousemove = null;
document.onmouseup = null;
if (dragDom && !dragDom.isOver) {
odiv.style.left = _domId.left / this.scale + "px";
odiv.style.top = _domId.top / this.scale + "px";
this.$message.error("请将印章拖拽到合同区域");
return;
} else {
const _index = this.currentDocPosList.findIndex((item) => {
return item.domId == odiv.id;
});
this.currentDocPosList[_index].left = dragDom.left * this.scale;
this.currentDocPosList[_index].top = dragDom.top * this.scale;
this.currentDocPosList[_index].posX = dragDom.posX;
this.currentDocPosList[_index].posY = dragDom.posY;
}
};
},
// 查询详情
async selectSignInfo(code) {
this.listLoading = true;
const query = {
signBatchId: this.userData.signBatchId,
};
const { data: res } = await selectSignInfoH5Sign(query);
if (res.code == 0) {
const document = res.data.documentList.filter((item) => {
return item.signDocumentId == this.userData.signDocumentId;
})[0];
this._getFileSteam(document.signCurrentUrl);
}
this.listLoading = false;
},
},
computed: {
currentCompanyId() {
return this.$store.state.currentCompanyId;
},
},
created() {
const query = this.$route.query;
this._getAnalysisCode(query.code);
},
mounted() {
this.$nextTick(function () {
this.$refs.pdfBox.addEventListener("scroll", this.handleScroll, false);
});
},
};
</script>
<style lang="scss">
.back-seal {
position: absolute;
cursor: move;
z-index: 7;
// overflow: hidden;
}
.delete {
width: 100%;
position: absolute;
bottom: -20px;
text-align: center;
color: #fff;
font-size: 16px;
background-color: rgba(236, 49, 49, 0.7);
cursor: pointer;
display: none;
}
.nameBox {
margin-top: 10px;
width: 100%;
font-size: 14px;
text-align: center;
color: #333;
}
.sign-img {
position: absolute;
cursor: move;
z-index: 7;
// overflow: hidden;
background-repeat: no-repeat;
background-size: contain;
background-position: 100%;
}
</style>
<style lang="scss">
.headerBox {
// position: fixed;
// top: 0;
width: 100%;
background: #fff;
z-index: 999;
.doc-title-list {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 60px;
.active-doc {
border: none;
color: #444;
font-size: 22px;
}
}
.page-title {
margin-left: 15px;
}
.sign-btn {
position: absolute;
top: 12px;
right: 20px;
}
}
.cont {
margin-top: 20px;
display: flex;
.item {
margin: 0 0 25px 0;
}
}
.left-area-container,
.right-area-container {
// width: 340px;
width: 20%;
overflow: auto;
font-size: 14px;
background: #fff;
}
.sign-title {
height: 55px;
line-height: 55px;
background: #0091ff;
border-radius: 5px;
color: #fff;
margin-bottom: 5px;
font-size: 16px;
}
.sign-parties {
padding: 0 5px;
}
.instructBox {
text-align: left;
color: #999;
line-height: 22px;
p {
margin-top: 5px;
}
}
.signed-sum li {
text-align: left;
cursor: auto;
}
.signed-sum-number {
font-size: 16px;
color: #0096ff;
}
.right-area-container .sign-title {
li {
width: 33.33%;
}
}
.right-area-container .pages {
ul {
background: #fff;
border-radius: 5px;
margin-bottom: 5px;
li {
width: 33.33%;
margin: 0;
}
}
}
.delete {
width: 100%;
position: absolute;
bottom: -20px;
text-align: center;
color: #fff;
font-size: 16px;
background-color: rgba(236, 49, 49, 0.7);
cursor: pointer;
display: none;
}
.nameBox {
margin-top: 10px;
width: 100%;
font-size: 14px;
text-align: center;
color: #333;
}
.viewerContainer {
display: flex;
height: 91vh;
width: 80%;
overflow: auto;
user-select: none;
/*firefox浏览器*/
-moz-user-select: none;
/*safari、chrome浏览器*/
-webkit-user-select: none; /*Safari中不支持该属性值,只能使用none或者text,或者是在html的标签属性中使用*/
.input {
border: none;
outline: none;
width: 100%;
}
}
.pdfContent_1PW2f {
width: 700px;
flex: 1;
display: flex;
flex-direction: column;
height: 100%;
overflow: auto;
// background: #f5f5f5;
.pdf-header {
/*position: fixed;*/
top: 55px;
left: 240px;
right: 240px;
height: 40px;
border-bottom: 1px solid #eee;
background-color: #fff;
z-index: 100;
text-align: center;
display: flex;
.block {
flex: 1;
display: flex;
.demonstration,
.slider {
flex: 0 0 150px;
line-height: 40px;
width: 150px;
text-align: right;
}
.demonstration {
flex: 1;
margin-right: 20px;
}
}
.input {
flex: 1;
text-align: left;
line-height: 40px;
margin-left: 20px;
.input-text {
border: none;
outline: none;
border-bottom: 1px solid #e4e7ed;
margin-left: 10px;
width: 25px;
text-align: center;
}
}
}
.pdf-container {
display: inline-block;
overflow: auto;
height: 100%;
width: 100%;
.pdf-box {
position: relative;
margin: 0 auto;
.sign-img {
z-index: 4;
}
}
}
.pdfPage_1yRne {
/*transition: left .3s;*/
position: relative;
margin: 10px 0;
}
.dragLayer_3ccsq {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
}
.signed-list {
padding: 0 15px;
display: flex;
justify-content: space-between;
align-items: center;
span {
flex: 1;
}
}
.signed-item {
margin: 10px 0;
border: 1px dashed rgba(0, 0, 0, 0.3);
}
</style>
组件代码DragSeal:
<template>
<div>
<div class="sign-fields item">
<div class="sign-title">请选择印章类型</div>
<div class="sign-list">
<div class="seal-box-wrap">
<div
v-for="seal in sealList"
:key="seal.code"
v-bind:id="seal.code"
@mousedown="_dragSeal($event, seal)"
>
<template v-if="seal.isSealDate == 0">
<div
class="seal-img"
:style="{
height: 130 + 'px',
width: 130 + 'px',
backgroundImage: 'url(' + seal.sealImg + ')',
}"
></div>
</template>
<div
v-else
class="seal-date"
:style="{
height: 130 + 'px',
width: 130 + 'px',
lineHeight: 130 + 'px',
}"
>
{{ getNowFormatDate() }}
</div>
</div>
</div>
</div>
</div>
<div class="sign-fields item instructBox">
<div>
<div>设置签章位置说明</div>
<p>1、告知签署方需要在文件具体哪一处进行加盖电子印章</p>
</div>
<div>
操作指示:鼠标选中上方签约方信息,鼠标左键单击选择印章/时间戳,查找正文内容盖章位置单击左键
</div>
</div>
</div>
</template>
<script>
export default {
props: {
sealList: {
type: Array,
default: () => {
return [];
},
},
},
components: {},
data() {
return {};
},
methods: {
_dragSeal(e, seal) {
this.$emit("drag", e, seal);
},
getNowFormatDate() {
let date = new Date(),
year = date.getFullYear(), //获取完整的年份(4位)
month = date.getMonth() + 1, //获取当前月份(0-11,0代表1月)
strDate = date.getDate(); // 获取当前日(1-31)
if (month < 10) month = `0${month}`; // 如果月份是个位数,在前面补0
if (strDate < 10) strDate = `0${strDate}`; // 如果日是个位数,在前面补0
return `${year} 年 ${month} 月 ${strDate} 日`;
},
},
mounted() {},
};
</script>
<style lang='scss'>
.sign-fields .sign-list {
padding: 0 20px;
}
.seal-box-wrap {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
.seal-box {
width: 100%;
border-radius: 5px;
padding: 10px;
margin-top: 15px;
background-color: #fff;
}
.seal-img {
background-size: contain;
background-repeat: no-repeat;
background-position: 100%;
border: 1px solid rgb(225, 225, 226);
margin: 8px 0;
}
.seal-date {
text-align: center;
font-weight: bolder;
border: 1px solid rgb(225, 225, 226);
}
}
</style>
组件代码KeySeal:
<template>
<div class="sign-fields item">
<div class="sign-title">请选择印章类型</div>
<div class="sign-list-vertical">
<el-radio-group v-model="selectSeal" @input="_selectSeal">
<el-radio
v-for="seal in showList"
:key="seal.code"
v-bind:id="seal.code"
v-model="seal.code"
:label="seal.code"
border
>
<template v-if="seal.sealType != 'DATE_SEAL'">
<span class="seal-name">{{ seal.sealTypeName }}</span>
<div
class="seal-img"
:style="{
height: 100 + 'px',
width: 100 + 'px',
backgroundImage: 'url(' + seal.sealImg + ')',
}"
></div>
</template>
</el-radio>
</el-radio-group>
</div>
</div>
</template>
<script>
export default {
props: {
sealList: {
type: Array,
default: () => {
return [];
},
},
},
components: {},
data() {
return {
selectSeal: "",
showList: [],
};
},
watch: {
sealList: {
handler(newVal, oldVal) {
this.showList = newVal.filter((item) => {
return item.isSealDate == 0;
});
},
immediate: true,
deep: true,
},
},
methods: {
_selectSeal(value) {
const _seal = this.sealList
.filter((item) => {
return item.code == value;
})
.map((item) => {
return {
...item,
posX: 0,
posY: 0,
posPage: 0,
};
});
this.$emit("select", _seal);
},
getNowFormatDate() {
let date = new Date(),
year = date.getFullYear(), //获取完整的年份(4位)
month = date.getMonth() + 1, //获取当前月份(0-11,0代表1月)
strDate = date.getDate(); // 获取当前日(1-31)
if (month < 10) month = `0${month}`; // 如果月份是个位数,在前面补0
if (strDate < 10) strDate = `0${strDate}`; // 如果日是个位数,在前面补0
return `${year} 年 ${month} 月 ${strDate} 日`;
},
},
mounted() {},
};
</script>
<style lang='scss'>
.sign-list-vertical {
display: flex;
flex-direction: column;
justify-content: flex-start;
margin-top: 10px;
.seal-item {
margin-bottom: 15px;
}
.el-radio.is-bordered {
width: 100%;
height: auto;
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
padding: 10px;
}
.el-radio__label {
display: flex;
justify-content: space-around;
align-items: center;
}
}
.seal-name {
margin-right: 15px;
}
.seal-img {
background-size: contain;
background-repeat: no-repeat;
background-position: 100%;
}
.el-radio.is-bordered + .el-radio.is-bordered {
margin-left: 0;
}
</style>
组件代码ReplaceSeal:
<template>
<BaseDialog
v-if="dialogVisible"
:dialogVisible="dialogVisible"
title="替换印章"
@closeDialog="_closeDialog"
@confirmDialog="_confirmSeal"
>
<span>选择印章:</span>
<el-select
v-model="changeSeal"
placeholder="请选择"
style="width: 80%"
value-key="sealId"
>
<el-option
v-for="item in showList"
:key="item.sealId"
:label="item.sealTypeName"
:value="item"
:disabled="item.sealId == sealId"
>
<span style="float: left">{{ item.sealTypeName }}</span>
<span style="float: right; color: #8492a6; font-size: 13px">{{
item.sealId == sealId ? "当前印章" : ""
}}</span>
</el-option>
</el-select></BaseDialog
>
</template>
<script>
const BaseDialog = () => import("@/components/BaseDialog.vue");
export default {
props: {
dialogVisible: {
type: Boolean,
default: false,
},
sealList: {
type: Array,
default: () => {
return [];
},
},
sealId: {
type: String,
default: "",
},
},
components: { BaseDialog },
data() {
return {
changeSeal: "",
showList: [],
};
},
watch: {
sealList: {
handler(newVal, oldVal) {
this.showList = newVal.filter((item) => {
return item.isSealDate == 0;
});
},
immediate: true,
deep: true,
},
},
methods: {
_closeDialog() {
this.$emit("confirm", false);
},
_confirmSeal() {
if (!this.changeSeal) {
this.$message.warning("请先选择印章!");
return;
}
this.$emit("confirm", true, this.changeSeal);
},
},
mounted() {},
};
</script>
<style lang='scss' scoped></style>
组件代码ShowSeal:
<template>
<div>
<div class="sign-parties item">
<div class="sign-title">已{{ signType == 1 ? "添加" : "选" }}印章项</div>
<div class="sign-list">
<div v-for="seal in sealList" :key="seal.code" class="show-seal">
<template v-if="seal.num > 0">
<span> {{ seal.sealTypeName }} </span>
<span class="primaryText"> {{ seal.num }} </span>项
</template>
</div>
</div>
</div>
<div class="sign-fields item">
<div class="sign-title signed-list">
<span>签章类型</span>
<span>页码</span>
<span>操作</span>
</div>
<div class="sign-list pages">
<div
class="signed-list signed-item"
v-for="a in selPosList"
:key="a.domId"
:title="a.sealTypeName"
>
<span
><span> {{ a.sealTypeName }}</span>
<span v-if="a.code == 'date'">-盖章时间</span></span
>
<span> 第{{ a.posPage }}页 </span>
<span
v-if="signType == 1"
class="el-icon-delete"
@click="deleteSign(a)"
></span>
<span v-else></span>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
sealList: {
type: Array,
default: () => {
return [];
},
},
selPosList: {
type: Array,
default: () => {
return [];
},
},
signType: {
type: Number,
default: 1,
},
},
components: {},
data() {
return {};
},
methods: {
deleteSign(a) {
this.$emit("delete", a);
},
},
mounted() {},
};
</script>
<style lang='scss' scoped>
.sign-list {
max-height: 580px;
overflow-y: auto;
.show-seal {
padding-left: 10px;
text-align: left;
margin-bottom: 5px;
font-size: 16px;
}
}
</style>