signContract.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588
  1. <template>
  2. <view class="content">
  3. <!-- <view class="content1"> -->
  4. <!-- <view style='width:70px'>付款方式</view>
  5. <u-radio-group v-model="dataDetails.advanceFreightService" placement="row">
  6. <u-radio :customStyle="radioCustomStyle" v-for="(item, index) in radiolist1" :key="index"
  7. :label="item.name" :name="item.name" @change="radioChange">
  8. </u-radio>
  9. </u-radio-group> -->
  10. <!-- <view class="left">
  11. 付款方式
  12. </view>
  13. <view class="right">
  14. <view class="left-text">平台垫付运费</view>
  15. <u-switch @change="change" v-model="value" inactiveColor='#ABB0BB' size="20" ></u-switch>
  16. </view> -->
  17. <!-- </view> -->
  18. <view class="content2">
  19. <view class="title">
  20. 合同摘要
  21. </view>
  22. <view class='row-between'>
  23. <view class="gray">发货单位</view>
  24. <view class="">{{dataDetails.compName?dataDetails.compName:'个人货主'}}</view>
  25. </view>
  26. <view class='row-between'>
  27. <view class="gray">发货地</view>
  28. <view class="place">
  29. {{dataDetails.sendPrivate}}{{dataDetails.sendCity}}{{dataDetails.sendArea}}{{dataDetails.sendDetailedAddress}}
  30. </view>
  31. </view>
  32. <view class='row-between'>
  33. <view class="gray">卸货地</view>
  34. <view class=" place">
  35. {{dataDetails.unloadPrivate}}{{dataDetails.unloadCity}}{{dataDetails.unloadArea}}{{dataDetails.unloadDetailedAddress}}
  36. </view>
  37. </view>
  38. <view class='row-between'>
  39. <view class="gray">货名</view>
  40. <view class="">{{dataDetails.goodsName}}</view>
  41. </view>
  42. <view class='row-between'>
  43. <view class="gray">距离</view>
  44. <view class="">约{{dataDetails.distance}}公里</view>
  45. </view>
  46. <!-- <view class='row-between'>
  47. <view class="gray">运费</view>
  48. <view class="">{{dataDetails.freightInfo.freight}}{{dataDetails.illingMethod==0?'元/吨':'元/车'}}</view>
  49. </view> -->
  50. <view class='row-between'>
  51. <!-- 后加 -->
  52. <view class="gray">收费比例(%)</view>
  53. <view class="">{{chargeProportion}}</view><!-- 暂时写死6% -->
  54. </view>
  55. </view>
  56. <view class="wrapper content3">
  57. <view class="qm-row">
  58. <view class="handTitle">手写签名</view>
  59. <image src="@/static/xiangpica@2x.png" mode="widthFix" @click="retDraw" class="retDraw-image"></image>
  60. <!-- <button @click="retDraw" class="delBtn">重写</button> -->
  61. </view>
  62. <view class="handCenter">
  63. <canvas class="handWriting" :disable-scroll="true" @touchstart="uploadScaleStart"
  64. @touchmove="uploadScaleMove" canvas-id="handWriting"></canvas>
  65. </view>
  66. <view class="handRight">
  67. </view>
  68. <view class="handBtn">
  69. <!-- <image @click="selectColorEvent('black','#1A1A1A')"
  70. :src="selectColor === 'black' ? '/static/other/color_black_selected.png' : '/static/other/color_black.png'"
  71. :class="[selectColor === 'black' ? 'color_select' : '', 'black-select']"></image>
  72. <image @click="selectColorEvent('red','#ca262a')"
  73. :src="selectColor === 'red' ? '/static/other/color_red_selected.png' : '/static/other/color_red.png'"
  74. :class="[selectColor === 'red' ? 'color_select' : '', 'black-select']"></image> -->
  75. <!-- <button @click="saveCanvasAsImg" class="saveBtn">保存</button> -->
  76. <view @click="$u.throttle(submit, 5000)" class="saveBtn">提交</view>
  77. <!-- <button @click="previewCanvasImg" class="previewBtn">预览</button> -->
  78. <!-- <button @click="subCanvas" class="subBtn">完成</button> -->
  79. </view>
  80. </view>
  81. <u-toast ref="uToast"></u-toast>
  82. </view>
  83. </template>
  84. <script>
  85. import {
  86. mapState
  87. } from 'vuex';
  88. var that;
  89. import uploadImage from '@/components/ossutil/uploadFile.js';
  90. export default {
  91. data() {
  92. return {
  93. isScaleStart: false,
  94. radioCustomStyle: {
  95. margin: '0 0 0 10rpx'
  96. },
  97. canvasName: 'handWriting',
  98. ctx: '',
  99. startX: null,
  100. startY: null,
  101. canvasWidth: 0,
  102. canvasHeight: 0,
  103. selectColor: 'black',
  104. lineColor: '#1A1A1A', // 颜色
  105. lineSize: 5, // 笔记倍数
  106. value: true,
  107. dataDetails: {
  108. carrierInfo: {},
  109. serviceCharge:'50'
  110. },
  111. radiolist1: [{
  112. name: '平台垫付运费',
  113. disabled: false
  114. },
  115. {
  116. name: '无需平台垫付运费',
  117. disabled: false
  118. },
  119. ],
  120. chargeProportion:"",//收费比例
  121. };
  122. },
  123. computed: {
  124. ...mapState(['hasLogin', 'userInfo', 'firstAuthentication'])
  125. },
  126. onLoad(options) {
  127. that = this
  128. // 如果登录之后没有切换到我的页面缓存不会存上,所以在这调用接口取收费比例
  129. this.$request.baseRequest('get', '/cargoOwnerInfo/firstAuthentication', {
  130. phone: this.userInfo.phone
  131. }).then(res => {
  132. uni.setStorageSync("firstAuthentication", res.data)
  133. //收费比例从缓存中取
  134. that.chargeProportion =uni.getStorageSync("firstAuthentication").chargeProportion*100
  135. })
  136. this.dataDetails = JSON.parse(decodeURIComponent(options.obj))
  137. // this.dataDetails.advanceFreightService = '平台垫付运费'
  138. this.ctx = uni.createCanvasContext("handWriting");
  139. this.$nextTick(() => {
  140. uni.createSelectorQuery().select('.handCenter').boundingClientRect(rect => {
  141. this.canvasWidth = rect.width;
  142. this.canvasHeight = rect.height;
  143. /* 将canvas背景设置为 白底,不设置 导出的canvas的背景为透明 */
  144. this.setCanvasBg('#fff');
  145. })
  146. .exec();
  147. });
  148. },
  149. methods: {
  150. submit() {
  151. if (!that.isScaleStart) {
  152. that.$refs.uToast.show({
  153. type: 'error',
  154. message: "手写签名不能为空!",
  155. })
  156. return
  157. }
  158. // if (uni.$u.test.isEmpty(that.dataDetails.freight)) {
  159. // that.$refs.uToast.show({
  160. // type: 'error',
  161. // message: "运费不能为空!",
  162. // })
  163. // return
  164. // }
  165. uni.canvasToTempFilePath({
  166. canvasId: 'handWriting',
  167. fileType: 'png',
  168. quality: 1, //图片质量
  169. success(res) {
  170. console.log(res.tempFilePath, 'canvas生成图片地址');
  171. uploadImage('image', res.tempFilePath, 'appData/',
  172. result => {
  173. // 上传成功
  174. console.log('图片地址', result)
  175. that.dataDetails.cargoOwnerAutograph = result
  176. uni.showLoading({
  177. title: '加载中',
  178. mask: true
  179. })
  180. let _obj = {}
  181. _obj.id = that.dataDetails.id
  182. _obj.submitFlag=2
  183. _obj.typeFlag = 1
  184. _obj.cargoOwnerAutograph = that.dataDetails.cargoOwnerAutograph
  185. that.$request.baseRequest('get', '/orderInfo/setPdf', _obj).then(
  186. res => {
  187. uni.hideLoading()
  188. uni.navigateBack({
  189. delta:1
  190. })
  191. if (res.code == 200) {
  192. // that.contractSrc = res.data
  193. // uni.downloadFile({
  194. // url: res.data,
  195. // success: function(res) {
  196. // var filePath = res.tempFilePath;
  197. // uni.openDocument({
  198. // filePath: filePath,
  199. // showMenu: true,
  200. // success: function(res) {
  201. // console.log('打开文档成功');
  202. // }
  203. // });
  204. // }
  205. // });
  206. // this.$refs.uToast.show({
  207. // type: 'success',
  208. // message: "提交成功",
  209. // complete() {
  210. // that.upCallback({
  211. // size: 10,
  212. // num: 1
  213. // })
  214. // }
  215. // })
  216. }
  217. })
  218. .catch(res => {
  219. uni.$u.toast(res.message);
  220. });
  221. }
  222. )
  223. }
  224. });
  225. },
  226. // change(e){
  227. // if(this.value){
  228. // this.$set(this.dataDetails,'advanceFreightService',1)
  229. // }else{
  230. // this.$set(this.dataDetails,'advanceFreightService',0)
  231. // }
  232. // },
  233. // 笔迹开始
  234. uploadScaleStart(e) {
  235. this.isScaleStart = true
  236. this.startX = e.changedTouches[0].x
  237. this.startY = e.changedTouches[0].y
  238. //设置画笔参数
  239. //画笔颜色
  240. this.ctx.setStrokeStyle(this.lineColor)
  241. //设置线条粗细
  242. this.ctx.setLineWidth(this.lineSize)
  243. //设置线条的结束端点样式
  244. this.ctx.setLineCap("round")//'butt'、'round'、'square'
  245. //开始画笔
  246. this.ctx.beginPath()
  247. },
  248. // 笔迹移动
  249. uploadScaleMove(e) {
  250. //取点
  251. let temX = e.changedTouches[0].x
  252. let temY = e.changedTouches[0].y
  253. //画线条
  254. this.ctx.moveTo(this.startX, this.startY)
  255. this.ctx.lineTo(temX, temY)
  256. this.ctx.stroke()
  257. this.startX = temX
  258. this.startY = temY
  259. this.ctx.draw(true)
  260. },
  261. /**
  262. * 重写
  263. */
  264. retDraw() {
  265. this.ctx.clearRect(0, 0, 700, 730);
  266. this.ctx.draw();
  267. //设置canvas背景
  268. this.setCanvasBg('#fff');
  269. },
  270. /**
  271. * @param {Object} str
  272. * @param {Object} color
  273. * 选择颜色
  274. */
  275. selectColorEvent(str, color) {
  276. this.selectColor = str;
  277. this.lineColor = color;
  278. },
  279. //完成
  280. subCanvas() {
  281. uni.canvasToTempFilePath({
  282. canvasId: 'handWriting',
  283. fileType: 'png',
  284. quality: 1, //图片质量
  285. success(res) {
  286. // console.log(res.tempFilePath, 'canvas生成图片地址');
  287. uni.showToast({
  288. title: '以保存'
  289. });
  290. //保存到系统相册
  291. uni.saveImageToPhotosAlbum({
  292. filePath: res.tempFilePath,
  293. success(res) {
  294. uni.showToast({
  295. title: '已成功保存到相册',
  296. duration: 2000
  297. });
  298. }
  299. });
  300. }
  301. });
  302. },
  303. //保存到相册
  304. saveCanvasAsImg() {
  305. uni.canvasToTempFilePath({
  306. canvasId: 'handWriting',
  307. fileType: 'png',
  308. quality: 1, //图片质量
  309. success(res) {
  310. console.log(res.tempFilePath, 'canvas生成图片地址');
  311. uni.saveImageToPhotosAlbum({
  312. filePath: res.tempFilePath,
  313. success(res) {
  314. uni.showToast({
  315. title: '已保存到相册',
  316. duration: 2000
  317. });
  318. }
  319. });
  320. }
  321. });
  322. },
  323. //预览
  324. previewCanvasImg() {
  325. uni.canvasToTempFilePath({
  326. canvasId: 'handWriting',
  327. fileType: 'jpg',
  328. quality: 1, //图片质量
  329. success(res) {
  330. uni.previewImage({
  331. urls: [res.tempFilePath] //预览图片 数组
  332. });
  333. }
  334. });
  335. },
  336. //设置canvas背景色 不设置 导出的canvas的背景为透明
  337. //@params:字符串 color
  338. setCanvasBg(color) {
  339. /* 将canvas背景设置为 白底,不设置 导出的canvas的背景为透明 */
  340. //rect() 参数说明 矩形路径左上角的横坐标,左上角的纵坐标, 矩形路径的宽度, 矩形路径的高度
  341. //这里是 canvasHeight - 4 是因为下边盖住边框了,所以手动减了写
  342. this.ctx.rect(0, 0, this.canvasWidth, this.canvasHeight - 4);
  343. // ctx.setFillStyle('red')
  344. this.ctx.setFillStyle(color);
  345. this.ctx.fill(); //设置填充
  346. this.ctx.draw(); //开画
  347. }
  348. }
  349. };
  350. </script>
  351. <style lang="scss" scoped>
  352. page {
  353. background: #fbfbfb;
  354. height: auto;
  355. }
  356. .content1 {
  357. background: white;
  358. border-radius: 20rpx;
  359. margin: 20rpx;
  360. padding: 30rpx 20rpx;
  361. display: flex;
  362. justify-content: space-between;
  363. .right {
  364. display: flex;
  365. }
  366. }
  367. .content2 {
  368. background: white;
  369. border-radius: 20rpx;
  370. margin: 20rpx;
  371. padding: 30rpx 20rpx;
  372. .title {
  373. font-size: 36rpx;
  374. font-weight: 700;
  375. margin-bottom: 20rpx;
  376. }
  377. .row-between {
  378. margin-bottom: 20rpx;
  379. }
  380. .left-text {
  381. margin-right: 20rpx;
  382. }
  383. .yf-input {
  384. padding-right: 10rpx;
  385. }
  386. }
  387. .content3 {
  388. background: white;
  389. border-radius: 20rpx;
  390. margin: 20rpx;
  391. padding: 30rpx 20rpx;
  392. }
  393. .place {
  394. width: 80%;
  395. text-align: right;
  396. }
  397. .handCenter {
  398. border: 4rpx dashed #e9e9e9;
  399. overflow: hidden;
  400. box-sizing: border-box;
  401. height: 500rpx;
  402. }
  403. .handWriting {
  404. background: #F9F9FB;
  405. width: 100%;
  406. height: 100%;
  407. }
  408. .handRight {
  409. display: inline-flex;
  410. align-items: center;
  411. }
  412. .handCenter {
  413. border: 4rpx dashed #e9e9e9;
  414. flex: 5;
  415. overflow: hidden;
  416. box-sizing: border-box;
  417. }
  418. .handTitle {
  419. font-size: 36rpx;
  420. color: #666;
  421. font-weight: 700;
  422. color: #333333;
  423. margin-bottom: 20rpx;
  424. }
  425. .retDraw-image {
  426. width: 50rpx;
  427. }
  428. .qm-row {
  429. display: flex;
  430. justify-content: space-between;
  431. }
  432. .saveBtn {
  433. width: 80%;
  434. background: #2772FB;
  435. color: white;
  436. text-align: center;
  437. border-radius: 50rpx;
  438. padding: 20rpx;
  439. }
  440. .handBtn {
  441. display: flex;
  442. justify-content: center;
  443. }
  444. /*
  445. .wrapper {
  446. width: 100%;
  447. height: 95vh;
  448. margin: 30rpx 0;
  449. overflow: hidden;
  450. display: flex;
  451. align-content: center;
  452. flex-direction: row;
  453. justify-content: center;
  454. font-size: 28rpx;
  455. }
  456. .handBtn button {
  457. font-size: 28rpx;
  458. }
  459. .handBtn {
  460. height: 95vh;
  461. display: inline-flex;
  462. flex-direction: column;
  463. justify-content: space-between;
  464. align-content: space-between;
  465. flex: 1;
  466. }
  467. .delBtn {
  468. position: absolute;
  469. top: 250rpx;
  470. left: 0rpx;
  471. transform: rotate(90deg);
  472. color: #666;
  473. }
  474. .delBtn image {
  475. position: absolute;
  476. top: 13rpx;
  477. left: 25rpx;
  478. }
  479. .subBtn {
  480. position: absolute;
  481. bottom: 52rpx;
  482. left: -3rpx;
  483. display: inline-flex;
  484. transform: rotate(90deg);
  485. background: #008ef6;
  486. color: #fff;
  487. margin-bottom: 30rpx;
  488. text-align: center;
  489. justify-content: center;
  490. }
  491. .saveBtn {
  492. position: absolute;
  493. top: 375rpx;
  494. left: 0rpx;
  495. transform: rotate(90deg);
  496. color: #666;
  497. }
  498. .previewBtn {
  499. position: absolute;
  500. top: 500rpx;
  501. left: 0rpx;
  502. transform: rotate(90deg);
  503. color: #666;
  504. }
  505. .uploadBtn {
  506. position: absolute;
  507. top: 625rpx;
  508. left: 0rpx;
  509. transform: rotate(90deg);
  510. color: #666;
  511. }
  512. .black-select {
  513. width: 60rpx;
  514. height: 60rpx;
  515. position: absolute;
  516. top: 30rpx;
  517. left: 25rpx;
  518. }
  519. .black-select.color_select {
  520. width: 90rpx;
  521. height: 90rpx;
  522. top: 100rpx;
  523. left: 10rpx;
  524. }
  525. .red-select {
  526. width: 60rpx;
  527. height: 60rpx;
  528. position: absolute;
  529. top: 140rpx;
  530. left: 25rpx;
  531. }
  532. .red-select.color_select {
  533. width: 90rpx;
  534. height: 90rpx;
  535. top: 120rpx;
  536. left: 10rpx;
  537. } */
  538. </style>