papers.js 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713
  1. var app = new Vue({
  2. el: '#app',
  3. data: {
  4. // 用户信息
  5. memberInfo: {},
  6. // 当前编辑后图片
  7. preview: true,
  8. editPic: '',
  9. // 剪切参数
  10. cropParams: {
  11. id: 0,
  12. url: '',
  13. preview: '',
  14. cropData: {},
  15. },
  16. // 图片列表
  17. picList: {
  18. img1: {url: '', preview: ''},
  19. img2: {url: '', preview: ''}
  20. },
  21. // 预览状态
  22. cropPreviewStatus: false,
  23. // 上传状态
  24. submitting: false,
  25. // 打印方式
  26. printType: 1,
  27. // 色彩
  28. colorType: 1,
  29. image: null,
  30. // 设备ID
  31. deviceId: 0,
  32. // 剪切对象
  33. jc: false,
  34. id: 0,
  35. },
  36. created: function () {
  37. //this.getFileList();
  38. var printType = getParam('pt');
  39. this.id = getParam('id');
  40. this.printType = printType ? printType : 1;
  41. },
  42. mounted: function () {
  43. var _this = this;
  44. // 计时器
  45. var MAX = 100, MIN = 1;
  46. $('.weui-count__decrease').on('click', function (e) {
  47. var $input = $(e.target).siblings('.weui-count__number');
  48. var number = parseInt($input.val() || "0") - 1
  49. if (number < MIN) number = MIN;
  50. $input.val(number)
  51. })
  52. $('.weui-count__increase').on('click', function (e) {
  53. var $input = $(e.target).siblings('.weui-count__number');
  54. var number = parseInt($input.val() || "0") + 1;
  55. if (number > MAX) number = MAX;
  56. $input.val(number)
  57. });
  58. $(".weui-count__number").blur(function () {
  59. var num = $.trim($(this).val());
  60. if (!/[1-9][0-9]{0,2}/.test(num) || num < MIN || num > MAX) {
  61. num = 1;
  62. }
  63. $(this).val(num);
  64. });
  65. $("#colorType").change(function(){
  66. if($(this).is(":checked")){
  67. _this.colorType = 2;
  68. }else{
  69. _this.colorType = 1;
  70. }
  71. })
  72. $("body").css('overflow','hidden');
  73. },
  74. methods: {
  75. // 获取图片列表
  76. getFileList: function () {
  77. var _this = this;
  78. $.post('/weixin/print/getFileList', {type: 3}, function (res) {
  79. if (res.code == 'success') {
  80. } else if (res.code == 'login') {
  81. login(res.data.url);
  82. }
  83. }, "json");
  84. },
  85. // 获取用户信息
  86. getMemberInfo: function () {
  87. var _this = this;
  88. $.post('/weixin/member/getMemberInfo', {}, function (res) {
  89. if (res.code == 'success') {
  90. _this.memberInfo = res.data
  91. } else if (res.code == 'login') {
  92. login(res.data.url);
  93. }
  94. }, "json");
  95. },
  96. // 提交
  97. doSubmit: function () {
  98. var _this = this;
  99. var count = 0;
  100. var formData = new FormData();
  101. if (_this.submitting) {
  102. return false;
  103. }
  104. if ((_this.picList.img1.preview == '' || typeof(_this.picList.img1.preview) == 'undefined') && (_this.picList.img2.preview == '' || typeof(_this.picList.img2.preview) == 'undefined')) {
  105. $.toast('请选择打印的图片');
  106. return false;
  107. }
  108. _this.preview = false;
  109. setTimeout(function(){
  110. $.closePopup();
  111. $("#previewBox").popup();
  112. // _this.colorType = $("#colorType").is(":checked") ? 2 : 1;
  113. var num = parseInt($("#papers-num").val());
  114. num = num > 0 ? num : 1;
  115. $("#previewBox").show();
  116. var $previewImg = document.getElementById("print-preview");
  117. html2canvas($previewImg, {scale: 3, useCORS: true}).then( function (canvas) {
  118. const context = canvas.getContext('2d');
  119. context.translate(0.5,0.5);
  120. context.mozImageSmoothingEnabled = false;
  121. context.webkitImageSmoothingEnabled = false;
  122. context.msImageSmoothingEnabled = false;
  123. context.imageSmoothingEnabled = false;
  124. var src = canvas.toDataURL('image/jpeg');
  125. var file = _this.dataURLtoFile(src, '证件打印.jpeg');
  126. formData.append('type', 3);
  127. formData.append('image[]', file);
  128. formData.append('nums[]', num);
  129. formData.append('colors[]', _this.colorType);
  130. $.hideLoading();
  131. _this.saveImg(formData);
  132. }
  133. );
  134. }, 200)
  135. },
  136. // 保存图片
  137. saveImg: function (formData) {
  138. // 上传
  139. var _this = this;
  140. $.showLoading('文件上传处理中...');
  141. var ajax = $.ajax({
  142. url: '/weixin/upload/image',
  143. data: formData,
  144. type: "post",
  145. dataType: 'json',
  146. cache: false,
  147. contentType: false,
  148. processData: false,
  149. timeout: 30000,
  150. success: function (res) {
  151. $.hideLoading();
  152. if (res.code == 'success') {
  153. _this.showModal();
  154. } else if (res.code == 'login') {
  155. login(res.data.url);
  156. } else {
  157. $.toast(res.message);
  158. }
  159. },
  160. error: function (res) {
  161. $.toast('服务器错误');
  162. },
  163. complete: function (XMLHttpRequest, status) {
  164. if (status == 'timeout') {
  165. ajax.abort();
  166. $.toast('请求超时,请重新提交');
  167. location.reload();
  168. }
  169. }
  170. })
  171. },
  172. // 显示填写窗口
  173. showModal: function () {
  174. var _this = this;
  175. $.closeModal();
  176. $.modal({
  177. title: "",
  178. autoClose: false,
  179. text: "<div class='scan'>填写/扫码打印设备</div><div class='tips'>设备号<input type='text' id='device_code' placeholder='请填写打印机设备号'></div>",
  180. buttons: [
  181. {
  182. text: "取消",
  183. className: "default",
  184. onClick: function () {
  185. $.closeModal();
  186. $.closePopup();
  187. $("#previewBox").hide();
  188. return false;
  189. }
  190. },
  191. {
  192. text: "扫码打印",
  193. className: "warning",
  194. onClick: function () {
  195. _this.scan();
  196. }
  197. },
  198. {
  199. text: "填写打印",
  200. className: "success",
  201. onClick: function () {
  202. _this.inputCode();
  203. return false;
  204. }
  205. },
  206. ]
  207. });
  208. },
  209. // 输入设备号打印
  210. inputCode: function () {
  211. var _this = this;
  212. var deviceCode = $.trim($("#device_code").val());
  213. if (deviceCode == '' || deviceCode === null) {
  214. $.toast('请填写设备号');
  215. setTimeout(function () {
  216. _this.showModal();
  217. }, 500)
  218. return false;
  219. }
  220. $.post('/weixin/print/checkDevice', {deviceCode: deviceCode}, function (res) {
  221. if (res.code == 'success') {
  222. var deviceId = res.data.id;
  223. $.closeModal();
  224. $.modal({
  225. title: "",
  226. text: "<div class='scan'>设备验证成功</div><div class='info'></div><div class='tips'>点击下方确认下单</div>",
  227. buttons: [
  228. {
  229. text: "取消",
  230. className: "default",
  231. onClick: function () {
  232. $.closeModal();
  233. setTimeout(function () {
  234. _this.showModal();
  235. }, 500)
  236. return false;
  237. }
  238. },
  239. {
  240. text: "确认下单",
  241. className: "warning",
  242. onClick: function () {
  243. var params = {
  244. clusterId: _this.id,
  245. deviceId: deviceId,
  246. printType: _this.printType,
  247. colorType: _this.colorType,
  248. type: 3
  249. };
  250. $.showLoading('订单处理中...');
  251. $.post('/weixin/order/confirm', params, function (res) {
  252. $.hideLoading();
  253. if (res.code == 'success') {
  254. var msg = _this.id > 0 && _this.printType == 2 ? '参与拼团成功' : (_this.printType == 2 ? '发起拼团成功' : '下单成功');
  255. $.showLoading(msg + ',即将前往支付...');
  256. setTimeout(function () {
  257. location.href = '/weixin/order/pay?id=' + res.data;
  258. }, 800);
  259. } else if (res.code == 'login') {
  260. login(res.data.url);
  261. } else if(res.code == 'excepition'){
  262. showAlert(res.message);
  263. } else {
  264. $.closeModal();
  265. $.modal({
  266. title: "",
  267. text: "<div class='scan'>下单失败</div><div class='tips'>" + res.message + "</div>",
  268. buttons: [
  269. {
  270. text: "取消",
  271. onClick: function () {
  272. return false;
  273. }
  274. }
  275. ]
  276. });
  277. }
  278. }, "json")
  279. }
  280. },
  281. ]
  282. });
  283. } else {
  284. $.toast(res.message);
  285. setTimeout(function () {
  286. _this.showModal();
  287. }, 500)
  288. }
  289. }, 'json');
  290. },
  291. // 扫码设备
  292. scan: function () {
  293. var _this = this;
  294. $.post('/weixin/index/getJssdkParams', {url: location.href}, function (res) {
  295. var params = res.data;
  296. // 微信JSSDK
  297. wx.config({
  298. debug: false, // 是否调试模式
  299. appId: params.appId, // 必填,公众号的唯一标识
  300. timestamp: params.timestamp, // 必填,生成签名的时间戳
  301. nonceStr: params.nonceStr, // 必填,生成签名的随机串
  302. signature: params.signature,// 必填,签名
  303. jsApiList: ['onMenuShareTimeline', 'onMenuShareAppMessage', 'scanQRCode'] // 必填,需要使用的JS接口列表
  304. });
  305. // 初始化处理
  306. wx.ready(function () {
  307. // 微信扫一扫
  308. $.closeModal();
  309. wx.scanQRCode({
  310. needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
  311. scanType: ["qrCode", "barCode"], // 可以指定扫二维码还是一维码,默认二者都有
  312. success: function (res) {
  313. var deviceId = res.resultStr;
  314. _this.deviceId = deviceId;
  315. if (deviceId) {
  316. $.closeModal();
  317. $.modal({
  318. title: "",
  319. text: "<div class='scan'>扫码成功</div><div class='info'></div><div class='tips'>点击下方确认下单</div>",
  320. buttons: [
  321. {
  322. text: "取消",
  323. className: "default",
  324. onClick: function () {
  325. $.closeModal();
  326. setTimeout(function () {
  327. _this.showModal();
  328. }, 500)
  329. return false;
  330. }
  331. },
  332. {
  333. text: "确认下单",
  334. className: "warning",
  335. onClick: function () {
  336. var params = {
  337. clusterId: _this.id,
  338. deviceId: deviceId,
  339. printType: _this.printType,
  340. colorType: _this.colorType,
  341. type: 3
  342. };
  343. $.showLoading('订单处理中...');
  344. $.post('/weixin/order/confirm', params, function (res) {
  345. $.hideLoading();
  346. if (res.code == 'success') {
  347. var msg = _this.id > 0 && _this.printType == 2 ? '参与拼团成功' : (_this.printType == 2 ? '发起拼团成功' : '下单成功');
  348. $.showLoading(msg + ',即将前往支付...');
  349. setTimeout(function () {
  350. location.href = '/weixin/order/pay?id=' + res.data;
  351. }, 800);
  352. } else if (res.code == 'login') {
  353. login(res.data.url);
  354. } else {
  355. $.closeModal();
  356. $.modal({
  357. title: "",
  358. text: "<div class='scan'>下单失败</div><div class='tips'>" + res.message + "</div>",
  359. buttons: [
  360. {
  361. text: "取消",
  362. onClick: function () {
  363. return false;
  364. }
  365. },
  366. {
  367. text: "重新扫码下单",
  368. className: "warning",
  369. onClick: function () {
  370. _this.scan();
  371. }
  372. },
  373. ]
  374. });
  375. }
  376. }, "json")
  377. }
  378. },
  379. ]
  380. });
  381. } else {
  382. $.toast('扫码信息错误');
  383. }
  384. }
  385. });
  386. });
  387. }, "JSON");
  388. },
  389. // base转文件
  390. dataURLtoFile: function (dataurl, filename) {//将base64转换为文件
  391. var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
  392. bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
  393. while (n--) {
  394. u8arr[n] = bstr.charCodeAt(n);
  395. }
  396. return new File([u8arr], filename, {type: mime});
  397. },
  398. // base转文件
  399. dataBlobtoFile: function (dataurl, filename) {//将base64转换为文件
  400. return new File([dataurl], filename, {type: 'image/jpeg'});
  401. },
  402. // 删除图片
  403. picDel: function (id) {
  404. this.picList[id] = {url: '', preview: ''};
  405. $("#upload_"+id).val('');
  406. },
  407. // 彩印
  408. picColor: function (k) {
  409. if ($("#color_" + k).hasClass('active')) {
  410. $("#color_" + k).attr('data-color', 1);
  411. $("#color_" + k).text('黑白');
  412. } else {
  413. $("#color_" + k).attr('data-color', 2);
  414. $("#color_" + k).text('彩印');
  415. }
  416. $("#color_" + k).toggleClass('active');
  417. },
  418. // 编辑图片
  419. picEdit: function (id) {
  420. var _this = this;
  421. $.closePopup();
  422. $(".crop-img").html('<img id="cropImg" src="" alt="" off="">');
  423. _this.cropParams = JSON.parse(JSON.stringify(_this.picList[id]));
  424. if (_this.cropParams.url == '') {
  425. $.toast('请选择图片');
  426. return false;
  427. }
  428. $("#cropImg").attr('src', _this.cropParams.url);
  429. $image = $("#cropImg");
  430. $("#cropBox").popup();
  431. var imgWidth = 243;
  432. var imgHeight = 153;
  433. var options = {
  434. aspectRatio: parseFloat(243/153),
  435. zoomOnWheel: false,
  436. scalable: false,
  437. // touchDragZoom: false,
  438. responsive:false,
  439. minCropBoxWidth: imgWidth,
  440. minCropBoxHeight: imgHeight,
  441. // maxCropBoxWidth: imgWidth,
  442. // maxCropBoxHeight: imgHeight,
  443. preview: '.preview_' + id,
  444. crop: function (data) {
  445. _this.cropParams.id = id;
  446. _this.cropParams.cropData = {
  447. width: data.width,
  448. height: data.height,
  449. rotate: data.rotate,
  450. imageSmoothingQuality: 'high',
  451. fillColor: '#fff',
  452. };
  453. }
  454. }
  455. if (_this.jc != null) {
  456. $image.cropper(options);
  457. $image.cropper('replace', _this.cropParams.old_url);
  458. } else {
  459. $image.cropper(options);
  460. _this.jc = $image.cropper('replace', _this.cropParams.old_url);
  461. }
  462. },
  463. // 旋转图片处理
  464. rotateImg: function(img, direction,canvas) {
  465. //alert(img);
  466. //最小与最大旋转方向,图片旋转4次后回到原方向
  467. var min_step = 0;
  468. var max_step = 3;
  469. //var img = document.getElementById(pid);
  470. if (img == null)return;
  471. //img的高度和宽度不能在img元素隐藏后获取,否则会出错
  472. var height = img.height;
  473. var width = img.width;
  474. //var step = img.getAttribute('step');
  475. var step = 2;
  476. if (step == null) {
  477. step = min_step;
  478. }
  479. if (direction == 'right') {
  480. step++;
  481. //旋转到原位置,即超过最大值
  482. step > max_step && (step = min_step);
  483. } else {
  484. step--;
  485. step < min_step && (step = max_step);
  486. }
  487. //旋转角度以弧度值为参数
  488. var degree = step * 90 * Math.PI / 180;
  489. var ctx = canvas.getContext('2d');
  490. switch (step) {
  491. case 0:
  492. canvas.width = width;
  493. canvas.height = height;
  494. ctx.drawImage(img, 0, 0);
  495. break;
  496. case 1:
  497. canvas.width = height;
  498. canvas.height = width;
  499. ctx.rotate(degree);
  500. ctx.drawImage(img, 0, -height);
  501. break;
  502. case 2:
  503. canvas.width = width;
  504. canvas.height = height;
  505. ctx.rotate(degree);
  506. ctx.drawImage(img, -width, -height);
  507. break;
  508. case 3:
  509. canvas.width = height;
  510. canvas.height = width;
  511. ctx.rotate(degree);
  512. ctx.drawImage(img, -width, 0);
  513. break;
  514. }
  515. },
  516. // 取消剪切
  517. cropCancel: function () {
  518. $.closePopup();
  519. $("#previewBox").hide();
  520. this.preview = true;
  521. if (this.jc != false) {
  522. $("#cropImg").cropper('destroy');
  523. this.jc = null;
  524. $("#cropImg").remove();
  525. }
  526. },
  527. // 预览剪切
  528. cropPreview: function () {
  529. $.closePopup();
  530. $("#previewBox").hide();
  531. $("#previewBox").popup();
  532. if(this.picList.img1.url || this.picList.img2.url){
  533. this.preview = false;
  534. }
  535. },
  536. // 旋转
  537. rotateConfirm: function(){
  538. $("#cropImg").cropper("rotate", 45);
  539. },
  540. // 缩放
  541. cropZoom: function(ele, type){
  542. $("#cropImg").cropper("zoom", type==1? 0.1 : -0.1);
  543. },
  544. // 确定剪切
  545. cropConfirm: function () {
  546. var _this = this;
  547. $.closePopup();
  548. $("#previewBox").hide();
  549. if (this.jc != null) {
  550. $.showLoading('图片处理中...');
  551. $image = $("#cropImg");
  552. var id = _this.cropParams.id;
  553. var canvas = $image.cropper('getCroppedCanvas', _this.cropParams.cropData);
  554. var url = canvas.toBlob(function(e){
  555. //生成Blob的图片格式
  556. if(e != null){
  557. var timestamp = Date.parse(new Date());
  558. e.name=timestamp+".jpg";
  559. url = URL.createObjectURL(e);
  560. _this.picList[id].url = url;
  561. _this.picList[id].preview = url;
  562. _this.picList[id].fileData = _this.dataBlobtoFile(e, e.name);
  563. setTimeout(function(){
  564. $.hideLoading();
  565. $("#cropImg").cropper('destroy');
  566. _this.jc = null;
  567. $("#cropImg").remove();
  568. }, 500)
  569. }else{
  570. $.hideLoading();
  571. $.showLoading('图片处理失败请刷新重试');
  572. setTimeout(function(){
  573. $("#cropImg").cropper('destroy');
  574. _this.jc = null;
  575. $("#cropImg").remove();
  576. }, 1000);
  577. }
  578. },"image/jpeg");
  579. }
  580. },
  581. // 选择图片
  582. selectPic: function (ele, id) {
  583. var _this = this;
  584. var files = ele.target.files;
  585. if (files.length > 0) {
  586. $.each(files, function (k, file) {
  587. if (file) {
  588. var Orientation = null;
  589. //获取照片方向角属性,用户旋转控制
  590. EXIF.getData(file, function() {
  591. // alert(EXIF.pretty(this));
  592. EXIF.getAllTags(this);
  593. //alert(EXIF.getTag(this, 'Orientation'));
  594. Orientation = EXIF.getTag(this, 'Orientation');
  595. //return;
  596. });
  597. var reader = new FileReader();
  598. reader.readAsDataURL(file);
  599. var blobUrl = URL.createObjectURL(file);
  600. reader.onloadend = function (even) {
  601. var image = new Image();
  602. image.src = even.currentTarget.result;
  603. image.onload = function(){
  604. var expectWidth = this.naturalWidth;
  605. var expectHeight = this.naturalHeight;
  606. if (this.naturalWidth > this.naturalHeight && this.naturalWidth > 800) {
  607. expectWidth = 800;
  608. expectHeight = expectWidth * this.naturalHeight / this.naturalWidth;
  609. } else if (this.naturalHeight > this.naturalWidth && this.naturalHeight > 1200) {
  610. expectHeight = 1200;
  611. expectWidth = expectHeight * this.naturalWidth / this.naturalHeight;
  612. }
  613. var canvas = document.createElement("canvas");
  614. var ctx = canvas.getContext("2d");
  615. canvas.width = expectWidth;
  616. canvas.height = expectHeight;
  617. ctx.drawImage(this, 0, 0, expectWidth, expectHeight);
  618. var base64 = null;
  619. //修复ios
  620. if (navigator.userAgent.match(/iphone/i)) {
  621. //alert(expectWidth + ',' + expectHeight);
  622. //如果方向角不为1,都需要进行旋转 added by lzk
  623. if(Orientation != "" && Orientation != 1){
  624. //alert('旋转处理');
  625. switch(Orientation){
  626. case 6://需要顺时针(向左)90度旋转
  627. //alert('需要顺时针(向左)90度旋转');
  628. _this.rotateImg(this,'left',canvas);
  629. break;
  630. case 8://需要逆时针(向右)90度旋转
  631. //alert('需要顺时针(向右)90度旋转');
  632. _this.rotateImg(this,'right',canvas);
  633. break;
  634. case 3://需要180度旋转
  635. //alert('需要180度旋转');
  636. _this.rotateImg(this,'right',canvas);//转两次
  637. _this.rotateImg(this,'right',canvas);
  638. break;
  639. }
  640. }
  641. base64 = canvas.toDataURL("image/jpeg", 0.8);
  642. }else{
  643. //alert(Orientation);
  644. if(Orientation != "" && Orientation != 1){
  645. //alert('旋转处理');
  646. switch(Orientation){
  647. case 6://需要顺时针(向左)90度旋转
  648. //alert('需要顺时针(向左)90度旋转');
  649. _this.rotateImg(this,'left',canvas);
  650. break;
  651. case 8://需要逆时针(向右)90度旋转
  652. //alert('需要顺时针(向右)90度旋转');
  653. _this.rotateImg(this,'right',canvas);
  654. break;
  655. case 3://需要180度旋转
  656. //alert('需要180度旋转');
  657. _this.rotateImg(this,'right',canvas);//转两次
  658. _this.rotateImg(this,'right',canvas);
  659. break;
  660. }
  661. }
  662. base64 = canvas.toDataURL("image/jpeg", 0.8);
  663. }
  664. //uploadImage(base64);
  665. //$("#myImage").attr("src", base64);
  666. var img = {
  667. id: id,
  668. url: base64,
  669. preview: base64,
  670. old_url: base64,
  671. blobUrl: blobUrl,
  672. name: file.name,
  673. file_size: file.size,
  674. file_type: file.type
  675. };
  676. _this.picList[id] = img;
  677. setTimeout(function(){
  678. _this.picEdit(id);
  679. }, 300)
  680. }
  681. }
  682. }
  683. })
  684. }
  685. }
  686. }
  687. });