|
|
<template>
|
|
|
<view>
|
|
|
<topnav :title='pageTitle' @tohome="tohome"></topnav>
|
|
|
<view class="content">
|
|
|
<view class="orderBox">
|
|
|
<orderinfo :info="order"></orderinfo>
|
|
|
</view>
|
|
|
|
|
|
<view class="pageTitle">
|
|
|
协议签名
|
|
|
</view>
|
|
|
|
|
|
<view class="signatureBox">
|
|
|
<view class="signatureItem">
|
|
|
<view class="signatureTitle">护工签名</view>
|
|
|
<view class="signatureArea">
|
|
|
<!-- 未签名时显示开始签名按钮(弹出全屏签名) -->
|
|
|
<view v-if="!paramedicSignImage" class="signatureStart" @click="openSignature('paramedic')">
|
|
|
开始签名
|
|
|
</view>
|
|
|
<!-- 签名图片 - 已签名时显示 -->
|
|
|
<image
|
|
|
v-if="paramedicSignImage"
|
|
|
:src="paramedicSignImage"
|
|
|
class="signatureImage"
|
|
|
:style="getSignatureImageStyle(paramedicSignImage)"
|
|
|
mode="aspectFit">
|
|
|
</image>
|
|
|
</view>
|
|
|
<view class="signatureActions">
|
|
|
<text class="btnSave" @click="openSignature('paramedic')" v-if="!paramedicSignImage">开始签名</text>
|
|
|
<text class="btnResign" @click="resignSignature('paramedic')" v-if="paramedicSignImage">重新签名</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
<view class="signatureItem">
|
|
|
<view class="signatureTitle">客户签名</view>
|
|
|
<view class="signatureArea">
|
|
|
<!-- 未签名时显示开始签名按钮(弹出全屏签名) -->
|
|
|
<view v-if="!customerSignImage" class="signatureStart" @click="openSignature('customer')">
|
|
|
开始签名
|
|
|
</view>
|
|
|
<!-- 签名图片 - 已签名时显示 -->
|
|
|
<image
|
|
|
v-if="customerSignImage"
|
|
|
:src="customerSignImage"
|
|
|
class="signatureImage"
|
|
|
:style="getSignatureImageStyle(customerSignImage)"
|
|
|
mode="aspectFit">
|
|
|
</image>
|
|
|
</view>
|
|
|
<view class="signatureActions">
|
|
|
<text class="btnSave" @click="openSignature('customer')" v-if="!customerSignImage">开始签名</text>
|
|
|
<text class="btnResign" @click="resignSignature('customer')" v-if="customerSignImage">重新签名</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
<!-- <view class="signatureItem">
|
|
|
<view class="signatureTitle">公司签名</view>
|
|
|
<view class="signatureArea">
|
|
|
<image
|
|
|
:src="companySignImage"
|
|
|
class="signatureImage"
|
|
|
mode="aspectFit">
|
|
|
</image>
|
|
|
</view>
|
|
|
<view class="signatureActions">
|
|
|
<text class="btnSave" style="opacity:.6;">已使用公司签名</text>
|
|
|
</view>
|
|
|
</view> -->
|
|
|
</view>
|
|
|
|
|
|
<!-- 预览协议按钮 -->
|
|
|
<view class="previewSection">
|
|
|
<view class="previewBtn" @click="previewAgreement">
|
|
|
预览协议
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
<view class="bottom">
|
|
|
<view class="bottomLeft">
|
|
|
</view>
|
|
|
<view class="bottomRight">
|
|
|
<view class="btnCancel btn" @click="bindCancel">取消</view>
|
|
|
<view class="btnSubmit btn" @click="bindsubmitFun">提交</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
<!-- 协议预览弹窗 -->
|
|
|
<uni-popup ref="agreementPopup" type="center" :mask-click="true" class="fullscreen-popup" :safe-area="false">
|
|
|
<view class="agreementPopup">
|
|
|
<view class="popupHeader">
|
|
|
<text class="popupTitle">协议预览</text>
|
|
|
<text class="popupClose" @click="closeAgreementPopup">×</text>
|
|
|
</view>
|
|
|
<scroll-view class="popupContent" v-if="agreementHtml" scroll-y="true" style="max-height: 100vh;">
|
|
|
<div class="agreementContent" v-html="agreementHtml"></div>
|
|
|
</scroll-view>
|
|
|
<view class="popupContent" v-else>
|
|
|
<view class="noAgreement">
|
|
|
<text>还未上传协议,请联系管理员补充协议</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
<view class="popupFooter" v-if="agreementHtml">
|
|
|
<view class="btnGenerate"
|
|
|
@click="handleDirectSubmit"
|
|
|
:class="{ disabled: isGenerating }"
|
|
|
:disabled="isGenerating">
|
|
|
{{ generateButtonText }}
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
</uni-popup>
|
|
|
|
|
|
<!-- 全屏签名弹窗 -->
|
|
|
<uni-popup ref="signaturePopup" type="center" :mask-click="false" class="fullscreen-popup" :safe-area="false">
|
|
|
<view class="signaturePopup">
|
|
|
<view class="popupHeader">
|
|
|
<text class="popupTitle">{{ signaturePopupTitle }}</text>
|
|
|
<text class="popupClose" @click="closeSignaturePopup">×</text>
|
|
|
</view>
|
|
|
<view class="popupContent">
|
|
|
<view class="signatureWorkspace">
|
|
|
<view class="signatureInlineToast" v-if="signatureToastVisible">{{ signatureToastText }}</view>
|
|
|
<view class="signatureCanvasWrap">
|
|
|
<l-signature
|
|
|
ref="popupSignatureRef"
|
|
|
:penColor="penColor"
|
|
|
:penSize="penSize"
|
|
|
:openSmooth="openSmooth"
|
|
|
:boundingBox="boundingBox"
|
|
|
disableScroll
|
|
|
class="signatureCanvas">
|
|
|
</l-signature>
|
|
|
</view>
|
|
|
<view class="signatureControlsRow">
|
|
|
<view class="btnRow btnRowClear" @click="clearPopupSignature">清除</view>
|
|
|
<view class="btnRow btnRowReset" @click="resetPopupSignature">重置</view>
|
|
|
<view class="btnRow btnRowSave" @click="savePopupSignature">保存</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
</uni-popup>
|
|
|
</view>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
var util = require("../../../../utils/util.js");
|
|
|
export default {
|
|
|
data() {
|
|
|
return {
|
|
|
pageTitle: "签订协议",
|
|
|
order: {},
|
|
|
id: "",
|
|
|
// 签名相关
|
|
|
paramedicSignPath: "",
|
|
|
customerSignPath: "",
|
|
|
companySignPath: "",
|
|
|
paramedicSignId: "",
|
|
|
customerSignId: "",
|
|
|
companySignId: "",
|
|
|
paramedicSignImage: "", // 护工签名图片
|
|
|
customerSignImage: "", // 客户签名图片
|
|
|
companySignImage: '', // 公司签名图片(固定)
|
|
|
// 协议预览相关
|
|
|
agreementHtml: "", // 协议HTML内容
|
|
|
pendingAgreementHtml: "", // 待提交的HTML内容(包含完整头部)
|
|
|
// 签名组件配置
|
|
|
penColor: '#000',
|
|
|
penSize: 3,
|
|
|
openSmooth: true,
|
|
|
boundingBox: true,
|
|
|
// 按钮状态
|
|
|
isGenerating: false, // 是否正在提交
|
|
|
generateButtonText: '直接提交', // 按钮文本
|
|
|
// 全屏签名弹窗
|
|
|
currentSignatureType: '',
|
|
|
signaturePopupTitle: '',
|
|
|
signatureToastVisible: false,
|
|
|
signatureToastText: ''
|
|
|
}
|
|
|
},
|
|
|
onLoad: function(option) {
|
|
|
var that = this;
|
|
|
that.id = option.id;
|
|
|
util.getOrderInfo(option.id, function(r) {
|
|
|
that.order = r.data;
|
|
|
// 初始化公司签名(固定图片)
|
|
|
that.initCompanySign();
|
|
|
}, function(r) {
|
|
|
|
|
|
});
|
|
|
},
|
|
|
methods: {
|
|
|
// 规范化URL,去除域名后的多余斜杠以及 //storage -> /storage
|
|
|
normalizeUrl: function(url){
|
|
|
if(!url){ return url; }
|
|
|
let u = String(url);
|
|
|
// 把 :// 后面可能出现的多个 / 压缩成一个 /
|
|
|
u = u.replace(/(:\/\/[^/]*?)\/+/, '$1/');
|
|
|
// 把 //storage 归一为 /storage
|
|
|
u = u.replace(/\/+storage\//, '/storage/');
|
|
|
return u;
|
|
|
},
|
|
|
// 初始化公司签名(不需要手写)
|
|
|
initCompanySign: function(){
|
|
|
// 使用指定的公司签名图片地址
|
|
|
this.companySignImage = 'https://tiantianxinye.365care.langye.net/h5/static/companySign.png';
|
|
|
this.companySignId = 'STATIC_COMPANY_SIGN';
|
|
|
},
|
|
|
tohome:function(){
|
|
|
uni.navigateTo({
|
|
|
url:"../../../../pages/index/index"
|
|
|
})
|
|
|
},
|
|
|
|
|
|
// 显示签名弹窗内的提示
|
|
|
showSignatureToast: function(text){
|
|
|
this.signatureToastText = text || '';
|
|
|
this.signatureToastVisible = true;
|
|
|
clearTimeout(this._signatureToastTimer);
|
|
|
this._signatureToastTimer = setTimeout(()=>{
|
|
|
this.signatureToastVisible = false;
|
|
|
}, 1600);
|
|
|
},
|
|
|
bindCancel: function(e) {
|
|
|
uni.navigateBack({
|
|
|
|
|
|
})
|
|
|
},
|
|
|
bindsubmitFun: function(e) {
|
|
|
var that = this;
|
|
|
|
|
|
// 检查是否所有签名都已完成(公司签名固定,不再校验 companySignId)
|
|
|
if (!that.paramedicSignId || !that.customerSignId) {
|
|
|
util.alert("请完成所有签名");
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
uni.showModal({
|
|
|
title: '提示',
|
|
|
content: "确认签订协议?",
|
|
|
confirmText: "确认",
|
|
|
confirmColor: "#000",
|
|
|
cancelColor: "#eee",
|
|
|
success(res) {
|
|
|
if (res.confirm) {
|
|
|
that.submitAgreement();
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
},
|
|
|
|
|
|
// 处理直接提交(从预览弹窗中调用)
|
|
|
handleDirectSubmit: function() {
|
|
|
var that = this;
|
|
|
|
|
|
// 防重复点击
|
|
|
if (that.isGenerating) {
|
|
|
util.alert('正在提交协议,请稍候...');
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 设置按钮状态
|
|
|
that.isGenerating = true;
|
|
|
that.generateButtonText = '提交中...';
|
|
|
|
|
|
// 构建完整的HTML内容
|
|
|
const fullHtml = `<!DOCTYPE html>
|
|
|
<html>
|
|
|
<head>
|
|
|
<meta charset="utf-8">
|
|
|
<title>协议</title>
|
|
|
</head>
|
|
|
<body style="font-family: 'SimSun', 'Microsoft YaHei', 'WenQuanYi Zen Hei', sans-serif;">
|
|
|
${that.agreementHtml}
|
|
|
</body>
|
|
|
</html>`;
|
|
|
|
|
|
// 设置待提交的HTML内容
|
|
|
that.pendingAgreementHtml = fullHtml;
|
|
|
|
|
|
// 关闭弹窗并提交
|
|
|
that.closeAgreementPopup();
|
|
|
|
|
|
// 调用提交方法
|
|
|
that.submitAgreement();
|
|
|
},
|
|
|
|
|
|
// 打开全屏签名
|
|
|
openSignature: function(type){
|
|
|
this.currentSignatureType = type;
|
|
|
const typeNames = {
|
|
|
'paramedic': '护工签名',
|
|
|
'customer': '客户签名',
|
|
|
'company': '公司签名'
|
|
|
};
|
|
|
this.signaturePopupTitle = typeNames[type] || '签名';
|
|
|
this.$nextTick(()=>{
|
|
|
this.$refs.signaturePopup.open();
|
|
|
// 清空一次画布
|
|
|
setTimeout(()=>{
|
|
|
if(this.$refs.popupSignatureRef){
|
|
|
this.$refs.popupSignatureRef.clear();
|
|
|
}
|
|
|
}, 50);
|
|
|
});
|
|
|
},
|
|
|
|
|
|
// 关闭全屏签名
|
|
|
closeSignaturePopup: function(){
|
|
|
if(this.$refs.signaturePopup){
|
|
|
this.$refs.signaturePopup.close();
|
|
|
}
|
|
|
},
|
|
|
|
|
|
// 清除弹窗中的签名
|
|
|
clearPopupSignature: function(){
|
|
|
if(this.$refs.popupSignatureRef){
|
|
|
this.$refs.popupSignatureRef.clear();
|
|
|
}
|
|
|
},
|
|
|
|
|
|
// 重置:清空画布并清除当前签名人的已保存签名(ID与图片)
|
|
|
resetPopupSignature: function(){
|
|
|
this.clearPopupSignature();
|
|
|
const type = this.currentSignatureType;
|
|
|
switch(type){
|
|
|
case 'paramedic':
|
|
|
this.paramedicSignId = '';
|
|
|
this.paramedicSignImage = '';
|
|
|
break;
|
|
|
case 'customer':
|
|
|
this.customerSignId = '';
|
|
|
this.customerSignImage = '';
|
|
|
break;
|
|
|
case 'company':
|
|
|
this.companySignId = '';
|
|
|
this.companySignImage = '';
|
|
|
break;
|
|
|
}
|
|
|
// 签名被重置后,若已有协议,需清除以避免不一致
|
|
|
this.autoClearAgreement();
|
|
|
},
|
|
|
|
|
|
// 保存弹窗中的签名
|
|
|
savePopupSignature: function(){
|
|
|
const type = this.currentSignatureType;
|
|
|
if(!type){
|
|
|
return;
|
|
|
}
|
|
|
if(this.$refs.popupSignatureRef){
|
|
|
// 若未签字,禁止保存
|
|
|
try{
|
|
|
if (typeof this.$refs.popupSignatureRef.isEmpty === 'function' && this.$refs.popupSignatureRef.isEmpty()){
|
|
|
this.showSignatureToast('请先签名后再保存');
|
|
|
return;
|
|
|
}
|
|
|
}catch(e){
|
|
|
// 兼容无isEmpty方法的实现,继续后续流程
|
|
|
}
|
|
|
this.$refs.popupSignatureRef.canvasToTempFilePath({
|
|
|
quality: 0.9,
|
|
|
success: (res)=>{
|
|
|
// 直接使用原图上传,不进行旋转
|
|
|
this.rotateImageToLandscape(res.tempFilePath, (rotatedDataUrl)=>{
|
|
|
const uploadPath = rotatedDataUrl || res.tempFilePath;
|
|
|
this.uploadSignature(uploadPath, type, ()=>{
|
|
|
this.closeSignaturePopup();
|
|
|
// 清理已生成协议
|
|
|
this.checkAndClearAgreement(type);
|
|
|
});
|
|
|
});
|
|
|
},
|
|
|
fail: ()=>{
|
|
|
util.alert('签名保存失败');
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
},
|
|
|
|
|
|
// 不进行图片旋转,直接使用原图
|
|
|
rotateImageToLandscape: function(filePath, callback){
|
|
|
console.log('使用原图,不进行旋转:', filePath);
|
|
|
// 直接返回 null,表示使用原图
|
|
|
callback(null);
|
|
|
},
|
|
|
|
|
|
// 清除签名
|
|
|
clearSignature: function(type) {
|
|
|
const refName = type + 'SignatureRef';
|
|
|
if (this.$refs[refName]) {
|
|
|
this.$refs[refName].clear();
|
|
|
this.setSignPath(type, "");
|
|
|
}
|
|
|
},
|
|
|
|
|
|
// 获取签名图片样式(正向显示)
|
|
|
getSignatureImageStyle: function(imagePath) {
|
|
|
// 统一使用正向显示,不进行旋转
|
|
|
return {
|
|
|
width: '120px',
|
|
|
height: '60px'
|
|
|
};
|
|
|
},
|
|
|
|
|
|
// 保存签名
|
|
|
saveSignature: function(type) {
|
|
|
const refName = type + 'SignatureRef';
|
|
|
if (this.$refs[refName]) {
|
|
|
console.log('开始保存签名:', type);
|
|
|
this.$refs[refName].canvasToTempFilePath({
|
|
|
quality: 0.8,
|
|
|
success: (res) => {
|
|
|
console.log('签名保存成功:', type, res);
|
|
|
this.setSignPath(type, res.tempFilePath);
|
|
|
|
|
|
// 保存成功后立即上传到接口
|
|
|
console.log('开始上传签名到接口:', type, res.tempFilePath);
|
|
|
this.uploadSignature(res.tempFilePath, type, (signId) => {
|
|
|
console.log('签名上传完成:', type, signId);
|
|
|
// 上传成功后清除签名路径,图片会自动显示
|
|
|
this.setSignPath(type, "");
|
|
|
|
|
|
// 将英文type转换为中文显示
|
|
|
const typeNames = {
|
|
|
'paramedic': '护工',
|
|
|
'customer': '客户',
|
|
|
'company': '公司'
|
|
|
};
|
|
|
const typeName = typeNames[type] || type;
|
|
|
util.alert(typeName + '签名上传成功');
|
|
|
|
|
|
// 检查是否需要清除已生成的协议
|
|
|
this.checkAndClearAgreement(type);
|
|
|
});
|
|
|
},
|
|
|
fail: (err) => {
|
|
|
console.log('签名保存失败:', type, err);
|
|
|
util.alert(type + '签名保存失败');
|
|
|
}
|
|
|
});
|
|
|
} else {
|
|
|
console.log('签名组件引用不存在:', refName);
|
|
|
}
|
|
|
},
|
|
|
|
|
|
// 重新签名
|
|
|
resignSignature: function(type) {
|
|
|
console.log('重新签名:', type);
|
|
|
|
|
|
// 清除签名ID和图片
|
|
|
switch(type) {
|
|
|
case 'paramedic':
|
|
|
this.paramedicSignId = "";
|
|
|
this.paramedicSignImage = "";
|
|
|
break;
|
|
|
case 'customer':
|
|
|
this.customerSignId = "";
|
|
|
this.customerSignImage = "";
|
|
|
break;
|
|
|
case 'company':
|
|
|
this.companySignId = "";
|
|
|
this.companySignImage = "";
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
// 清除签名路径
|
|
|
this.setSignPath(type, "");
|
|
|
|
|
|
// 将英文type转换为中文显示
|
|
|
const typeNames = {
|
|
|
'paramedic': '护工',
|
|
|
'customer': '客户',
|
|
|
'company': '公司'
|
|
|
};
|
|
|
const typeName = typeNames[type] || type;
|
|
|
|
|
|
// 自动清除已生成的协议
|
|
|
this.autoClearAgreement();
|
|
|
|
|
|
// 立即弹出对应的签名区域
|
|
|
this.openSignature(type);
|
|
|
},
|
|
|
|
|
|
// 签名保存事件处理
|
|
|
onSignatureSave: function(e) {
|
|
|
const type = e.currentTarget.dataset.type;
|
|
|
console.log('签名保存事件:', type);
|
|
|
},
|
|
|
|
|
|
// 设置签名路径
|
|
|
setSignPath: function(type, path) {
|
|
|
switch(type) {
|
|
|
case 'paramedic':
|
|
|
this.paramedicSignPath = path;
|
|
|
break;
|
|
|
case 'customer':
|
|
|
this.customerSignPath = path;
|
|
|
break;
|
|
|
case 'company':
|
|
|
this.companySignPath = path;
|
|
|
break;
|
|
|
}
|
|
|
},
|
|
|
|
|
|
// 上传单个签名
|
|
|
uploadSignature: function(filePath, type, callback) {
|
|
|
var that = this;
|
|
|
var user = uni.getStorageSync('userInfo');
|
|
|
|
|
|
if (!user || !user.access_token) {
|
|
|
util.alert('用户未登录或token无效');
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
console.log('开始上传签名:', type, filePath);
|
|
|
|
|
|
// 支持 dataURL 和本地临时路径
|
|
|
const doUpload = (pathToUpload) => {
|
|
|
uni.uploadFile({
|
|
|
url: util.HOST + 'manager/upload-image',
|
|
|
filePath: pathToUpload,
|
|
|
name: 'file',
|
|
|
formData: {
|
|
|
'token': user.access_token,
|
|
|
'folder': 'public'
|
|
|
},
|
|
|
success(res) {
|
|
|
console.log('签名上传响应:', res);
|
|
|
console.log('响应状态码:', res.statusCode);
|
|
|
console.log('响应数据类型:', typeof res.data);
|
|
|
console.log('响应数据内容:', res.data);
|
|
|
|
|
|
if (res.statusCode == 200 || res.statusCode == "200") {
|
|
|
try {
|
|
|
// 尝试解析响应数据
|
|
|
let mod;
|
|
|
if (typeof res.data === 'string') {
|
|
|
mod = JSON.parse(res.data);
|
|
|
} else if (typeof res.data === 'object') {
|
|
|
mod = res.data;
|
|
|
} else {
|
|
|
throw new Error('响应数据格式不支持');
|
|
|
}
|
|
|
|
|
|
console.log('解析后的数据:', mod);
|
|
|
|
|
|
// 检查必要字段
|
|
|
if (!mod.id || !mod.public_path) {
|
|
|
console.log('响应数据缺少必要字段:', mod);
|
|
|
util.alert('签名上传失败:响应数据格式不完整');
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 直接设置签名ID和图片路径
|
|
|
switch(type) {
|
|
|
case 'paramedic':
|
|
|
that.paramedicSignId = mod.id;
|
|
|
that.paramedicSignImage = util.HOST + mod.public_path;
|
|
|
break;
|
|
|
case 'customer':
|
|
|
that.customerSignId = mod.id;
|
|
|
that.customerSignImage = util.HOST + mod.public_path;
|
|
|
break;
|
|
|
case 'company':
|
|
|
that.companySignId = mod.id;
|
|
|
that.companySignImage = util.HOST + mod.public_path;
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
callback(mod.id);
|
|
|
} catch (error) {
|
|
|
console.log('解析上传响应失败:', error);
|
|
|
console.log('原始响应数据:', res.data);
|
|
|
// util.alert('签名上传失败:响应格式错误 - ' + error.message);
|
|
|
}
|
|
|
} else {
|
|
|
console.log('签名上传失败,状态码:', res.statusCode);
|
|
|
util.alert('签名上传失败:' + res.statusCode);
|
|
|
}
|
|
|
},
|
|
|
fail(res) {
|
|
|
console.log('签名上传失败:', res);
|
|
|
util.alert('签名上传失败:网络错误');
|
|
|
}
|
|
|
});
|
|
|
};
|
|
|
|
|
|
if (typeof filePath === 'string' && filePath.startsWith('data:')) {
|
|
|
// 直接上传 dataURL
|
|
|
doUpload(filePath);
|
|
|
} else {
|
|
|
// 本地路径按原逻辑上传
|
|
|
doUpload(filePath);
|
|
|
}
|
|
|
},
|
|
|
|
|
|
// 提交协议
|
|
|
submitAgreement: function() {
|
|
|
var that = this;
|
|
|
|
|
|
// 检查必要参数
|
|
|
if (!that.paramedicSignId || !that.customerSignId || !that.companySignId) {
|
|
|
util.alert("请完成所有签名");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 检查是否有待提交的HTML内容,如果没有则提示
|
|
|
if (!that.pendingAgreementHtml && !that.agreementHtml) {
|
|
|
util.alert("请先预览协议");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 构建完整的HTML内容(如果还没有)
|
|
|
const html = that.pendingAgreementHtml || `<!DOCTYPE html>
|
|
|
<html>
|
|
|
<head>
|
|
|
<meta charset="utf-8">
|
|
|
<title>协议</title>
|
|
|
</head>
|
|
|
<body style="font-family: 'SimSun', 'Microsoft YaHei', 'WenQuanYi Zen Hei', sans-serif;">
|
|
|
${that.agreementHtml}
|
|
|
</body>
|
|
|
</html>`;
|
|
|
|
|
|
// 重置按钮状态
|
|
|
that.isGenerating = false;
|
|
|
that.generateButtonText = '直接提交';
|
|
|
|
|
|
util.request({
|
|
|
api: 'manager/create-order-agreements',
|
|
|
method: 'POST',
|
|
|
data: {
|
|
|
order_id: that.id,
|
|
|
paramedic_id: that.order.paramedic_id,
|
|
|
paramedic_sign_id: that.paramedicSignId,
|
|
|
customer_id: that.order.customer_id,
|
|
|
customer_sign_id: that.customerSignId,
|
|
|
// 后端若需要可传固定占位值
|
|
|
company_sign_id: that.companySignId || 'STATIC_COMPANY_SIGN',
|
|
|
html: html
|
|
|
},
|
|
|
utilSuccess: function(r) {
|
|
|
util.alert("协议签订成功");
|
|
|
uni.navigateTo({
|
|
|
url: "/pages/order/order"
|
|
|
});
|
|
|
},
|
|
|
utilFail: function(r) {
|
|
|
util.alert(r);
|
|
|
}
|
|
|
});
|
|
|
},
|
|
|
|
|
|
// 预览协议
|
|
|
previewAgreement: function() {
|
|
|
var that = this;
|
|
|
|
|
|
// 检查三个签名是否都已完成(公司签名固定,不再校验 companySignId)
|
|
|
if (!that.paramedicSignId || !that.customerSignId) {
|
|
|
util.alert('请先完成所有签名');
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 检查是否有协议内容
|
|
|
if (!that.order.project || !that.order.project.content) {
|
|
|
util.alert('还未上传协议,请联系管理员补充协议');
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 处理协议内容,替换占位符
|
|
|
that.processAgreementContent();
|
|
|
|
|
|
// 打开预览弹窗
|
|
|
that.$refs.agreementPopup.open();
|
|
|
},
|
|
|
|
|
|
// 关闭协议预览弹窗
|
|
|
closeAgreementPopup: function() {
|
|
|
this.$refs.agreementPopup.close();
|
|
|
},
|
|
|
|
|
|
// 处理协议内容,替换占位符
|
|
|
processAgreementContent: function() {
|
|
|
var that = this;
|
|
|
let content = that.order.project.content;
|
|
|
|
|
|
// 获取签名图片的样式(正向显示)
|
|
|
const getSignatureImgStyle = function(imagePath) {
|
|
|
if (!imagePath) return '';
|
|
|
|
|
|
// 统一使用正向显示,不进行旋转
|
|
|
return 'vertical-align: middle; display: inline-block; width: 50px; height: 20px; margin: 0 5px;';
|
|
|
};
|
|
|
|
|
|
// 定义占位符映射
|
|
|
const placeholders = {
|
|
|
'paramedic_sign': that.paramedicSignImage ? `<img src="${that.paramedicSignImage}" alt="护工签名" style="${getSignatureImgStyle(that.paramedicSignImage)}">` : '',
|
|
|
'customer_sign': that.customerSignImage ? `<img src="${that.customerSignImage}" alt="客户签名" style="${getSignatureImgStyle(that.customerSignImage)}">` : '',
|
|
|
'company_sign': `<img class="company-stamp" src="${that.companySignImage}" alt="公司签名" style="display: inline-block;width: 80px;height: 80px;position: relative;left: -150px;margin: 0 5px;vertical-align: middle;">`,
|
|
|
'manage_sign': `<img class="company-stamp" src="${that.companySignImage}" alt="公司签名" style="display: inline-block; width: 80px;height: 80px;position: relative;left: -150px;margin: 0 5px;vertical-align: middle;">`,
|
|
|
'paramedic_sign2': that.paramedicSignImage ? `<img src="${that.paramedicSignImage}" alt="护工签名" style="${getSignatureImgStyle(that.paramedicSignImage)} margin-right: 54px;">` : '',
|
|
|
'customer_sign2': that.customerSignImage ? `<img src="${that.customerSignImage}" alt="客户签名" style="${getSignatureImgStyle(that.customerSignImage)} margin-right: 54px;">` : '',
|
|
|
'manage_sign2': `<img class="company-stamp" src="${that.companySignImage}" alt="公司签名" style="display: inline-block; width: 80px;height: 80px;position: relative;left: -150px;vertical-align: middle; margin: 0 5px; margin-right: 54px;">`,
|
|
|
'paramedic_sign_id': that.paramedicSignId || '',
|
|
|
'customer_sign_id': that.customerSignId || '',
|
|
|
'company_sign_id': that.companySignId || 'STATIC_COMPANY_SIGN',
|
|
|
'days': that.order.days || '',
|
|
|
'price': that.order.price || '',
|
|
|
'total': that.order.total || '',
|
|
|
'range_mobile': (that.order.project && that.order.project.range_mobile) || '',
|
|
|
'complaint_mobile': (that.order.project && that.order.project.complaint_mobile) || '',
|
|
|
'today_date': (() => {
|
|
|
const today = new Date();
|
|
|
return today.getFullYear() + '年' + (today.getMonth() + 1) + '月' + today.getDate() + '日';
|
|
|
})()
|
|
|
};
|
|
|
|
|
|
// 替换所有占位符,包括被HTML标签包裹的情况
|
|
|
Object.keys(placeholders).forEach(key => {
|
|
|
// 匹配 {key} 或 {<span>key</span>} 等复杂情况
|
|
|
const regex = new RegExp(`\\{([^}]*${key}[^}]*)\\}`, 'g');
|
|
|
const matches = content.match(regex);
|
|
|
if (matches && matches.length > 0) {
|
|
|
content = content.replace(regex, placeholders[key]);
|
|
|
}
|
|
|
});
|
|
|
|
|
|
// 清理text-wrap-mode: nowrap样式
|
|
|
content = content.replace(/text-wrap-mode:\s*nowrap;?/gi, '');
|
|
|
content = content.replace(/text-wrap-mode:\s*nowrap/gi, '');
|
|
|
|
|
|
that.agreementHtml = content;
|
|
|
},
|
|
|
|
|
|
|
|
|
// 预览协议
|
|
|
previewAgreement: function() {
|
|
|
var that = this;
|
|
|
|
|
|
// 检查三个签名是否都已完成(公司签名固定,不再校验 companySignId)
|
|
|
if (!that.paramedicSignId || !that.customerSignId) {
|
|
|
util.alert('请先完成所有签名');
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 检查是否有协议内容
|
|
|
if (!that.order.project || !that.order.project.content) {
|
|
|
util.alert('还未上传协议,请联系管理员补充协议');
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 处理协议内容,替换占位符
|
|
|
that.processAgreementContent();
|
|
|
|
|
|
// 打开预览弹窗
|
|
|
that.$refs.agreementPopup.open();
|
|
|
},
|
|
|
|
|
|
}
|
|
|
}
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
::v-deep .nav{
|
|
|
z-index: 998 !important;
|
|
|
}
|
|
|
.content {
|
|
|
padding: 20rpx;
|
|
|
padding-bottom: 120rpx;
|
|
|
}
|
|
|
|
|
|
.pageTitle {
|
|
|
font-size: 32rpx;
|
|
|
font-weight: bold;
|
|
|
margin: 30rpx 0 20rpx 0;
|
|
|
color: #333;
|
|
|
}
|
|
|
|
|
|
.signatureBox {
|
|
|
background: #fff;
|
|
|
border-radius: 12rpx;
|
|
|
padding: 20rpx;
|
|
|
}
|
|
|
|
|
|
.signatureItem {
|
|
|
margin-bottom: 30rpx;
|
|
|
}
|
|
|
|
|
|
.signatureTitle {
|
|
|
font-size: 28rpx;
|
|
|
color: #333;
|
|
|
margin-bottom: 15rpx;
|
|
|
}
|
|
|
|
|
|
.signatureImage {
|
|
|
width: 100%;
|
|
|
height: 200rpx;
|
|
|
border: 1px solid #ddd;
|
|
|
border-radius: 8rpx;
|
|
|
background-color: #f9f9f9;
|
|
|
}
|
|
|
|
|
|
.signatureArea {
|
|
|
height: 200rpx;
|
|
|
border: 1px solid #ddd;
|
|
|
border-radius: 8rpx;
|
|
|
background-color: #fff;
|
|
|
position: relative;
|
|
|
display: flex;
|
|
|
justify-content: center;
|
|
|
}
|
|
|
|
|
|
.signatureStart {
|
|
|
height: 100%;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
color: #0DC99E;
|
|
|
font-size: 28rpx;
|
|
|
}
|
|
|
|
|
|
.signatureActions {
|
|
|
margin-top: 15rpx;
|
|
|
display: flex;
|
|
|
justify-content: space-between;
|
|
|
}
|
|
|
|
|
|
.btnClear, .btnSave, .btnResign {
|
|
|
padding: 10rpx 20rpx;
|
|
|
border-radius: 6rpx;
|
|
|
font-size: 24rpx;
|
|
|
}
|
|
|
|
|
|
.btnClear {
|
|
|
color: #666;
|
|
|
background: #f0f0f0;
|
|
|
}
|
|
|
|
|
|
.btnSave {
|
|
|
color: #fff;
|
|
|
background: #0DC99E;
|
|
|
}
|
|
|
|
|
|
.btnResign {
|
|
|
color: #fff;
|
|
|
background: #FF9500;
|
|
|
}
|
|
|
|
|
|
.previewSection {
|
|
|
margin-top: 30rpx;
|
|
|
padding: 20rpx;
|
|
|
background: #fff;
|
|
|
border-radius: 12rpx;
|
|
|
display: flex;
|
|
|
justify-content: center;
|
|
|
}
|
|
|
|
|
|
.previewBtn {
|
|
|
background-color: #0DC99E;
|
|
|
color: #fff;
|
|
|
padding: 10px 20px;
|
|
|
border-radius: 6px;
|
|
|
border: none;
|
|
|
font-size: 16px;
|
|
|
cursor: pointer;
|
|
|
margin-right: 10px;
|
|
|
}
|
|
|
|
|
|
.previewBtn:hover {
|
|
|
background-color: #0bb08a;
|
|
|
}
|
|
|
|
|
|
.agreementPreviewSection {
|
|
|
margin-top: 20px;
|
|
|
padding: 20px;
|
|
|
background-color: #f8f9fa;
|
|
|
border-radius: 8px;
|
|
|
z-index: 9999;
|
|
|
}
|
|
|
|
|
|
.sectionTitle {
|
|
|
font-size: 28rpx;
|
|
|
font-weight: bold;
|
|
|
color: #333;
|
|
|
margin-bottom: 15rpx;
|
|
|
}
|
|
|
|
|
|
.agreementImageContainer {
|
|
|
height: 300rpx;
|
|
|
display: flex;
|
|
|
justify-content: center;
|
|
|
align-items: center;
|
|
|
background-color: #f9f9f9;
|
|
|
border: 1px solid #ddd;
|
|
|
border-radius: 8rpx;
|
|
|
}
|
|
|
|
|
|
.agreementImage {
|
|
|
width: 100%;
|
|
|
height: 100%;
|
|
|
border-radius: 8rpx;
|
|
|
}
|
|
|
|
|
|
.agreementActions {
|
|
|
margin-top: 15rpx;
|
|
|
display: flex;
|
|
|
justify-content: flex-end;
|
|
|
}
|
|
|
|
|
|
.btnRegenerate {
|
|
|
padding: 10rpx 20rpx;
|
|
|
border-radius: 6rpx;
|
|
|
font-size: 24rpx;
|
|
|
color: #fff;
|
|
|
background: #FF9500;
|
|
|
}
|
|
|
|
|
|
/* 弹窗样式 */
|
|
|
.fullscreen-popup {
|
|
|
width: 100vw !important;
|
|
|
height: 100vh !important;
|
|
|
max-width: none !important;
|
|
|
left: 0 !important;
|
|
|
top: 0 !important;
|
|
|
transform: none !important;
|
|
|
}
|
|
|
|
|
|
/* 预览协议弹窗样式 */
|
|
|
.fullscreen-popup {
|
|
|
position: fixed;
|
|
|
top: 0;
|
|
|
left: 0;
|
|
|
width: 100%;
|
|
|
height: 100%;
|
|
|
background-color: rgba(0, 0, 0, 0.8);
|
|
|
z-index: 9999;
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
justify-content: center;
|
|
|
align-items: center;
|
|
|
/* 确保在移动设备上可以滚动 */
|
|
|
-webkit-overflow-scrolling: touch;
|
|
|
overflow: hidden;
|
|
|
}
|
|
|
|
|
|
/* 全屏签名弹窗内部 */
|
|
|
.signaturePopup {
|
|
|
width: 100vw;
|
|
|
height: 90vh;
|
|
|
background: #fff;
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
position: relative;
|
|
|
z-index: 9999;
|
|
|
}
|
|
|
|
|
|
.signatureWorkspace{display:flex;flex-direction:column;gap:20rpx;position:relative;height:100%;}
|
|
|
/* 下方按钮区域:横向排布 */
|
|
|
.signatureControlsRow{display:flex;align-items:center;justify-content:center;gap:20rpx;padding:20rpx 0;}
|
|
|
.btnRow{display:flex;align-items:center;justify-content:center;padding: 20rpx 40rpx;border-radius: 999rpx;text-align:center;font-size: 28rpx;min-width:120rpx;}
|
|
|
.btnRowClear{background:#f0f0f0;color:#333;border:2rpx solid #c84f3d;}
|
|
|
.btnRowSave{background:#0DC99E;color:#fff;}
|
|
|
.btnRowReset{background:#FFEFD9;color:#c84f3d;border:2rpx solid #f3c7a5;}
|
|
|
.signatureCanvasWrap{flex:1;}
|
|
|
.signatureCanvas {width: 100%;height: calc(100% - 100rpx)!important;background: #fff;border: 1px solid #eee;border-radius: 8rpx;}
|
|
|
|
|
|
/* 弹窗内提示,层级高于画布 */
|
|
|
.signatureInlineToast{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);background: rgba(0,0,0,0.75);color:#fff;padding: 16rpx 24rpx;border-radius: 10rpx;font-size: 26rpx;z-index: 10;}
|
|
|
|
|
|
.agreementPopup {
|
|
|
width: 100vw;
|
|
|
height: 100vh;
|
|
|
background: #fff;
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
position: relative;
|
|
|
z-index: 9999;
|
|
|
/* 微信浏览器滚动优化 */
|
|
|
-webkit-overflow-scrolling: touch;
|
|
|
overflow: hidden;
|
|
|
/* 确保在微信浏览器中正常显示 */
|
|
|
-webkit-transform: translateZ(0);
|
|
|
transform: translateZ(0);
|
|
|
/* 防止微信浏览器的滚动穿透 */
|
|
|
overscroll-behavior: contain;
|
|
|
}
|
|
|
|
|
|
.popupHeader {
|
|
|
display: flex;
|
|
|
justify-content: space-between;
|
|
|
align-items: center;
|
|
|
padding: 20rpx;
|
|
|
border-bottom: 1px solid #eee;
|
|
|
background: #f8f8f8;
|
|
|
flex-shrink: 0;
|
|
|
/* 确保头部固定 */
|
|
|
position: sticky;
|
|
|
top: 0;
|
|
|
z-index: 10;
|
|
|
}
|
|
|
|
|
|
.popupTitle {
|
|
|
font-size: 32rpx;
|
|
|
font-weight: bold;
|
|
|
color: #333;
|
|
|
}
|
|
|
|
|
|
.popupClose {
|
|
|
font-size: 40rpx;
|
|
|
color: #999;
|
|
|
cursor: pointer;
|
|
|
padding: 10rpx 15rpx;
|
|
|
background: #f0f0f0;
|
|
|
border-radius: 50%;
|
|
|
width: 60rpx;
|
|
|
height: 60rpx;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
transition: all 0.3s ease;
|
|
|
}
|
|
|
|
|
|
.popupClose:hover {
|
|
|
background: #e0e0e0;
|
|
|
color: #666;
|
|
|
}
|
|
|
|
|
|
.popupContent {
|
|
|
flex: 1;
|
|
|
height: calc(100vh - 120rpx); /* 减去头部和底部的高度 */
|
|
|
overflow-y: auto;
|
|
|
overflow-x: hidden;
|
|
|
padding: 20rpx;
|
|
|
/* 微信浏览器滚动优化 */
|
|
|
-webkit-overflow-scrolling: touch;
|
|
|
/* 允许触摸滚动 */
|
|
|
touch-action: pan-y;
|
|
|
/* 设置滚动条样式 */
|
|
|
scrollbar-width: thin;
|
|
|
scrollbar-color: #ccc transparent;
|
|
|
/* 微信浏览器特殊处理 */
|
|
|
position: relative;
|
|
|
/* 确保内容可以滚动 */
|
|
|
overscroll-behavior: contain;
|
|
|
}
|
|
|
|
|
|
/* Webkit浏览器的滚动条样式 */
|
|
|
.popupContent::-webkit-scrollbar {
|
|
|
width: 6px;
|
|
|
}
|
|
|
|
|
|
.popupContent::-webkit-scrollbar-track {
|
|
|
background: transparent;
|
|
|
}
|
|
|
|
|
|
.popupContent::-webkit-scrollbar-thumb {
|
|
|
background: #ccc;
|
|
|
border-radius: 3px;
|
|
|
}
|
|
|
|
|
|
.popupContent::-webkit-scrollbar-thumb:hover {
|
|
|
background: #999;
|
|
|
}
|
|
|
|
|
|
.agreementContent {
|
|
|
font-size: 28rpx;
|
|
|
line-height: 1.6;
|
|
|
color: #333;
|
|
|
word-wrap: break-word;
|
|
|
word-break: break-all;
|
|
|
overflow-wrap: break-word;
|
|
|
/* 确保在移动设备上内容可以正常显示和滚动 */
|
|
|
-webkit-text-size-adjust: 100%;
|
|
|
-ms-text-size-adjust: 100%;
|
|
|
text-size-adjust: 100%;
|
|
|
// height:100vh;
|
|
|
// overflow: scroll;
|
|
|
}
|
|
|
|
|
|
.agreementContent * {
|
|
|
max-width: 100% !important;
|
|
|
box-sizing: border-box !important;
|
|
|
/* 确保所有元素都能正常显示 */
|
|
|
word-wrap: break-word !important;
|
|
|
overflow-wrap: break-word !important;
|
|
|
}
|
|
|
|
|
|
.agreementContent img {
|
|
|
max-width: 50px !important;
|
|
|
height: 20px !important;
|
|
|
display: inline-block !important;
|
|
|
margin: 0 5px !important;
|
|
|
vertical-align: middle !important;
|
|
|
}
|
|
|
|
|
|
.agreementContent p, .agreementContent div {
|
|
|
margin: 10rpx 0 !important;
|
|
|
padding: 0 !important;
|
|
|
}
|
|
|
|
|
|
.agreementContent span {
|
|
|
word-break: break-all !important;
|
|
|
}
|
|
|
|
|
|
.noAgreement {
|
|
|
text-align: center;
|
|
|
padding: 40rpx;
|
|
|
color: #999;
|
|
|
font-size: 28rpx;
|
|
|
}
|
|
|
|
|
|
.popupFooter {
|
|
|
padding: 20rpx;
|
|
|
border-top: 1px solid #eee;
|
|
|
display: flex;
|
|
|
justify-content: center;
|
|
|
flex-shrink: 0;
|
|
|
/* 确保底部固定 */
|
|
|
position: sticky;
|
|
|
bottom: 0;
|
|
|
background: #fff;
|
|
|
z-index: 10;
|
|
|
}
|
|
|
|
|
|
.btnGenerate {
|
|
|
padding: 15rpx 30rpx;
|
|
|
border-radius: 8rpx;
|
|
|
font-size: 28rpx;
|
|
|
color: #fff;
|
|
|
background: #0DC99E;
|
|
|
}
|
|
|
|
|
|
.btnGenerate.disabled {
|
|
|
background-color: #ccc;
|
|
|
color: #666;
|
|
|
cursor: not-allowed;
|
|
|
}
|
|
|
|
|
|
.bottom {
|
|
|
background: #FFFFFF;
|
|
|
box-shadow: 0 -2rpx 12rpx 0 rgba(0, 0, 0, 0.16), inset 0 1rpx 0 0 #E4E4E4;
|
|
|
width: 100%;
|
|
|
height: 100rpx;
|
|
|
position: fixed;
|
|
|
bottom: 0;
|
|
|
left: 0;
|
|
|
display: flex;
|
|
|
justify-content: space-between;
|
|
|
}
|
|
|
|
|
|
.bottom .bottomLeft {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
}
|
|
|
|
|
|
.bottom .bottomRight {
|
|
|
display: flex;
|
|
|
flex: 1;
|
|
|
}
|
|
|
|
|
|
.btn {
|
|
|
width: 50%;
|
|
|
line-height: 100rpx;
|
|
|
text-align: center;
|
|
|
line-height: 100rpx;
|
|
|
font-family: SourceHanSansCN-Medium;
|
|
|
font-size: 32rpx;
|
|
|
letter-spacing: 0;
|
|
|
}
|
|
|
|
|
|
.btnCancel {
|
|
|
color: #666666;
|
|
|
background: #F0F0F0;
|
|
|
}
|
|
|
|
|
|
.btnSubmit {
|
|
|
color: #FFFFFF;
|
|
|
background: #0DC99E;
|
|
|
}
|
|
|
|
|
|
/* 移动设备优化 */
|
|
|
@media screen and (max-width: 768px) {
|
|
|
.agreementPopup {
|
|
|
width: 100vw;
|
|
|
height: 100vh;
|
|
|
max-height: 100vh;
|
|
|
}
|
|
|
|
|
|
.popupContent {
|
|
|
padding: 15rpx;
|
|
|
/* 移动设备上的滚动优化 */
|
|
|
-webkit-overflow-scrolling: touch;
|
|
|
overscroll-behavior: contain;
|
|
|
}
|
|
|
|
|
|
.agreementContent {
|
|
|
font-size: 26rpx;
|
|
|
line-height: 1.5;
|
|
|
}
|
|
|
|
|
|
.popupHeader {
|
|
|
padding: 15rpx;
|
|
|
}
|
|
|
|
|
|
.popupFooter {
|
|
|
padding: 15rpx;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* 小屏幕设备优化 */
|
|
|
@media screen and (max-width: 480px) {
|
|
|
.agreementContent {
|
|
|
font-size: 24rpx;
|
|
|
line-height: 1.4;
|
|
|
}
|
|
|
|
|
|
.popupContent {
|
|
|
padding: 10rpx;
|
|
|
}
|
|
|
|
|
|
.popupHeader {
|
|
|
padding: 10rpx;
|
|
|
}
|
|
|
|
|
|
.popupFooter {
|
|
|
padding: 10rpx;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* 微信浏览器特殊优化 */
|
|
|
@supports (-webkit-touch-callout: none) {
|
|
|
.popupContent {
|
|
|
/* 强制启用硬件加速 */
|
|
|
-webkit-transform: translateZ(0);
|
|
|
transform: translateZ(0);
|
|
|
/* 微信浏览器滚动优化 */
|
|
|
-webkit-overflow-scrolling: touch;
|
|
|
/* 防止滚动卡顿 */
|
|
|
will-change: scroll-position;
|
|
|
/* 确保内容可以滚动 */
|
|
|
overflow-y: auto;
|
|
|
height: calc(100vh - 120rpx);
|
|
|
}
|
|
|
|
|
|
.agreementPopup {
|
|
|
/* 防止微信浏览器的滚动穿透 */
|
|
|
position: fixed;
|
|
|
top: 0;
|
|
|
left: 0;
|
|
|
right: 0;
|
|
|
bottom: 0;
|
|
|
/* 微信浏览器特殊处理 */
|
|
|
-webkit-transform: translateZ(0);
|
|
|
transform: translateZ(0);
|
|
|
}
|
|
|
|
|
|
/* 微信浏览器中的滚动条优化 */
|
|
|
.popupContent::-webkit-scrollbar {
|
|
|
width: 4px;
|
|
|
}
|
|
|
|
|
|
.popupContent::-webkit-scrollbar-track {
|
|
|
background: transparent;
|
|
|
}
|
|
|
|
|
|
.popupContent::-webkit-scrollbar-thumb {
|
|
|
background: rgba(0, 0, 0, 0.3);
|
|
|
border-radius: 2px;
|
|
|
}
|
|
|
}
|
|
|
</style>
|