qa-prevention-gwj-first-app/pages/application/limit-space-affirm/limit-space-affirm-detail.vue

1424 lines
40 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<view :class="isUps == true ? 'prevent' : ''">
<cu-custom bgColor="bg-gradual-blueness" :isBack="true" >
<block slot="backText">返回</block>
<block slot="content">现场负责人确认</block>
</cu-custom>
<scroll-view scroll-y="false" >
<view class="form">
<!-- <view class="cu-form-textarea">
<view class="cu-form-title text-hui">检查内容</view>
<view class="f24 text-black">
{{pd.CHECK_CONTENT}}
</view>
</view> -->
<view class="de-card-list de-list">
<!-- <view class="de-title">
<text class="text-semi">隐患验收</text>
</view> -->
<view class="cu-form-group">
<view class="title">申请审批编号</view>
<input name="input" disabled v-model="pd.APPROVENUMBER" placeholder="请输入申请审批编号"></input>
</view>
<view class="cu-form-group">
<view class="title">有限空间名称</view>
<picker @change="limitspaceChange" disabled :value="lindex" :range="limitSpaceList" range-key="NAME">
<view class="picker">
{{pd.LIMITSPACENAME?pd.LIMITSPACENAME:'请选择'}}
</view>
</picker>
</view>
<view class="cu-form-group">
<view class="title">作业单位</view>
<input name="input" disabled v-model="pd.UNIT" placeholder="请输入作业单位"></input>
</view>
<view class="cu-form-group">
<view class="title">作业内容</view>
<input name="input" disabled v-model="pd.CONTONT" placeholder="请输入作业内容"></input>
</view>
<view class="cu-form-group bb">
<view class="title">作业开始时间</view>
<picker mode="date" disabled :value="pd.STARTTIME" @change="changeStartDate">
<view class="picker">
{{pd.STARTTIME?pd.STARTTIME:'请选择'}}
</view>
</picker>
</view>
<view class="cu-form-group bb">
<view class="title">作业结束时间</view>
<picker mode="date" disabled :value="pd.ENDTIME" @change="changeEndDate">
<view class="picker">
{{pd.ENDTIME?pd.ENDTIME:'请选择'}}
</view>
</picker>
</view>
<view class="cu-form-textarea bb-default" style="border-top: 1upx solid #eee;" >
<view class="cu-form-title" >可能存在风险及有害因素</view>
<textarea maxlength="-1" disabled v-model="pd.HARMFULFACTOR" placeholder="请输入可能存在风险及有害因素"></textarea>
</view>
<view class="cu-form-group ">
<view class="title">作业负责人</view>
<input name="input" disabled="true" v-model="pd.PRINCIPALNAME" placeholder="请输入作业负责人"></input>
</view>
<view class="cu-form-group ">
<view class="title">监护人员</view>
<picker @change="guardianChange" disabled :value="gindex" :range="userList" range-key="USERNAME">
<view class="picker">
{{pd.GUARDIANNAME?pd.GUARDIANNAME:'请选择'}}
</view>
</picker>
</view>
<view class="cu-form-group ">
<view class="title">作业人员</view>
<input name="input" disabled v-model="pd.WORKER" placeholder="请输入作业人员"></input>
</view>
<view class="cu-form-group ">
<view class="title">其他人员</view>
<input name="input" disabled v-model="pd.OTHERPERSON" placeholder="请输入其他人员"></input>
</view>
</view>
<view class="de-card-list de-list">
<view class="de-title">
<text class="text-semi">主要安全防护措施</text>
</view>
<view class="cu-form-group ">
<view class="title text-hui">制定有限空间作业方案并经审核、批准</view>
<view class="select">
<view class="flex align-center">
<radio class='mr10' disabled :checked="pd.ISFLOW==1" @change="isflowClick(pd.ISFLOW)"></radio>
</view>
</view>
</view>
<view class="cu-form-group " style="height: 150upx;">
<view class="title text-hui" style="height: auto;line-height: 24px;">参加作业人员经有限空间作业安全相关培训合格</view>
<view class="select">
<view class="flex align-center">
<radio class='mr10' disabled :checked="pd.ISTRAIN==1" @change="istrainClick(pd.ISTRAIN)"></radio>
</view>
</view>
</view>
<view class="cu-form-group " style="height: 150upx;">
<view class="title text-hui" style="height: auto;line-height: 24px;">安全防护设备、个体防护用品、作业设备和工具齐全有效、满足要求</view>
<view class="select">
<view class="flex align-center">
<radio class='mr10' disabled :checked="pd.ISEQUIPMENT==1" @change="isequipmentClick(pd.ISEQUIPMENT)"></radio>
</view>
</view>
</view>
<view class="cu-form-group ">
<view class="title text-hui">应急救援装备满足要求</view>
<view class="select">
<view class="flex align-center">
<radio class='mr10' disabled :checked="pd.ISRESCUE==1" @change="isrescueClick(pd.ISRESCUE)"></radio>
</view>
</view>
</view>
<view class="cu-form-group " style="border-bottom: 1upx solid #eee;" >
<view class="title">审批负责人</view>
<picker @change="approverChange" disabled :value="aindex" :range="userList" range-key="USERNAME">
<view class="picker">
{{pd.APPROVERNAME?pd.APPROVERNAME:'请选择'}}
</view>
</picker>
</view>
<view class="" style="border-bottom: 1upx solid #eee;" >
<view class="cu-form-group">
<view class="cu-form-title" >现场作业负责人意见</view>
<radio-group class="selected" @change="radioType" :disabled="forbidEdit">
<view class="group mr20">
<radio class='radio' :disabled="forbidEdit" value="1" :checked="pd.SITEOPINION==1"></radio>
<text>符合</text>
</view>
<view class="group">
<radio class='radio' :disabled="forbidEdit" value="0" :checked="pd.SITEOPINION==0"></radio>
<text>不符合</text>
</view>
</radio-group>
</view>
<view class="cu-tip" >*现场作业负责人确认以上安全防护措施是否符合要求</view>
</view>
<view class="cu-form-group" v-show="pd.SITEOPINION=='1'">
<view class="title">现场作业负责人签字</view>
<button class="cu-btn bg-green shadow" :disabled="forbidEdit" @tap="showModal" data-target="Modal">手写签字</button>
</view>
<view class="cu-bar bg-white" v-show="imgList && imgList.length > 0">
<view class="action">
签字照片
</view>
<!-- <view class="action">
{{imgList.length}}/4
</view> -->
</view>
<view class="cu-form-group" v-show="imgList && imgList.length > 0">
<view class="grid col-4 grid-square flex-sub">
<view style="width: 60%;" class="bg-img" v-for="(item,index) in imgList" :key="index" @tap="ViewImage" data-type="0" :data-url="imgList[index].filePath">
<image :src="imgList[index].filePath" mode="aspectFill"></image>
<view class="cu-tag bg-red" v-show="!forbidEdit" @tap.stop="DelImg" data-type="0" :data-index="index">
<text class='cuIcon-close'></text>
</view>
</view>
</view>
</view>
<view class="cu-modal" :class="modalName=='Modal'?'show':''">
<view class="cu-dialog">
<view class="cu-bar bg-white justify-end">
<view class="content">签名</view>
<view class="action" @tap="hideModal">
<text class="cuIcon-close text-red"></text>
</view>
</view>
<view>
<view class="wrapper">
<view class="handCenter">
<canvas
class="handWriting"
:disable-scroll="true"
@touchstart="uploadScaleStart"
@touchmove="uploadScaleMove"
@touchend="uploadScaleEnd"
canvas-id="handWriting"
></canvas>
</view>
<!-- <view class="handBtn">
<image
@click="selectColorEvent('black','#1A1A1A')"
:src="selectColor === 'black' ? '/static/color_black_selected.png' : '/static/color_black.png'"
:class="[selectColor === 'black' ? 'color_select' : '', 'black-select']"
></image>
<image
@click="selectColorEvent('red','#ca262a')"
:src="selectColor === 'red' ? '/static/color_red_selected.png' : '/static/color_red.png'"
:class="[selectColor === 'red' ? 'color_select' : '', 'black-select']"
></image>
<button @click="retDraw" class="delBtn">重写</button>
<button @click="subCanvas" class="subBtn">完成</button>
</view> -->
</view>
</view>
<view class="cu-bar bg-white justify-end">
<view class="action">
<button class="cu-btn line-green text-green" @click="retDraw">重写</button>
<button class="cu-btn bg-green margin-left" @click="subCanvas" >完成</button>
</view>
</view>
</view>
</view>
</view>
</view>
<view class="padding flex flex-direction">
<button v-if="!forbidEdit" class="cu-btn bg-blue margin-tb-sm lg" @click="$noMultipleClicks(goSubmit)"></button>
</view>
</scroll-view>
</view>
</template>
<script>
import {
basePath,corpinfoId,deptId,loginUser,formatDate,loginSession,baseImgPath
} from '@/common/tool.js';
import tkiTree from "@/components/select-tree/select-tree.vue"
import gcoord from '@/common/gcoord.js'
export default {
components: {
tkiTree
},
data() {
return {
isUps:false,
msg:'add',
riskId:'',
itemId:'',
index:'',
noClick:true,
limitSpaceList:[],
pd:{
ISFLOW:0,
ISTRAIN:0,
ISEQUIPMENT:0,
ISRESCUE:0,
},// 数据
aindex:-1,
userList:[],//用户列表
sindex:-1,
lindex:-1,
gindex:-1,
todayDate:'',
forbidEdit:true,// 禁止修改
jcuserList:[],// 检测人员可选
iindex:-1,
modalName:null,
imgList:[],
//手写板
canvasName: 'handWriting',
ctx: '',
canvasWidth: 0,
canvasHeight: 0,
transparent: 1, // 透明度
selectColor: 'black',
lineColor: '#1A1A1A', // 颜色
lineSize: 1.5, // 笔记倍数
lineMin: 0.5, // 最小笔画半径
lineMax: 4, // 最大笔画半径
pressure: 1, // 默认压力
smoothness: 60, //顺滑度用60的距离来计算速度
currentPoint: {},
currentLine: [], // 当前线条
firstTouch: true, // 第一次触发
radius: 1, //画圆的半径
cutArea: { top: 0, right: 0, bottom: 0, left: 0 }, //裁剪区域
bethelPoint: [], //保存所有线条 生成的贝塞尔点;
lastPoint: 0,
chirography: [], //笔迹
currentChirography: {}, //当前笔迹
linePrack: [], //划线轨迹 , 生成线条的实际点
}
},
onLoad(event){
var _this = this;
this.todayDate = formatDate(new Date(), 'yyyy-MM-dd');
this.pd.LIMITSPACEAPPROVE_ID = event.LIMITSPACEAPPROVE_ID;
if(this.pd.LIMITSPACEAPPROVE_ID){
this.msg="edit";
this.getData();
}else {
// 初始化作业负责人
this.pd.PRINCIPAL = loginUser.USER_ID;
this.pd.PRINCIPALNAME = loginUser.NAME;
this.forbidEdit = false;
this.jcuserList.push({"USER_ID":loginUser.USER_ID,"USERNAME":loginUser.NAME});
}
// 初始化现场作业负责人
this.pd.SITESUPERVISOR = this.pd.PRINCIPAL;
this.pd.SITESUPERVISORNAME = this.pd.PRINCIPALNAME;
this.getDict();
this.getUserList();
this.getLimitSpace();
loginSession();
//手写板
let canvasName = this.canvasName;
let ctx = uni.createCanvasContext(canvasName);
this.ctx = ctx;
var query = uni.createSelectorQuery();
query
.select('.handCenter')
.boundingClientRect(rect => {
this.canvasWidth = rect.width;
this.canvasHeight = rect.height;
/* 将canvas背景设置为 白底,不设置 导出的canvas的背景为透明 */
this.setCanvasBg('#fff');
})
.exec();
},
methods: {
showModal(e) {
this.modalName = e.currentTarget.dataset.target
},
getData() {
var _this = this;
uni.showLoading({
title: '请稍候'
})
uni.request({
url: basePath + '/app/limitspaceapprove/goEdit',
method: 'POST',
dataType: 'json',
header: {
'Content-type': 'application/x-www-form-urlencoded'
},
data: {
LIMITSPACEAPPROVE_ID: _this.pd.LIMITSPACEAPPROVE_ID,
},
success: (res) => {
if ("success" == res.data.result) {
uni.hideLoading();
_this.pd = res.data.pd; //参数map
if(_this.pd.STATUS =='2'){
_this.forbidEdit = false;
}
let files=res.data.qrImgs;
for(var i=0;i<files.length;i++){
let img={};
img.filePath=baseImgPath+files[i].FILEPATH;
img.id=files[i].IMGFILES_ID;
_this.imgList.push(img);
}
this.jcuserList.push({"USER_ID":res.data.pd.SITESUPERVISOR,"USERNAME":res.data.pd.SITESUPERVISORNAME});
this.jcuserList.push({"USER_ID":res.data.pd.GUARDIAN,"USERNAME":res.data.pd.GUARDIANNAME});
} else if ("exception" == data.result) {
uni.showToast({
title: '',
duration: 2000
});
}
}
});
},
//
getDict: function () {
var _this = this;
uni.request({
method: 'POST',
dataType: 'json',
header: {
'Content-type': 'application/x-www-form-urlencoded'
},
url: basePath + '/dictionaries/getLevels?tm=' + new Date().getTime(),
data: {DICTIONARIES_ID: 'dad23a464729485ba364994942db83cc'},
dataType: 'json',
success: function (res) {
_this.finiteSpaceList = res.data.list;
}
});
uni.request({
method: 'POST',
dataType: 'json',
header: {
'Content-type': 'application/x-www-form-urlencoded'
},
url: basePath + '/dictionaries/getLevels?tm=' + new Date().getTime(),
data: {DICTIONARIES_ID: 'a178357ce6ce4d6a9ac95def6aca3a14'},
dataType: 'json',
success: function (res) {
_this.riskGradeList = res.data.list;
}
});
},
//
getUserList(){
var _this = this;
uni.request({
method: 'POST',
dataType: 'json',
header: {
'Content-type': 'application/x-www-form-urlencoded'
},
url: basePath + '/app/user/listUserByCorp?tm=' + new Date().getTime(),
data: {CORPINFO_ID: corpinfoId},
dataType: 'json',
success: function (res) {
_this.userList = res.data.userList;
}
});
},
//
getLimitSpace(){
var _this = this;
uni.request({
method: 'POST',
dataType: 'json',
header: {
'Content-type': 'application/x-www-form-urlencoded'
},
url: basePath + '/app/limitspace/listAllSpace?tm=' + new Date().getTime(),
data: {CORPINFO_ID: corpinfoId},
dataType: 'json',
success: function (res) {
_this.limitSpaceList = res.data.varList;
}
});
},
guardianChange(e){
this.gindex = e.detail.value;
this.pd.GUARDIAN=this.userList[this.gindex].USER_ID;
this.pd.GUARDIANNAME=this.userList[this.gindex].USERNAME; //
this.jcuserList.splice(0,this.jcuserList.length);
if(this.pd.SITESUPERVISOR != this.pd.GUARDIAN){
this.jcuserList.push({"USER_ID":this.pd.SITESUPERVISOR,"USERNAME":this.pd.SITESUPERVISORNAME});
this.jcuserList.push({"USER_ID":this.pd.GUARDIAN,"USERNAME":this.pd.GUARDIANNAME});
} else {
this.jcuserList.push({"USER_ID":this.pd.GUARDIAN,"USERNAME":this.pd.GUARDIANNAME});
}
this.pd.INSPECTOR = '';
this.pd.INSPECTORNAME = '';
this.iindex = -1;
this.$forceUpdate();//
},
sitesupervisorChange(e){
this.sindex = e.detail.value;
this.pd.SITESUPERVISOR=this.userList[this.sindex].USER_ID;
this.pd.SITESUPERVISORNAME=this.userList[this.sindex].USERNAME;
this.jcuserList.splice(0,this.jcuserList.length);
if(this.pd.SITESUPERVISOR != this.pd.GUARDIAN){
this.jcuserList.push({"USER_ID":this.pd.SITESUPERVISOR,"USERNAME":this.pd.SITESUPERVISORNAME});
this.jcuserList.push({"USER_ID":this.pd.GUARDIAN,"USERNAME":this.pd.GUARDIANNAME});
} else {
this.jcuserList.push({"USER_ID":this.pd.GUARDIAN,"USERNAME":this.pd.GUARDIANNAME});
}
//
this.pd.INSPECTOR = '';
this.pd.INSPECTORNAME = '';
this.iindex = -1;
this.$forceUpdate();//
},
approverChange(e){
this.aindex = e.detail.value;
this.pd.APPROVER=this.userList[this.aindex].USER_ID;
this.pd.APPROVERNAME=this.userList[this.aindex].USERNAME;
this.$forceUpdate();//
},
limitspaceChange(e){
this.lindex = e.detail.value;
this.pd.LIMITSPACE_ID=this.limitSpaceList[this.lindex].LIMITSPACE_ID;
this.pd.LIMITSPACENAME=this.limitSpaceList[this.lindex].NAME;
this.$forceUpdate();//
},
inspectorChange(e){
this.iindex = e.detail.value;
this.pd.INSPECTOR=this.jcuserList[this.iindex].USER_ID;
this.pd.INSPECTORNAME=this.jcuserList[this.iindex].USERNAME;
this.$forceUpdate();//
},
isflowClick(e){
if(e==1){
this.pd.ISFLOW = 0;
} else if(e==0){
this.pd.ISFLOW = 1;
}
},
istrainClick(e){
if(e==1){
this.pd.ISTRAIN = 0;
} else if(e==0){
this.pd.ISTRAIN = 1;
}
},
isequipmentClick(e){
if(e==1){
this.pd.ISEQUIPMENT = 0;
} else if(e==0){
this.pd.ISEQUIPMENT = 1;
}
},
isrescueClick(e){
if(e==1){
this.pd.ISRESCUE = 0;
} else if(e==0){
this.pd.ISRESCUE = 1;
}
},
isPosInt(){
if(!/^[1-9]\d*$/.test(this.pd.MAXPERSON)){
uni.showToast({
icon: 'none',
title: '',
duration: 1500
});
}
},
changeStartDate(e) {
this.pd.STARTTIME = e.detail.value
this.$forceUpdate();//
},
changeEndDate(e) {
this.pd.ENDTIME = e.detail.value
this.$forceUpdate();//
},
goSubmit() {
var _this = this;
uni.showLoading({
title: ''
})
console.info(_this.pd.SITEOPINION);
if (!_this.pd.SITEOPINION) {
uni.showToast({
icon: 'none',
title: '',
duration: 1500
});
return;
}
if(this.pd.SITEOPINION=='1'){
if (_this.imgList.length <= 0) {
uni.showToast({
icon: 'none',
title: '',
duration: 1500
});
return;
}
}
var fileList = [];
for (var i = 0; i < _this.imgList.length; i++) {
if(!_this.imgList[i].id){
var file = {};
file.type = 9;
file.filePath = _this.imgList[i].filePath;
fileList.push(file);
}
}
new Promise((resolve, reject) => {
_this.submit().then(() => {resolve();})
}).then(() => {
var i=0;
_this.uploadImg(fileList,i).then(() => {resolve();})
}).then(() => {
uni.showToast({
icon:'none',
title: '保存成功',
duration: 2000
});
var pages = getCurrentPages(); // 获取当前页面栈
var prePage = pages[pages.length - 2]; // 上一个页面
// var task = prePage.$vm.list[_this.index];
if(_this.index) {
prePage.$vm.initflag = true; // A 页面 init方法 为true
// prePage.$vm.list[_this.index].ISNORMAL = 1;
// prePage.$vm.list[_this.index].HIDDEN_ID = _this.pd.HIDDEN_ID;
}
uni.navigateBack({});
uni.hideLoading();
})
},
submit(){
return new Promise((resolve, reject) => {
var status = 3;
if(this.pd.SITEOPINION == '0'){
status = 6;
}
uni.request({
url: basePath+'/app/limitspaceapprove/editStatus',
method: 'POST',
dataType: 'json',
header: {
'Content-type':'application/x-www-form-urlencoded'
},
data: {
LIMITSPACEAPPROVE_ID:this.pd.LIMITSPACEAPPROVE_ID,
SITEOPINION:this.pd.SITEOPINION,
SITEOPINIONTIME: this.todayDate,
STATUS:status,
CORPINFO_ID:corpinfoId,
USER:loginUser.USER_ID,
},
success: (res) => {
uni.hideLoading();
if ("success" == res.data.result) {
resolve();
}else{
uni.showToast({
icon:'none',
title: '系统错误',
duration: 2000
});
}
}
});
});
},
uploadImg(tempFilePaths,i){
return new Promise((resolve, reject) => {
var _this = this;
if(tempFilePaths.length==0){
resolve();
}
uni.showLoading({
title: '上传中'
})
uni.uploadFile({
url: basePath+'/app/imgfiles/add',
filePath: tempFilePaths[i].filePath,
name: 'FFILE',
formData: {
'TYPE': tempFilePaths[i].type,
'FOREIGN_KEY': _this.pd.LIMITSPACEAPPROVE_ID
},
success: (res) => {
i++;
if (tempFilePaths.length > i) {
_this.uploadImg(tempFilePaths, i);
} else {
uni.hideLoading();
resolve();
}
},
fail: (err) => {
uni.hideLoading();
uni.showModal({
content: err.errMsg,
showCancel: false
});
}
})
})
},
radioType(e){
this.pd.SITEOPINION = e.detail.value
if(this.pd.SITEOPINION=='0'){
this.imgList.splice(0,this.imgList.length);
}
this.$forceUpdate();//强制刷新
},
goToEdit(){
this.forbidEdit = false;
},
// 笔迹开始
uploadScaleStart(e) {
if (e.type != 'touchstart') return false;
let ctx = this.ctx;
ctx.setFillStyle(this.lineColor); // 初始线条设置颜色
ctx.setGlobalAlpha(this.transparent); // 设置半透明
let currentPoint = {
x: e.touches[0].x,
y: e.touches[0].y
};
let currentLine = this.currentLine;
currentLine.unshift({
time: new Date().getTime(),
dis: 0,
x: currentPoint.x,
y: currentPoint.y
});
this.currentPoint = currentPoint;
// currentLine
if (this.firstTouch) {
this.cutArea = { top: currentPoint.y, right: currentPoint.x, bottom: currentPoint.y, left: currentPoint.x };
this.firstTouch = false;
}
this.pointToLine(currentLine);
},
//图片上传
ChooseImage(e) {
var _this = this;
var ss=4-this.imgList.length;
uni.chooseImage({
count: ss, //默认9
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
sourceType: ['camera','album'], //从相册选择
success: (res) => {
if(e==0) {
let img={};
img.id='';
img.filePath=res.tempFilePaths[0];
this.imgList.push(img)
}else{
let img={};
img.id='';
img.filePath=res.tempFilePaths[0];
this.imgList1.push(img)
}
}
});
},
ViewImage(e) {
console.info(e.currentTarget.dataset.type)
if(e.currentTarget.dataset.type==0) {
let files =[];
for(var i=0;i<this.imgList.length;i++){
files.push(this.imgList[i].filePath)
}
uni.previewImage({
urls: files,
current: e.currentTarget.dataset.url
});
}else{
let files =[];
for(var i=0;i<this.imgList1.length;i++){
files.push(this.imgList1[i].filePath)
}
uni.previewImage({
urls: files,
current: e.currentTarget.dataset.url
});
}
},
DelImg(e) {
var _this = this;
let i=e.currentTarget.dataset.index
uni.showModal({
title: '',
content: '',
cancelColor:"#000000",
cancelText: '',
confirmText: '',
success: res => {
if (res.confirm) {
if(e.currentTarget.dataset.type==0) {
if(_this.imgList[i].id) {
uni.showLoading({
title: '处理中'
})
uni.request({
url: basePath+'/app/imgfiles/delete',
method: 'POST',
dataType: 'json',
header: {
'Content-type':'application/x-www-form-urlencoded'
},
data: {
IMGFILES_ID: _this.imgList[i].id,
},
success: (res) => {
uni.hideLoading();
uni.showToast({
icon: 'none',
title: '删除成功',
duration: 1500
});
_this.imgList.splice(i, 1)
},
fail: (err) => {
uni.hideLoading();
uni.showModal({
content: err.errMsg,
showCancel: false
});
}
})
}else {
this.imgList.splice(e.currentTarget.dataset.index, 1)
}
}else{
if(_this.imgList1[i].id) {
uni.showLoading({
title: '处理中'
})
uni.request({
url: basePath+'/app/imgfiles/delete',
method: 'POST',
dataType: 'json',
header: {
'Content-type':'application/x-www-form-urlencoded'
},
data: {
IMGFILES_ID: _this.imgList1[i].id,
},
success: (res) => {
uni.hideLoading();
uni.showToast({
icon: 'none',
title: '删除成功',
duration: 1500
});
_this.imgList1.splice(i, 1)
},
fail: (err) => {
uni.hideLoading();
uni.showModal({
content: err.errMsg,
showCancel: false
});
}
})
}else {
this.imgList1.splice(e.currentTarget.dataset.index, 1)
}
}
}
}
})
},
hideModal(e) {
this.modalName = null
},
// 笔迹移动
uploadScaleMove(e) {
if (e.type != 'touchmove') return false;
if (e.cancelable) {
// 判断默认行为是否已经被禁用
if (!e.defaultPrevented) {
e.preventDefault();
}
}
let point = {
x: e.touches[0].x,
y: e.touches[0].y
};
//测试裁剪
if (point.y < this.cutArea.top) {
this.cutArea.top = point.y;
}
if (point.y < 0) this.cutArea.top = 0;
if (point.x > this.cutArea.right) {
this.cutArea.right = point.x;
}
if (this.canvasWidth - point.x <= 0) {
this.cutArea.right = this.canvasWidth;
}
if (point.y > this.cutArea.bottom) {
this.cutArea.bottom = point.y;
}
if (this.canvasHeight - point.y <= 0) {
this.cutArea.bottom = this.canvasHeight;
}
if (point.x < this.cutArea.left) {
this.cutArea.left = point.x;
}
if (point.x < 0) this.cutArea.left = 0;
this.lastPoint = this.currentPoint;
this.currentPoint = point;
let currentLine = this.currentLine;
currentLine.unshift({
time: new Date().getTime(),
dis: this.distance(this.currentPoint, this.lastPoint),
x: point.x,
y: point.y
});
this.pointToLine(currentLine);
},
// 笔迹结束
uploadScaleEnd(e) {
if (e.type != 'touchend') return 0;
let point = {
x: e.changedTouches[0].x,
y: e.changedTouches[0].y
};
this.lastPoint = this.currentPoint;
this.currentPoint = point;
let currentLine = this.currentLine;
currentLine.unshift({
time: new Date().getTime(),
dis: this.distance(this.currentPoint, this.lastPoint),
x: point.x,
y: point.y
});
if (currentLine.length > 2) {
var info = (currentLine[0].time - currentLine[currentLine.length - 1].time) / currentLine.length;
//$("#info").text(info.toFixed(2));
}
//一笔结束,保存笔迹的坐标点,清空,当前笔迹
//增加判断是否在手写区域;
this.pointToLine(currentLine);
var currentChirography = {
lineSize: this.lineSize,
lineColor: this.lineColor
};
var chirography = this.chirography;
chirography.unshift(currentChirography);
this.chirography = chirography;
var linePrack = this.linePrack;
linePrack.unshift(this.currentLine);
this.linePrack = linePrack;
this.currentLine = [];
},
retDraw() {
this.ctx.clearRect(0, 0, 700, 730);
this.ctx.draw();
//设置canvas背景
this.setCanvasBg('#fff');
},
//画两点之间的线条;参数为:line会绘制最近的开始的两个点
pointToLine(line) {
this.calcBethelLine(line);
return;
},
//计算插值的方式;
calcBethelLine(line) {
if (line.length <= 1) {
line[0].r = this.radius;
return;
}
let x0,
x1,
x2,
y0,
y1,
y2,
r0,
r1,
r2,
len,
lastRadius,
dis = 0,
time = 0,
curveValue = 0.5;
if (line.length <= 2) {
x0 = line[1].x;
y0 = line[1].y;
x2 = line[1].x + (line[0].x - line[1].x) * curveValue;
y2 = line[1].y + (line[0].y - line[1].y) * curveValue;
//x2 = line[1].x;
//y2 = line[1].y;
x1 = x0 + (x2 - x0) * curveValue;
y1 = y0 + (y2 - y0) * curveValue;
} else {
x0 = line[2].x + (line[1].x - line[2].x) * curveValue;
y0 = line[2].y + (line[1].y - line[2].y) * curveValue;
x1 = line[1].x;
y1 = line[1].y;
x2 = x1 + (line[0].x - x1) * curveValue;
y2 = y1 + (line[0].y - y1) * curveValue;
}
//从计算公式看,三个点分别是(x0,y0),(x1,y1),(x2,y2) (x1,y1)这个是控制点,控制点不会落在曲线上;实际上,这个点还会手写获取的实际点,却落在曲线上
len = this.distance({ x: x2, y: y2 }, { x: x0, y: y0 });
lastRadius = this.radius;
for (let n = 0; n < line.length - 1; n++) {
dis += line[n].dis;
time += line[n].time - line[n + 1].time;
if (dis > this.smoothness) break;
}
this.radius = Math.min((time / len) * this.pressure + this.lineMin, this.lineMax) * this.lineSize;
line[0].r = this.radius;
//计算笔迹半径;
if (line.length <= 2) {
r0 = (lastRadius + this.radius) / 2;
r1 = r0;
r2 = r1;
//return;
} else {
r0 = (line[2].r + line[1].r) / 2;
r1 = line[1].r;
r2 = (line[1].r + line[0].r) / 2;
}
let n = 5;
let point = [];
for (let i = 0; i < n; i++) {
let t = i / (n - 1);
let x = (1 - t) * (1 - t) * x0 + 2 * t * (1 - t) * x1 + t * t * x2;
let y = (1 - t) * (1 - t) * y0 + 2 * t * (1 - t) * y1 + t * t * y2;
let r = lastRadius + ((this.radius - lastRadius) / n) * i;
point.push({ x: x, y: y, r: r });
if (point.length == 3) {
let a = this.ctaCalc(point[0].x, point[0].y, point[0].r, point[1].x, point[1].y, point[1].r, point[2].x, point[2].y, point[2].r);
a[0].color = this.lineColor;
// let bethelPoint = this.bethelPoint;
// bethelPoint = bethelPoint.push(a);
this.bethelDraw(a, 1);
point = [{ x: x, y: y, r: r }];
}
}
this.currentLine = line;
},
//求两点之间距离
distance(a, b) {
let x = b.x - a.x;
let y = b.y - a.y;
return Math.sqrt(x * x + y * y);
},
ctaCalc(x0, y0, r0, x1, y1, r1, x2, y2, r2) {
let a = [],
vx01,
vy01,
norm,
n_x0,
n_y0,
vx21,
vy21,
n_x2,
n_y2;
vx01 = x1 - x0;
vy01 = y1 - y0;
norm = Math.sqrt(vx01 * vx01 + vy01 * vy01 + 0.0001) * 2;
vx01 = (vx01 / norm) * r0;
vy01 = (vy01 / norm) * r0;
n_x0 = vy01;
n_y0 = -vx01;
vx21 = x1 - x2;
vy21 = y1 - y2;
norm = Math.sqrt(vx21 * vx21 + vy21 * vy21 + 0.0001) * 2;
vx21 = (vx21 / norm) * r2;
vy21 = (vy21 / norm) * r2;
n_x2 = -vy21;
n_y2 = vx21;
a.push({ mx: x0 + n_x0, my: y0 + n_y0, color: '#1A1A1A' });
a.push({ c1x: x1 + n_x0, c1y: y1 + n_y0, c2x: x1 + n_x2, c2y: y1 + n_y2, ex: x2 + n_x2, ey: y2 + n_y2 });
a.push({ c1x: x2 + n_x2 - vx21, c1y: y2 + n_y2 - vy21, c2x: x2 - n_x2 - vx21, c2y: y2 - n_y2 - vy21, ex: x2 - n_x2, ey: y2 - n_y2 });
a.push({ c1x: x1 - n_x2, c1y: y1 - n_y2, c2x: x1 - n_x0, c2y: y1 - n_y0, ex: x0 - n_x0, ey: y0 - n_y0 });
a.push({ c1x: x0 - n_x0 - vx01, c1y: y0 - n_y0 - vy01, c2x: x0 + n_x0 - vx01, c2y: y0 + n_y0 - vy01, ex: x0 + n_x0, ey: y0 + n_y0 });
a[0].mx = a[0].mx.toFixed(1);
a[0].mx = parseFloat(a[0].mx);
a[0].my = a[0].my.toFixed(1);
a[0].my = parseFloat(a[0].my);
for (let i = 1; i < a.length; i++) {
a[i].c1x = a[i].c1x.toFixed(1);
a[i].c1x = parseFloat(a[i].c1x);
a[i].c1y = a[i].c1y.toFixed(1);
a[i].c1y = parseFloat(a[i].c1y);
a[i].c2x = a[i].c2x.toFixed(1);
a[i].c2x = parseFloat(a[i].c2x);
a[i].c2y = a[i].c2y.toFixed(1);
a[i].c2y = parseFloat(a[i].c2y);
a[i].ex = a[i].ex.toFixed(1);
a[i].ex = parseFloat(a[i].ex);
a[i].ey = a[i].ey.toFixed(1);
a[i].ey = parseFloat(a[i].ey);
}
return a;
},
bethelDraw(point, is_fill, color) {
let ctx = this.ctx;
ctx.beginPath();
ctx.moveTo(point[0].mx, point[0].my);
if (undefined != color) {
ctx.setFillStyle(color);
ctx.setStrokeStyle(color);
} else {
ctx.setFillStyle(point[0].color);
ctx.setStrokeStyle(point[0].color);
}
for (let i = 1; i < point.length; i++) {
ctx.bezierCurveTo(point[i].c1x, point[i].c1y, point[i].c2x, point[i].c2y, point[i].ex, point[i].ey);
}
ctx.stroke();
if (undefined != is_fill) {
ctx.fill(); //填充图形 ( 后绘制的图形会覆盖前面的图形, 绘制时注意先后顺序 )
}
ctx.draw(true);
},
selectColorEvent(str,color) {
this.selectColor = str;
this.lineColor = color;
},
//将Canvas内容转成 临时图片 --> cb 为回调函数 形参 tempImgPath 为 生成的图片临时路径
canvasToImg(cb) {
//这种写法移动端 出不来
this.ctx.draw(true, () => {
uni.canvasToTempFilePath({
canvasId: 'handWriting',
fileType: 'png',
quality: 1, //图片质量
success(res) {
// console.log(res.tempFilePath, 'canvas生成图片地址');
uni.showToast({
title: '执行了吗?'
});
cb(res.tempFilePath);
}
});
});
},
//完成
subCanvas() {
var _this = this;
this.ctx.draw(true, () => {
uni.canvasToTempFilePath({
canvasId: 'handWriting',
fileType: 'jpg',
quality: 1, //图片质量
destWidth:900,
destHeight:435,
success(res) {
_this.imgList.splice(0,_this.imgList.length);
let img={};
img.id='';
img.filePath=res.tempFilePath;
_this.imgList.push(img)
// console.log(res.tempFilePath, 'canvas生成图片地址');
// uni.showToast({
// title: '以保存'
// });
_this.hideModal();
_this.retDraw();
// //保存到系统相册
// uni.saveImageToPhotosAlbum({
// filePath: res.tempFilePath,
// success(res) {
// uni.showToast({
// title: '已成功保存到相册',
// duration: 2000
// });
// }
// });
}
});
});
},
//保存到相册
saveCanvasAsImg() {
/*
this.canvasToImg( tempImgPath=>{
// console.log(tempImgPath, '临时路径');
uni.saveImageToPhotosAlbum({
filePath: tempImgPath,
success(res) {
uni.showToast({
title: '已保存到相册',
duration: 2000
});
}
})
} );
*/
uni.canvasToTempFilePath({
canvasId: 'handWriting',
fileType: 'png',
quality: 1, //图片质量
success(res) {
// console.log(res.tempFilePath, 'canvas生成图片地址');
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success(res) {
uni.showToast({
title: '已保存到相册',
duration: 2000
});
}
});
}
});
},
//预览
previewCanvasImg() {
uni.canvasToTempFilePath({
canvasId: 'handWriting',
fileType: 'jpg',
quality: 1, //图片质量
success(res) {
// console.log(res.tempFilePath, 'canvas生成图片地址');
uni.previewImage({
urls: [res.tempFilePath] //预览图片 数组
});
}
});
/* //移动端出不来 ^~^
this.canvasToImg( tempImgPath=>{
uni.previewImage({
urls: [tempImgPath], //预览图片 数组
})
} );
*/
},
//上传
uploadCanvasImg() {
uni.canvasToTempFilePath({
canvasId: 'handWriting',
fileType: 'png',
quality: 1, //图片质量
success(res) {
// console.log(res.tempFilePath, 'canvas生成图片地址');
//上传
uni.uploadFile({
url: 'https://example.weixin.qq.com/upload', // 仅为示例,非真实的接口地址
filePath: res.tempFilePath,
name: 'file_signature',
formData: {
user: 'test'
},
success(res) {
const data = res.data;
// do something
}
});
}
});
},
//设置canvas背景色 不设置 导出的canvas的背景为透明
//@params字符串 color
setCanvasBg(color) {
/* 将canvas背景设置为 白底,不设置 导出的canvas的背景为透明 */
//rect() 参数说明 矩形路径左上角的横坐标,左上角的纵坐标, 矩形路径的宽度, 矩形路径的高度
//这里是 canvasHeight - 4 是因为下边盖住边框了,所以手动减了写
this.ctx.rect(0, 0, this.canvasWidth, this.canvasHeight - 4);
// ctx.setFillStyle('red')
this.ctx.setFillStyle(color);
this.ctx.fill(); //设置填充
this.ctx.draw(); //开画
}
}
}
</script>
<style>
.prevent {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
overflow: hidden;
}
.cu-form-title{
padding: 20upx 0;
}
.cu-form-textarea{
background-color: #ffffff;
padding: 1upx 30upx 20upx;
min-height: 100upx;
}
.cu-form-textarea textarea {
height: 4.6em;
width: 100%;
line-height: 1.2em;
flex: 1;
font-size: 28upx;
padding: 0;
}
.selected{
display: flex;
align-items: center;
height: 100upx;
}
.selected .radio{
transform:scale(0.8);
margin-right: 10upx;
}
.group{
display: flex;
align-items: center;
}
.cu-form-group .title{
font-size: 28upx;
color: #666;
}
.cu-bar .action:first-child {
font-size: 28upx;
}
.wrapper {
width: 100%;
height: 24vh;
margin: 0;
overflow: hidden;
display: flex;
align-content: center;
flex-direction: row;
justify-content: center;
font-size: 28rpx;
}
.handWriting {
background: #fff;
width: 100%;
height: 100%;
}
.handRight {
display: inline-flex;
align-items: center;
}
.handCenter {
border: 4rpx dashed #e9e9e9;
flex: 5;
overflow: hidden;
box-sizing: border-box;
}
.handBtn button {
font-size: 28rpx;
}
.handBtn {
height: 95vh;
display: inline-flex;
flex-direction: column;
justify-content: space-between;
align-content: space-between;
flex: 1;
}
.delBtn {
position: absolute;
top: 250rpx;
left: 0rpx;
color: #666;
}
.delBtn image {
position: absolute;
top: 13rpx;
left: 25rpx;
}
.subBtn {
/* position: absolute; */
bottom: 0rpx;
left: -32rpx;
display: inline-flex;
background: #008ef6;
color: #fff;
margin-bottom: 30rpx;
text-align: center;
justify-content: center;
}
/*Peach - 新增 - 保存*/
.saveBtn {
position: absolute;
top: 375rpx;
left: 0rpx;
color: #666;
}
.previewBtn {
position: absolute;
top: 500rpx;
left: 0rpx;
color: #666;
}
.uploadBtn {
position: absolute;
top: 625rpx;
left: 0rpx;
color: #666;
}
/*Peach - 新增 - 保存*/
.black-select {
width: 60rpx;
height: 60rpx;
position: absolute;
top: 30rpx;
left: 25rpx;
}
.black-select.color_select {
width: 90rpx;
height: 90rpx;
top: 100rpx;
left: 10rpx;
}
.red-select {
width: 60rpx;
height: 60rpx;
position: absolute;
top: 140rpx;
left: 25rpx;
}
.red-select.color_select {
width: 90rpx;
height: 90rpx;
top: 120rpx;
left: 10rpx;
}
</style>