123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605 |
- <!doctype html>
- <html>
- <head>
- <meta charset="utf-8">
- <meta content="yes" name="apple-mobile-web-app-capable">
- <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
- <title>Hello APP</title>
- <link rel="stylesheet" type="text/css" href="../../../../../css/api.css" />
- <link rel="stylesheet" type="text/css" href="../../../../../css/aui-win.css" />
- <link rel="stylesheet" type="text/css" href="../../../../../css/css/vant-ui.css" />
- <link rel="stylesheet" type="text/css" href="../../../../../css/css/iconfont.css">
- <script src="../../../../../script/js/vue.js"></script>
- <script src="../../../../../script/js/vant-ui.js"></script>
- <script src="../../../../../script/js/auto-size.js"></script>
- <script src="../../../../../script/js/pdfjs-2.5.207-es5-dist/build/pdf.js"></script>
- <script src="../../../../../script/js/pdf_plugins.js"></script>
- <style>
- .flex{
- display: flex;
- }
- #app{}
- #aui-header{
- background: linear-gradient(to right,#1474E4,#14A7E4);
- justify-content: space-between;
- align-items: center;
- }
- #scrollcontaier{
- overflow-y: auto;
- }
- .aui-btn-info{
- border: 0
- }
- .title{
- padding: 10px 12px;
- color: #ffffff;
- }
- .image-icon{
- width: .66rem;
- height: .66rem;
- margin-right: 19px;
- }
- img{
- width: 100%;
- height: 100%;
- }
- .nav{
- width: 10.1rem;
- height: 1.44rem;
- margin: .28rem auto 0;
- justify-content: space-between;
- align-items: center;
- background: url("../../../../../image/icon/hedui.png") no-repeat 0 0;
- background-size: 100% auto;
- }
- .details-btn{
- height: .96rem;
- line-height: .96rem;
- padding: 0 .38rem;
- border-radius: 0.08rem;
- background: #1474E4;
- color: #ffffff;
- margin-right: .24rem;
- }
- .details-wrap{
- background: #ffffff;
- box-sizing: border-box;
- width: 10.1rem;
- margin: 0.36rem auto 0;
- border-radius: 0.08rem;
- padding: .4rem;
- }
- .canvas-container{
- position: relative;
- }
- #canvas{
- width: 9.45rem;
- height: 2.39rem;
- background: url("../../../../../image/icon/noimage.png") #e1e5e2 no-repeat 0 0;
- background-size: 100% auto;
- }
- .scale-btn{
- position: absolute;
- top: 0;
- right: -.13rem;
- width: 0;
- height: 0;
- border-bottom: .8rem solid transparent;
- border-right: .8rem solid #1474E4;
- border-left: .8rem solid transparent;
- }
- .scale-btn span{
- display: inline-block;
- width: .32rem;
- height: .32rem;
- position: absolute;
- top: 0;
- right: -.7rem;
- }
- .scale-btn span img{
- width: 100%;
- height: 100%;
- }
- .text-msg{
- color: #595959;
- }
- .field-container{
- background: #F5F5F5;
- }
- .signature{
- /*height: 3.2rem;*/
- width: 100%;
- }
- .signature p{
- color: #595959;
- }
- .esign-box{
- background: rgba(236,236,236,.5) url(../../../../../image/icon/qianming.png) no-repeat 50%;
- width: 9.42rem;
- height: 4.54rem;
- }
- .esigh-btns{
- margin-top: 10px;
- }
- .confirm-btn-container{
- justify-content: center;
- width: 10.1rem;
- margin: .4rem auto;
- }
- .confirm-btn{
- background: linear-gradient(to right, #F09623, #FFCF4C);
- /*padding: 0 1.18rem;*/
- height: .96rem;
- width: 10.1rem;
- line-height: .96rem;
- border-radius: .48rem;
- color: #ffffff;
- font-size: .42rem;
- text-align: center;
- margin: .42rem auto;
- }
- </style>
- </head>
- <style>
- </style>
- <body>
- <div id="app">
- <header class="flex flex-between" id="aui-header">
- <a class="aui-btn aui-btn-info aui-pull-left" tapmode onclick="closeWin()"> <span class="aui-iconfont aui-icon-left"></span> </a>
- <div class="title">签收</div>
- <div class="image-icon" @click="handleGoInstructions"><img src="../../../../../image/icon/zhiyinshuoming.png" alt=""></div>
- </header>
- <div id="scrollcontaier" ref="scrollcontaier">
- <div class="nav flex"><span></span><span class="details-btn" @click="handleGo">核对明细<van-icon name="arrow" /></span></div>
- <div class="details-wrap">
- <div class="canvas-container">
- <div id="canvas" ref="canvas"></div>
- <div class="scale-btn"><span @click='handleScale'><img src="../../../../../image/icon/fangda.png" alt="放大"></span></div>
- </div>
- <van-divider ></van-divider>
- <div class="signature">
- <p>请在空白处签名~</p>
- <div class="esign-box" ref="esignbox">
- <canvas ref="signcanvas" id="signcanvas" width="300" height="300"
- @mousedown="mouseDown"
- @mousemove="mouseMove"
- @mouseup="mouseUp"
- @touchstart="touchStart"
- @touchmove="touchMove"
- @touchend="touchEnd"></canvas>
- </div>
- <div class="esigh-btns">
- <button @click="reset">清空画板</button>
- </div>
- </div>
- <van-divider ></van-divider>
- <p class="text-msg">若您收到的货物与订单存在差异,可上传相关图片及描述,我们会及时处理。</p>
- <van-row class="image-container" gutter="20">
- <van-uploader v-model="fileList" multiple="true"/>
- </van-row>
- <van-field
- class="field-container"
- v-model="remark"
- rows="2"
- autosize
- type="textarea"
- maxlength="50"
- placeholder="请输入备注~"
- show-word-limit
- ref="remark"
- ></van-field>
- </div>
- <div class="list-item-row confirm-btn-container flex">
- <van-button color="linear-gradient(to right, #F09623, #FFCF4C)" :block="true" round :loading="submitLoading" type="info" loading-type="spinner" loading-text="加载中..." v-on:click="handleSubmit">提交</van-button>
- </div>
- </div>
- </div>
- </body>
- <script type="text/javascript" src="../../../../../script/aui_compress.min.js"></script>
- <script type="text/javascript" src="../../../../../script/api.js"></script>
- <link rel="stylesheet" href="../../../../../script/mescroll/mescroll.min.css">
- <script type="text/javascript" src="../../../../../script/mescroll/mescroll.min.js"></script>
- <script type="text/javascript" src="../../../js/httpRequest_sub.js"></script>
- <script type="text/javascript" src="../../../js/vue_plugins_sub.js"></script>
- <script type="text/javascript" src="../../../../../script/jquery-1.11.0.min.js"></script>
- <script type="text/javascript">
- function closeWin() {
- api.closeWin({
- });
- }
- apiready = function() {
- api.parseTapmode();
- var header = $api.byId('aui-header');
- $api.fixStatusBar(header);
- var headerPos = $api.offset(header);
- var body_h = $api.offset($api.dom('body')).h;
- document.getElementById("scrollcontaier").style.height = $api.offset($api.dom('body')).h - headerPos.h + "px";
- var tknum = api.pageParam.tknum;
- var kunnrWe = api.pageParam.kunnrWe;
- var vbelnList = api.pageParam.vbelnList;
- var kunnrWeName = api.pageParam.kunnrWeName;
- var wallBillDriver = api.pageParam.wallBillDriver;
- var grossWeight = api.pageParam.grossWeight;
- var lifmg = api.pageParam.lifmg;
- new Vue({
- el: '#app',
- data: {
- token: $api.getStorage('loginToken'),
- tknum: tknum,
- kunnrWe: kunnrWe,
- vbelnList: vbelnList,
- kunnrWeName:kunnrWeName,
- wallBillDriver:wallBillDriver,
- grossWeight: grossWeight,
- lifmg: lifmg,
- remark: "",
- formdata: new FormData(),
- pdfReader: "",
- imageUrls: "",
- imageList: [],
- fileList: [],
- message: "",
- submitLoading: false,
- width:300,
- height: 300,
- lineWidth: 6,
- lineColor: '#000000',
- bgColor: '',
- isCrop: false,
- hasDrew: false,
- resultImg: '',
- points: [],
- canvasTxt: null,
- startX: 0,
- startY: 0,
- isDrawing: false,
- sratio: 1
- },
- computed: {
- ratio () {
- return this.height / this.width
- },
- stageInfo () {
- return this.$refs.signcanvas.getBoundingClientRect()
- },
- myBg () {
- return this.bgColor ? this.bgColor : 'rgba(255, 255, 255, 0)'
- }
- },
- watch: {
- 'myBg': function (newVal) {
- this.$refs.signcanvas.style.background = newVal
- }
- },
- beforeMount () {
- window.addEventListener('resize', this.$_resizeHandler)
- },
- beforeDestroy () {
- window.removeEventListener('resize', this.$_resizeHandler)
- },
- filters:{
- },
- mounted: function() {
- //月度pdf文件
- this.pdfReader = api.require('pdfReader');
- // pdf展示成图片
- var canvasWidth=this.$refs.canvas.offsetWidth,canvasHeight=this.$refs.canvas.offsetHeight;
- if (this.wallBillDriver) {
- $canvasPdf.loadPDF(this.wallBillDriver,canvasWidth,canvasHeight);
- }
- // 电子签名
- this.width = this.$refs.esignbox.offsetWidth;
- this.height = this.$refs.esignbox.offsetHeight;
- var canvas = this.$refs.signcanvas;
- canvas.height = this.height;
- canvas.width = this.width;
- canvas.style.background = this.myBg;
- this.$_resizeHandler();
- // 在画板以外松开鼠标后冻结画笔
- document.onmouseup = function() {
- this.isDrawing = false;
- }
- },
- methods:{
- handleScale: function(){
- var _this = this;
- this.pdfReader.open({
- path: _this.wallBillDriver,//"https://srmapi.sailuntire.com/Files/20201221/20200000000186-3000100-8379-Out.pdf",
- hidden: {
- print: true,
- export: true,
- bookmark: true,
- email: true
- },
- backBtn: {
- size: { //JSON对象;左上角按钮的大小配置
- w: 20, //数字类型;左上角按钮的宽;默认:60
- h: 20 //数字类型;左上角按钮的高;默认:40
- },
- title: { //JSON对象;按钮标题配置
- text: "返回", //字符串类型;标题文本;默认:‘’
- },
- corner: 5 //数字类型;左上角按钮圆角大小;默认值:5.0
- }
- });
- },
- handleSubmit: function(){
- this.generate();
- if(this.resultImg==""||this.resultImg==null){
- api.toast({
- msg: '您还没签名!',
- duration: 2000,
- location: 'bottom'
- });
- return;
- };
- if(this.fileList.length>0){
- for(var i=0; i<this.fileList.length; i++){
- this.formdata.append('upload',this.fileList[i].file);
- }
- };
- this.formdata.append("token", this.token);
- this.formdata.append("signImg", this.resultImg);
- this.formdata.append("tknum", this.tknum);
- this.formdata.append("kunnrWe", this.kunnrWe);
- this.formdata.append("remark", this.remark);
- var _this = this;
- this.submitLoading = true;
- //测试地址:https://b2bcnapi.sailuntire.com/api/test/b2bapi/action/api/tms/signOperate.xhtml
- // 正式地址:测试地址:https://b2bcnapi.sailuntire.com/api/b2bapi/action/api/tms/signOperate.xhtml
- $.ajax({
- url: "https://b2bcnapi.sailuntire.com/api/b2bapi/action/api/tms/signOperate.xhtml",
- type: "POST",
- data: _this.formdata,
- processData: false, // 告诉jQuery不要去处理发送的数据
- contentType: false, // 告诉jQuery不要去设置Content-Type请求头
- success: function(ret, status, xhr) {
- // api.hideProgress();
- _this.submitLoading = false;
- if (ret.code == 1 || ret.code == '1') {
- api.toast({
- msg: '上传成功'
- });
- api.sendEvent({
- name: 'refusuTmsList'
- });
- api.closeWin();
- } else {
- api.toast({
- msg: ret.message
- });
- }
- }
- });
- },
- handleGo: function(){
- var params = {
- tknum: this.tknum,
- vbelnList: this.vbelnList,
- kunnrWeName: this.kunnrWeName,
- grossWeight: this.grossWeight,
- lifmg: this.lifmg
- };
- this.goWin("tmsdetails","./tmsDetails.html",params);
- },
- handleGoInstructions: function(){
- var _this = this;
- // this.goWin("tmsinstructions","./tmsInstructions.html");//操作视频
- this.pdfReader.open({
- path: "https://b2bcnfile.sailuntire.com/upload/TMS/operationManual/TMS销售出库单签收的操作手册.pdf",//"https://srmapi.sailuntire.com/Files/20201221/20200000000186-3000100-8379-Out.pdf",
- hidden: {
- print: true,
- export: true,
- bookmark: true,
- email: true
- },
- backBtn: {
- size: { //JSON对象;左上角按钮的大小配置
- w: 20, //数字类型;左上角按钮的宽;默认:60
- h: 20 //数字类型;左上角按钮的高;默认:40
- },
- title: { //JSON对象;按钮标题配置
- text: "返回", //字符串类型;标题文本;默认:‘’
- },
- corner: 5 //数字类型;左上角按钮圆角大小;默认值:5.0
- }
- });
- },
- $_resizeHandler () {
- var canvas = this.$refs.signcanvas;
- canvas.style.width = this.width + "px"
- var realw = parseFloat(window.getComputedStyle(canvas).width)
- canvas.style.height = this.ratio * realw + "px";
- this.canvasTxt = canvas.getContext('2d')
- this.canvasTxt.scale(1 * this.sratio, 1 * this.sratio)
- this.sratio = realw / this.width
- this.canvasTxt.scale(1 / this.sratio, 1 / this.sratio)
- },
- // pc
- mouseDown (e) {
- e = e || event
- e.preventDefault()
- this.isDrawing = true
- this.hasDrew = true
- var obj = {
- x: e.offsetX,
- y: e.offsetY
- }
- this.drawStart(obj)
- },
- mouseMove (e) {
- e = e || event
- e.preventDefault()
- if (this.isDrawing) {
- var obj = {
- x: e.offsetX,
- y: e.offsetY
- }
- this.drawMove(obj)
- }
- },
- mouseUp (e) {
- e = e || event
- e.preventDefault()
- var obj = {
- x: e.offsetX,
- y: e.offsetY
- }
- this.drawEnd(obj)
- this.isDrawing = false
- },
- // mobile
- touchStart (e) {
- this.$refs.remark.blur();
- e = e || event
- e.preventDefault()
- this.hasDrew = true
- if (e.touches.length === 1) {
- var obj = {
- x: e.targetTouches[0].clientX - this.$refs.signcanvas.getBoundingClientRect().left,
- y: e.targetTouches[0].clientY - this.$refs.signcanvas.getBoundingClientRect().top
- }
- this.drawStart(obj)
- }
- },
- touchMove (e) {
- e = e || event
- e.preventDefault()
- if (e.touches.length === 1) {
- var obj = {
- x: e.targetTouches[0].clientX - this.$refs.signcanvas.getBoundingClientRect().left,
- y: e.targetTouches[0].clientY - this.$refs.signcanvas.getBoundingClientRect().top
- }
- this.drawMove(obj)
- }
- },
- touchEnd (e) {
- e = e || event
- e.preventDefault()
- if (e.touches.length === 1) {
- var obj = {
- x: e.targetTouches[0].clientX - this.$refs.signcanvas.getBoundingClientRect().left,
- y: e.targetTouches[0].clientY - this.$refs.signcanvas.getBoundingClientRect().top
- }
- this.drawEnd(obj)
- }
- },
- // 绘制
- drawStart (obj) {
- this.startX = obj.x
- this.startY = obj.y
- this.canvasTxt.beginPath()
- this.canvasTxt.moveTo(this.startX, this.startY)
- this.canvasTxt.lineTo(obj.x, obj.y)
- this.canvasTxt.lineCap = 'round'
- this.canvasTxt.lineJoin = 'round'
- this.canvasTxt.lineWidth = this.lineWidth * this.sratio;
- this.canvasTxt.stroke()
- this.canvasTxt.closePath()
- this.points.push(obj)
- },
- drawMove (obj) {
- this.canvasTxt.beginPath()
- this.canvasTxt.moveTo(this.startX, this.startY)
- this.canvasTxt.lineTo(obj.x, obj.y)
- this.canvasTxt.strokeStyle = this.lineColor
- this.canvasTxt.lineWidth = this.lineWidth * this.sratio
- this.canvasTxt.lineCap = 'round'
- this.canvasTxt.lineJoin = 'round'
- this.canvasTxt.stroke()
- this.canvasTxt.closePath()
- this.startY = obj.y
- this.startX = obj.x
- this.points.push(obj)
- },
- drawEnd (obj) {
- this.canvasTxt.beginPath()
- this.canvasTxt.moveTo(this.startX, this.startY)
- this.canvasTxt.lineTo(obj.x, obj.y)
- this.canvasTxt.lineCap = 'round'
- this.canvasTxt.lineJoin = 'round'
- this.canvasTxt.stroke()
- this.canvasTxt.closePath()
- this.points.push(obj)
- this.points.push({x: -1, y: -1})
- },
- // 操作
- generate () {
- var pm = new Promise((resolve, reject) => {
- if (!this.hasDrew) {
- reject(`Warning: Not Signned!`)
- return
- }
- var resImgData = this.canvasTxt.getImageData(0, 0, this.$refs.signcanvas.width, this.$refs.signcanvas.height)
- this.canvasTxt.globalCompositeOperation = "destination-over"
- this.canvasTxt.fillStyle = this.myBg
- this.canvasTxt.fillRect(0,0,this.$refs.signcanvas.width ,this.$refs.signcanvas.height)
- this.resultImg = this.$refs.signcanvas.toDataURL()
- var resultImg = this.resultImg
- this.canvasTxt.clearRect(0, 0, this.$refs.signcanvas.width ,this.$refs.signcanvas.height)
- this.canvasTxt.putImageData(resImgData, 0, 0)
- this.canvasTxt.globalCompositeOperation = "source-over"
- if (this.isCrop) {
- var crop_area = this.getCropArea(resImgData.data)
- var crop_canvas = document.createElement('canvas')
- var crop_ctx = crop_canvas.getContext('2d')
- crop_canvas.width = crop_area[2] - crop_area[0]
- crop_canvas.height = crop_area[3] - crop_area[1]
- var crop_imgData = this.canvasTxt.getImageData(...crop_area)
- crop_ctx.globalCompositeOperation = "destination-over"
- crop_ctx.putImageData(crop_imgData, 0, 0)
- crop_ctx.fillStyle = this.myBg
- crop_ctx.fillRect(0, 0, crop_canvas.width , crop_canvas.height)
- resultImg = crop_canvas.toDataURL()
- crop_canvas = null
- }
- resolve(resultImg)
- })
- return pm
- },
- reset () {
- this.canvasTxt.clearRect(
- 0,
- 0,
- this.$refs.signcanvas.width,
- this.$refs.signcanvas.height
- )
- this.$emit('update:bgColor', '')
- this.$refs.signcanvas.style.background = 'rgba(255, 255, 255, 0)'
- this.points = []
- this.hasDrew = false
- this.resultImg = ''
- },
- getCropArea (imgData) {
- var topX = this.$refs.signcanvas.width; var btmX = 0; var topY = this.$refs.signcanvas.height; var btnY = 0
- for (var i = 0; i < this.$refs.signcanvas.width; i++) {
- for (var j = 0; j < this.$refs.signcanvas.height; j++) {
- var pos = (i + this.$refs.signcanvas.width * j) * 4
- if (imgData[pos] > 0 || imgData[pos + 1] > 0 || imgData[pos + 2] || imgData[pos + 3] > 0) {
- btnY = Math.max(j, btnY)
- btmX = Math.max(i, btmX)
- topY = Math.min(j, topY)
- topX = Math.min(i, topX)
- }
- }
- }
- topX++
- btmX++
- topY++
- btnY++
- var data = [topX, topY, btmX, btnY]
- return data
- }
- }
- })
- };
- </script>
- </html>
|