papers.js 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711
  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 {
  262. $.closeModal();
  263. $.modal({
  264. title: "",
  265. text: "<div class='scan'>下单失败</div><div class='tips'>" + res.message + "</div>",
  266. buttons: [
  267. {
  268. text: "取消",
  269. onClick: function () {
  270. return false;
  271. }
  272. }
  273. ]
  274. });
  275. }
  276. }, "json")
  277. }
  278. },
  279. ]
  280. });
  281. } else {
  282. $.toast(res.message);
  283. setTimeout(function () {
  284. _this.showModal();
  285. }, 500)
  286. }
  287. }, 'json');
  288. },
  289. // 扫码设备
  290. scan: function () {
  291. var _this = this;
  292. $.post('/weixin/index/getJssdkParams', {url: location.href}, function (res) {
  293. var params = res.data;
  294. // 微信JSSDK
  295. wx.config({
  296. debug: false, // 是否调试模式
  297. appId: params.appId, // 必填,公众号的唯一标识
  298. timestamp: params.timestamp, // 必填,生成签名的时间戳
  299. nonceStr: params.nonceStr, // 必填,生成签名的随机串
  300. signature: params.signature,// 必填,签名
  301. jsApiList: ['onMenuShareTimeline', 'onMenuShareAppMessage', 'scanQRCode'] // 必填,需要使用的JS接口列表
  302. });
  303. // 初始化处理
  304. wx.ready(function () {
  305. // 微信扫一扫
  306. $.closeModal();
  307. wx.scanQRCode({
  308. needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
  309. scanType: ["qrCode", "barCode"], // 可以指定扫二维码还是一维码,默认二者都有
  310. success: function (res) {
  311. var deviceId = res.resultStr;
  312. _this.deviceId = deviceId;
  313. if (deviceId) {
  314. $.closeModal();
  315. $.modal({
  316. title: "",
  317. text: "<div class='scan'>扫码成功</div><div class='info'></div><div class='tips'>点击下方确认下单</div>",
  318. buttons: [
  319. {
  320. text: "取消",
  321. className: "default",
  322. onClick: function () {
  323. $.closeModal();
  324. setTimeout(function () {
  325. _this.showModal();
  326. }, 500)
  327. return false;
  328. }
  329. },
  330. {
  331. text: "确认下单",
  332. className: "warning",
  333. onClick: function () {
  334. var params = {
  335. clusterId: _this.id,
  336. deviceId: deviceId,
  337. printType: _this.printType,
  338. colorType: _this.colorType,
  339. type: 3
  340. };
  341. $.showLoading('订单处理中...');
  342. $.post('/weixin/order/confirm', params, function (res) {
  343. $.hideLoading();
  344. if (res.code == 'success') {
  345. var msg = _this.id > 0 && _this.printType == 2 ? '参与拼团成功' : (_this.printType == 2 ? '发起拼团成功' : '下单成功');
  346. $.showLoading(msg + ',即将前往支付...');
  347. setTimeout(function () {
  348. location.href = '/weixin/order/pay?id=' + res.data;
  349. }, 800);
  350. } else if (res.code == 'login') {
  351. login(res.data.url);
  352. } else {
  353. $.closeModal();
  354. $.modal({
  355. title: "",
  356. text: "<div class='scan'>下单失败</div><div class='tips'>" + res.message + "</div>",
  357. buttons: [
  358. {
  359. text: "取消",
  360. onClick: function () {
  361. return false;
  362. }
  363. },
  364. {
  365. text: "重新扫码下单",
  366. className: "warning",
  367. onClick: function () {
  368. _this.scan();
  369. }
  370. },
  371. ]
  372. });
  373. }
  374. }, "json")
  375. }
  376. },
  377. ]
  378. });
  379. } else {
  380. $.toast('扫码信息错误');
  381. }
  382. }
  383. });
  384. });
  385. }, "JSON");
  386. },
  387. // base转文件
  388. dataURLtoFile: function (dataurl, filename) {//将base64转换为文件
  389. var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
  390. bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
  391. while (n--) {
  392. u8arr[n] = bstr.charCodeAt(n);
  393. }
  394. return new File([u8arr], filename, {type: mime});
  395. },
  396. // base转文件
  397. dataBlobtoFile: function (dataurl, filename) {//将base64转换为文件
  398. return new File([dataurl], filename, {type: 'image/jpeg'});
  399. },
  400. // 删除图片
  401. picDel: function (id) {
  402. this.picList[id] = {url: '', preview: ''};
  403. $("#upload_"+id).val('');
  404. },
  405. // 彩印
  406. picColor: function (k) {
  407. if ($("#color_" + k).hasClass('active')) {
  408. $("#color_" + k).attr('data-color', 1);
  409. $("#color_" + k).text('黑白');
  410. } else {
  411. $("#color_" + k).attr('data-color', 2);
  412. $("#color_" + k).text('彩印');
  413. }
  414. $("#color_" + k).toggleClass('active');
  415. },
  416. // 编辑图片
  417. picEdit: function (id) {
  418. var _this = this;
  419. $.closePopup();
  420. $(".crop-img").html('<img id="cropImg" src="" alt="" off="">');
  421. _this.cropParams = JSON.parse(JSON.stringify(_this.picList[id]));
  422. if (_this.cropParams.url == '') {
  423. $.toast('请选择图片');
  424. return false;
  425. }
  426. $("#cropImg").attr('src', _this.cropParams.url);
  427. $image = $("#cropImg");
  428. $("#cropBox").popup();
  429. var imgWidth = 243;
  430. var imgHeight = 153;
  431. var options = {
  432. aspectRatio: parseFloat(243/153),
  433. zoomOnWheel: false,
  434. scalable: false,
  435. // touchDragZoom: false,
  436. responsive:false,
  437. minCropBoxWidth: imgWidth,
  438. minCropBoxHeight: imgHeight,
  439. // maxCropBoxWidth: imgWidth,
  440. // maxCropBoxHeight: imgHeight,
  441. preview: '.preview_' + id,
  442. crop: function (data) {
  443. _this.cropParams.id = id;
  444. _this.cropParams.cropData = {
  445. width: data.width,
  446. height: data.height,
  447. rotate: data.rotate,
  448. imageSmoothingQuality: 'high',
  449. fillColor: '#fff',
  450. };
  451. }
  452. }
  453. if (_this.jc != null) {
  454. $image.cropper(options);
  455. $image.cropper('replace', _this.cropParams.old_url);
  456. } else {
  457. $image.cropper(options);
  458. _this.jc = $image.cropper('replace', _this.cropParams.old_url);
  459. }
  460. },
  461. // 旋转图片处理
  462. rotateImg: function(img, direction,canvas) {
  463. //alert(img);
  464. //最小与最大旋转方向,图片旋转4次后回到原方向
  465. var min_step = 0;
  466. var max_step = 3;
  467. //var img = document.getElementById(pid);
  468. if (img == null)return;
  469. //img的高度和宽度不能在img元素隐藏后获取,否则会出错
  470. var height = img.height;
  471. var width = img.width;
  472. //var step = img.getAttribute('step');
  473. var step = 2;
  474. if (step == null) {
  475. step = min_step;
  476. }
  477. if (direction == 'right') {
  478. step++;
  479. //旋转到原位置,即超过最大值
  480. step > max_step && (step = min_step);
  481. } else {
  482. step--;
  483. step < min_step && (step = max_step);
  484. }
  485. //旋转角度以弧度值为参数
  486. var degree = step * 90 * Math.PI / 180;
  487. var ctx = canvas.getContext('2d');
  488. switch (step) {
  489. case 0:
  490. canvas.width = width;
  491. canvas.height = height;
  492. ctx.drawImage(img, 0, 0);
  493. break;
  494. case 1:
  495. canvas.width = height;
  496. canvas.height = width;
  497. ctx.rotate(degree);
  498. ctx.drawImage(img, 0, -height);
  499. break;
  500. case 2:
  501. canvas.width = width;
  502. canvas.height = height;
  503. ctx.rotate(degree);
  504. ctx.drawImage(img, -width, -height);
  505. break;
  506. case 3:
  507. canvas.width = height;
  508. canvas.height = width;
  509. ctx.rotate(degree);
  510. ctx.drawImage(img, -width, 0);
  511. break;
  512. }
  513. },
  514. // 取消剪切
  515. cropCancel: function () {
  516. $.closePopup();
  517. $("#previewBox").hide();
  518. this.preview = true;
  519. if (this.jc != false) {
  520. $("#cropImg").cropper('destroy');
  521. this.jc = null;
  522. $("#cropImg").remove();
  523. }
  524. },
  525. // 预览剪切
  526. cropPreview: function () {
  527. $.closePopup();
  528. $("#previewBox").hide();
  529. $("#previewBox").popup();
  530. if(this.picList.img1.url || this.picList.img2.url){
  531. this.preview = false;
  532. }
  533. },
  534. // 旋转
  535. rotateConfirm: function(){
  536. $("#cropImg").cropper("rotate", 45);
  537. },
  538. // 缩放
  539. cropZoom: function(ele, type){
  540. $("#cropImg").cropper("zoom", type==1? 0.1 : -0.1);
  541. },
  542. // 确定剪切
  543. cropConfirm: function () {
  544. var _this = this;
  545. $.closePopup();
  546. $("#previewBox").hide();
  547. if (this.jc != null) {
  548. $.showLoading('图片处理中...');
  549. $image = $("#cropImg");
  550. var id = _this.cropParams.id;
  551. var canvas = $image.cropper('getCroppedCanvas', _this.cropParams.cropData);
  552. var url = canvas.toBlob(function(e){
  553. //生成Blob的图片格式
  554. if(e != null){
  555. var timestamp = Date.parse(new Date());
  556. e.name=timestamp+".jpg";
  557. url = URL.createObjectURL(e);
  558. _this.picList[id].url = url;
  559. _this.picList[id].preview = url;
  560. _this.picList[id].fileData = _this.dataBlobtoFile(e, e.name);
  561. setTimeout(function(){
  562. $.hideLoading();
  563. $("#cropImg").cropper('destroy');
  564. _this.jc = null;
  565. $("#cropImg").remove();
  566. }, 500)
  567. }else{
  568. $.hideLoading();
  569. $.showLoading('图片处理失败请刷新重试');
  570. setTimeout(function(){
  571. $("#cropImg").cropper('destroy');
  572. _this.jc = null;
  573. $("#cropImg").remove();
  574. }, 1000);
  575. }
  576. },"image/jpeg");
  577. }
  578. },
  579. // 选择图片
  580. selectPic: function (ele, id) {
  581. var _this = this;
  582. var files = ele.target.files;
  583. if (files.length > 0) {
  584. $.each(files, function (k, file) {
  585. if (file) {
  586. var Orientation = null;
  587. //获取照片方向角属性,用户旋转控制
  588. EXIF.getData(file, function() {
  589. // alert(EXIF.pretty(this));
  590. EXIF.getAllTags(this);
  591. //alert(EXIF.getTag(this, 'Orientation'));
  592. Orientation = EXIF.getTag(this, 'Orientation');
  593. //return;
  594. });
  595. var reader = new FileReader();
  596. reader.readAsDataURL(file);
  597. var blobUrl = URL.createObjectURL(file);
  598. reader.onloadend = function (even) {
  599. var image = new Image();
  600. image.src = even.currentTarget.result;
  601. image.onload = function(){
  602. var expectWidth = this.naturalWidth;
  603. var expectHeight = this.naturalHeight;
  604. if (this.naturalWidth > this.naturalHeight && this.naturalWidth > 800) {
  605. expectWidth = 800;
  606. expectHeight = expectWidth * this.naturalHeight / this.naturalWidth;
  607. } else if (this.naturalHeight > this.naturalWidth && this.naturalHeight > 1200) {
  608. expectHeight = 1200;
  609. expectWidth = expectHeight * this.naturalWidth / this.naturalHeight;
  610. }
  611. var canvas = document.createElement("canvas");
  612. var ctx = canvas.getContext("2d");
  613. canvas.width = expectWidth;
  614. canvas.height = expectHeight;
  615. ctx.drawImage(this, 0, 0, expectWidth, expectHeight);
  616. var base64 = null;
  617. //修复ios
  618. if (navigator.userAgent.match(/iphone/i)) {
  619. //alert(expectWidth + ',' + expectHeight);
  620. //如果方向角不为1,都需要进行旋转 added by lzk
  621. if(Orientation != "" && Orientation != 1){
  622. //alert('旋转处理');
  623. switch(Orientation){
  624. case 6://需要顺时针(向左)90度旋转
  625. //alert('需要顺时针(向左)90度旋转');
  626. _this.rotateImg(this,'left',canvas);
  627. break;
  628. case 8://需要逆时针(向右)90度旋转
  629. //alert('需要顺时针(向右)90度旋转');
  630. _this.rotateImg(this,'right',canvas);
  631. break;
  632. case 3://需要180度旋转
  633. //alert('需要180度旋转');
  634. _this.rotateImg(this,'right',canvas);//转两次
  635. _this.rotateImg(this,'right',canvas);
  636. break;
  637. }
  638. }
  639. base64 = canvas.toDataURL("image/jpeg", 0.8);
  640. }else{
  641. //alert(Orientation);
  642. if(Orientation != "" && Orientation != 1){
  643. //alert('旋转处理');
  644. switch(Orientation){
  645. case 6://需要顺时针(向左)90度旋转
  646. //alert('需要顺时针(向左)90度旋转');
  647. _this.rotateImg(this,'left',canvas);
  648. break;
  649. case 8://需要逆时针(向右)90度旋转
  650. //alert('需要顺时针(向右)90度旋转');
  651. _this.rotateImg(this,'right',canvas);
  652. break;
  653. case 3://需要180度旋转
  654. //alert('需要180度旋转');
  655. _this.rotateImg(this,'right',canvas);//转两次
  656. _this.rotateImg(this,'right',canvas);
  657. break;
  658. }
  659. }
  660. base64 = canvas.toDataURL("image/jpeg", 0.8);
  661. }
  662. //uploadImage(base64);
  663. //$("#myImage").attr("src", base64);
  664. var img = {
  665. id: id,
  666. url: base64,
  667. preview: base64,
  668. old_url: base64,
  669. blobUrl: blobUrl,
  670. name: file.name,
  671. file_size: file.size,
  672. file_type: file.type
  673. };
  674. _this.picList[id] = img;
  675. setTimeout(function(){
  676. _this.picEdit(id);
  677. }, 300)
  678. }
  679. }
  680. }
  681. })
  682. }
  683. }
  684. }
  685. });