signContract.vue 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934
  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> -->
  11. <view class="content2">
  12. <view class="flex">
  13. <view class="title">合同摘要</view>
  14. <view class="preview" @click="submit(1)">预览合同</view>
  15. </view>
  16. <view class='row-between'>
  17. <view class="gray">发货单位</view>
  18. <view class="">{{dataDetails.compName?dataDetails.compName:'个人货主'}}</view>
  19. </view>
  20. <view class='row-between'>
  21. <view class="gray">发货地</view>
  22. <view class="place">
  23. {{dataDetails.sendPrivate}}{{dataDetails.sendCity}}{{dataDetails.sendArea}}{{dataDetails.sendDetailedAddress}}
  24. </view>
  25. </view>
  26. <view class='row-between'>
  27. <view class="gray">卸货地</view>
  28. <view class=" place">
  29. {{dataDetails.unloadPrivate}}{{dataDetails.unloadCity}}{{dataDetails.unloadArea}}{{dataDetails.unloadDetailedAddress}}
  30. </view>
  31. </view>
  32. <view class='row-between'>
  33. <view class="gray">货名</view>
  34. <view class="">{{dataDetails.goodsName}}</view>
  35. </view>
  36. <view class='row-between'>
  37. <view class="gray">距离</view>
  38. <view class="">约{{dataDetails.distance}}公里</view>
  39. </view>
  40. <view class='row-between'>
  41. <!-- 后加 -->
  42. <view class="gray">服务费(元)</view>
  43. <view class="">{{dataDetails.serviceCharge}}</view>
  44. </view>
  45. <view class="title">
  46. 完善信息
  47. </view>
  48. <view class='row-between'>
  49. <view class="gray">运费(元/车)</view>
  50. <!-- <view class="">{{dataDetails.freight}}{{dataDetails.illingMethod==0?'元/吨':'元/车'}}</view> -->
  51. <!-- <view class="flex"><input type="text" placeholder="请输入运费" v-model="dataDetails.freight"
  52. class="text-align-right yf-input">{{dataDetails.freight}}元/车</view> -->
  53. <view class="flex">
  54. <u--input placeholder="请输入运费" border="none" type="number" v-model="dataDetails.freight"
  55. inputAlign='right' clearable @input="preMoney"></u--input>
  56. <!-- <span> 元/车</span> -->
  57. </view>
  58. </view>
  59. <view class='row-between'>
  60. <view class="gray">车牌号</view>
  61. <view class="" :style="{'color':dataDetails.carrierInfo.carNo?'#000':':#BBBBBB'}" @click="carClick">
  62. {{dataDetails.carrierInfo.carNo?dataDetails.carrierInfo.carNo:'请选择车牌号'}}
  63. <!--< u--input placeholder="请输入车牌号" border="none" readOnly v-model="dataDetails.carrierInfo.carNo"
  64. inputAlign='right' clearable></u--input> -->
  65. </view>
  66. <!-- <view class="flex">
  67. <input class="" v-model='dataDetails.carrierInfo.carNo' @click.stop="handleShowKeyboard"
  68. :disabled="true" placeholder="输入车牌号" name="input" style="text-align: right;"></input>
  69. </view> -->
  70. </view>
  71. <view class='row-between'>
  72. <view class="gray">挂车号(选填)</view>
  73. <view class="flex">
  74. <view :style="{'color':dataDetails.trailerNumber?'#000':':#BBBBBB'}">{{dataDetails.trailerNumber?dataDetails.trailerNumber:'请输入挂车号'}}</view>
  75. <!-- <u--input placeholder="请输入挂车号" border="none" readOnly v-model="dataDetails.trailerNumber"
  76. inputAlign='right' clearable></u--input> -->
  77. </view>
  78. </view>
  79. <view class='row-between'>
  80. <view class="gray">装车净重(吨)</view>
  81. <view class="flex">
  82. <u--input placeholder="请输入装车净重" border="none" v-model="dataDetails.weight" inputAlign='right'
  83. clearable></u--input>
  84. </view>
  85. </view>
  86. <view class='row-between'>
  87. <view class="gray">运输开始日期</view>
  88. <view class="">
  89. <view @click="dateShow">{{dataDetails.tranStartDate?dataDetails.tranStartDate:'请选择运输开始日期'}}
  90. </view>
  91. <u-calendar :show="startShow" mode="single" @confirm="startDate" @close="startShow= false">
  92. </u-calendar>
  93. </view>
  94. </view>
  95. <view class='row-between'>
  96. <view class="gray">运输截止日期</view>
  97. <view class="">
  98. <!-- <u--input placeholder="请输入内容" border="none" v-model="dataDetails.value" inputAlign='right'
  99. clearable></u--input> -->
  100. <view class="" @click="endShow = true">
  101. {{dataDetails.tranEndDate?dataDetails.tranEndDate:'请选择运输截止日期'}}
  102. </view>
  103. <u-calendar :show="endShow" mode="single" @confirm="endDate" @close="endShow= false"></u-calendar>
  104. </view>
  105. </view>
  106. <view class='row-between'>
  107. <view class="gray">联络人姓名</view>
  108. <view class="">
  109. <u--input placeholder="请输入联络人姓名" border="none" v-model="dataDetails.driverName" inputAlign='right'
  110. clearable></u--input>
  111. </view>
  112. </view>
  113. <view class='row-between'>
  114. <view class="gray">联络人电话</view>
  115. <view class="">
  116. <u--input placeholder="请输入联络人电话" border="none" type="number" maxlength="11"
  117. v-model="dataDetails.driverPhone" inputAlign='right' clearable></u--input>
  118. </view>
  119. </view>
  120. <view class='row-between'>
  121. <view class="gray">装车后预付款</view>
  122. <view class="">
  123. <u--input placeholder="自动获取,不可编辑" v-if="dataDetails.freightAdvance == 1" border="none"
  124. v-model="dataDetails.advanceCharge" inputAlign='right' clearable disabled></u--input>
  125. <u--input placeholder="请输入装车后预付款" v-else border="none" v-model="dataDetails.advanceCharge"
  126. inputAlign='right' clearable></u--input>
  127. </view>
  128. </view>
  129. <view class='row-between'>
  130. <view style='width:200px;' class="gray">收款账户</view>
  131. <view style='word-wrap:break-word;word-break:normal;' class="" @click="collection">
  132. {{dataDetails.bankDeposit?dataDetails.bankDeposit:"请选择收款账户"}}
  133. (尾号{{dataDetails.bankCard?dataDetails.bankCard.substring(dataDetails.bankCard.length - 4):""}})
  134. </view>
  135. </view>
  136. </view>
  137. <view class="wrapper content3">
  138. <view class="qm-row">
  139. <view class="handTitle">手写签名</view>
  140. <image src="@/static/xiangpica@2x.png" mode="widthFix" @click="retDraw" class="retDraw-image"></image>
  141. <!-- <button @click="retDraw" class="delBtn">重写</button> -->
  142. </view>
  143. <view class="handCenter">
  144. <canvas class="handWriting" :disable-scroll="true" @touchstart="uploadScaleStart"
  145. @touchmove="uploadScaleMove" canvas-id="handWriting"></canvas>
  146. </view>
  147. <view class="handRight">
  148. </view>
  149. <view class="handBtn">
  150. <!-- <image @click="selectColorEvent('black','#1A1A1A')"
  151. :src="selectColor === 'black' ? '/static/other/color_black_selected.png' : '/static/other/color_black.png'"
  152. :class="[selectColor === 'black' ? 'color_select' : '', 'black-select']"></image>
  153. <image @click="selectColorEvent('red','#ca262a')"
  154. :src="selectColor === 'red' ? '/static/other/color_red_selected.png' : '/static/other/color_red.png'"
  155. :class="[selectColor === 'red' ? 'color_select' : '', 'black-select']"></image> -->
  156. <!-- <button @click="saveCanvasAsImg" class="saveBtn">保存</button> -->
  157. <view @click="$u.throttle(submit(), 5000)" class="saveBtn">提交</view>
  158. <!-- <button @click="previewCanvasImg" class="previewBtn">预览</button> -->
  159. <!-- <button @click="subCanvas" class="subBtn">完成</button> -->
  160. </view>
  161. </view>
  162. <u-picker :show="showCarList" :columns="carList" :closeOnClickOverlay='true' @close='selectTypeClose'
  163. @cancel='selectTypeClose' @confirm='confirmBtn'></u-picker>
  164. <master-keyboard ref="keyboard" keyboardtype="car" :show="keyShow" :randomNumber="true" :newCar="false"
  165. :defaultValue="carNumber" @keyboardClick="handleClick"></master-keyboard>
  166. <u-toast ref="uToast"></u-toast>
  167. <u-toast ref="uToast"></u-toast>
  168. </view>
  169. </template>
  170. <script>
  171. import {
  172. mapState
  173. } from 'vuex';
  174. var that;
  175. import uploadImage from '@/components/ossutil/uploadFile.js';
  176. export default {
  177. data() {
  178. return {
  179. showCarList: false,
  180. carList: [],
  181. carlistCopy: [],
  182. keyShow: false,
  183. carNumber: '',
  184. isScaleStart: false,
  185. radioCustomStyle: {
  186. margin: '0 0 0 10rpx'
  187. },
  188. canvasName: 'handWriting',
  189. ctx: "",
  190. startX: null,
  191. startY: null,
  192. canvasWidth: 0,
  193. canvasHeight: 0,
  194. selectColor: 'black',
  195. lineColor: '#1A1A1A', // 颜色
  196. lineSize: 5, // 笔记倍数
  197. value: true,
  198. dataDetails: {
  199. carrierInfo: {
  200. loadingAdvancePayment: ''
  201. },
  202. serviceCharge: '50'
  203. },
  204. radiolist1: [{
  205. name: '平台垫付运费',
  206. disabled: false
  207. },
  208. {
  209. name: '无需平台垫付运费',
  210. disabled: false
  211. },
  212. ],
  213. startShow: false,
  214. endShow: false,
  215. contractCheck: false, //判断合同是否提交
  216. proportion: "", //垫付比例
  217. };
  218. },
  219. computed: {
  220. ...mapState(['hasLogin', 'userInfo', 'firstAuthentication']),
  221. },
  222. onShow() {
  223. let payInfo = uni.getStorageSync("payInfo")
  224. if (payInfo) {
  225. this.dataDetails.bankCard = payInfo.bankCard
  226. this.dataDetails.bankDeposit = payInfo.bankDeposit
  227. this.dataDetails.bankDepositBranch = payInfo.bankDepositBranch
  228. this.dataDetails.payeeName = payInfo.payeeName
  229. } else {
  230. this.$request.baseRequest('get', '/driverPayeeInfo/getDriverPayee', {
  231. commonId: that.firstAuthentication.commonId
  232. }).then(res => {
  233. if (res.data) {
  234. this.dataDetails.bankCard = res.data.bankCard
  235. this.dataDetails.bankDeposit = res.data.bankDeposit
  236. this.dataDetails.bankDepositBranch = res.data.bankDepositBranch
  237. this.dataDetails.payeeName = res.data.payeeName
  238. }
  239. })
  240. }
  241. this.$request.baseRequest('get', '/commonUser/getSignatureAddress', {
  242. phone: this.userInfo.phone,
  243. identification: 1
  244. }).then(res => {
  245. if (res.data) {
  246. if (res.data.signImg) {
  247. // 获取远程图片,canvas无法直接绘制远程图片
  248. this.userInfo.signImg = res.data.signImg
  249. uni.getImageInfo({
  250. src: res.data.signImg,
  251. success(res) {
  252. var ctx = uni.createCanvasContext('handWriting')
  253. ctx.drawImage(res.path, 0, 0, 330, 244)
  254. ctx.save()
  255. ctx.draw()
  256. }
  257. })
  258. }
  259. }
  260. })
  261. console.log(this.dataDetails)
  262. if (this.dataDetails.carNumber) {
  263. this.$set(this.dataDetails.carrierInfo, 'carNo', this.dataDetails.carNumber)
  264. }
  265. this.preMoney()
  266. // this.$set(this.dataDetails,'advanceCharge',this.dataDetails.advanceCharge)
  267. // this.$set(this.dataDetails.carrierInfo,'carNo',this.dataDetails.carNo)
  268. console.log(this.dataDetails)
  269. },
  270. onLoad(options) {
  271. this.carList = []
  272. that = this
  273. // this.dataDetails = JSON.parse(options.obj)
  274. this.dataDetails = JSON.parse(options.obj)
  275. // console.log(this.dataDetails.carNo,this.dataDetails.carrierInfo)
  276. // this.dataDetails.advanceFreightService = '平台垫付运费'
  277. this.dataDetails = JSON.parse(decodeURIComponent(options.obj))
  278. if (this.dataDetails.hyCarrierInfo) {
  279. this.dataDetails.weight = this.dataDetails.hyCarrierInfo.loadingWeight
  280. }
  281. if (this.dataDetails.freightAdvance == 1) {
  282. this.proportion = this.dataDetails.driverAdvancePayment >= this.dataDetails.ownerAdvancePayment ? this
  283. .dataDetails.ownerAdvancePayment : this.dataDetails.driverAdvancePayment
  284. }
  285. // console.log(this.dataDetails)
  286. this.dataDetails.carrierInfo = {}
  287. this.ctx = uni.createCanvasContext("handWriting");
  288. this.$nextTick(() => {
  289. uni.createSelectorQuery().select('.handCenter').boundingClientRect(rect => {
  290. this.canvasWidth = rect.width;
  291. this.canvasHeight = rect.height;
  292. /* 将canvas背景设置为 白底,不设置 导出的canvas的背景为透明 */
  293. this.setCanvasBg('#fff');
  294. })
  295. .exec();
  296. });
  297. uni.showLoading({
  298. title: '加载中'
  299. })
  300. this.$request.baseRequest('get', '/driverCarInfo/selectDriverCar', {
  301. // driverId: that.userInfo.driverId,
  302. commonId: this.userInfo.id
  303. }).then(res => {
  304. if (res.code == '200') {
  305. uni.hideLoading()
  306. if (res.data.length > 0) {
  307. let _list = []
  308. for (let i = 0; i < res.data.length; i++) {
  309. if (res.data[i].status == '已通过') {
  310. _list.push(res.data[i].carNumber)
  311. }
  312. }
  313. that.carlistCopy = res.data
  314. that.carList = [_list]
  315. }
  316. } else {
  317. uni.$u.toast(res.message);
  318. }
  319. })
  320. .catch(res => {
  321. uni.$u.toast(res.message);
  322. });
  323. },
  324. methods: {
  325. preMoney() {
  326. if (this.dataDetails.freightAdvance == 1) {
  327. this.dataDetails.advanceCharge = this.dataDetails.freight * this.proportion
  328. }
  329. },
  330. collection() {
  331. uni.$u.route('/pages/order/bankCard');
  332. },
  333. confirmBtn(e) {
  334. this.dataDetails.carrierInfo.carNo = e.value[0]
  335. for (let i = 0; i < this.carlistCopy.length; i++) {
  336. if (e.value[0] == this.carlistCopy[i].carNumber) {
  337. this.dataDetails.trailerNumber = this.carlistCopy[i].guaCarNumber
  338. }
  339. }
  340. this.showCarList = false
  341. },
  342. selectTypeClose() {
  343. this.showCarList = false
  344. },
  345. carClick() {
  346. this.showCarList = true
  347. },
  348. //车牌号弹出键盘
  349. handleShowKeyboard() {
  350. if (!this.dataDetails.carrierInfo.carNo) {
  351. this.carNumber = ''
  352. } else {
  353. this.carNumber = this.dataDetails.carrierInfo.carNo
  354. }
  355. if (this.$refs.keyboard.open) {
  356. this.$refs.keyboard.open(false) //true 键盘显示 false 键盘隐藏
  357. } else {
  358. this.$refs.keyboard[0].open(false)
  359. }
  360. if (this.$refs.keyboard.open) {
  361. this.$refs.keyboard.open(true) //true 键盘显示 false 键盘隐藏
  362. } else {
  363. this.$refs.keyboard[0].open(true)
  364. }
  365. },
  366. //车牌号弹出键盘
  367. handleClick(e) {
  368. this.carNumber = e.value
  369. this.dataDetails.carrierInfo.carNo = e.value //键盘输入值
  370. },
  371. dateShow() {
  372. this.startShow = true
  373. },
  374. removeStart() {
  375. this.startShow = false
  376. },
  377. removeEnd() {
  378. this.endShow = false
  379. },
  380. startDate(e) {
  381. this.startShow = false
  382. this.dataDetails.tranStartDate = e[0]
  383. },
  384. endDate(e) {
  385. this.dataDetails.tranEndDate = e[0]
  386. this.endShow = false
  387. },
  388. submit(num) {
  389. let _obj = {}
  390. if (num == 1) { //预览合同
  391. _obj.submitFlag = 1
  392. this.contractCheck = false
  393. } else { //提交合同
  394. this.contractCheck = true
  395. _obj.submitFlag = 2
  396. }
  397. if (!that.isScaleStart) {
  398. if (!this.userInfo.signImg) {
  399. that.$refs.uToast.show({
  400. type: 'error',
  401. message: "手写签名不能为空!",
  402. })
  403. return
  404. }
  405. }
  406. if (uni.$u.test.isEmpty(that.dataDetails.carrierInfo.carNo)) {
  407. that.$refs.uToast.show({
  408. type: 'error',
  409. message: "车牌号不能为空!",
  410. })
  411. return
  412. }
  413. if (uni.$u.test.isEmpty(that.dataDetails.weight)) {
  414. that.$refs.uToast.show({
  415. type: 'error',
  416. message: "装车净重不能为空!",
  417. })
  418. return
  419. }
  420. if (uni.$u.test.isEmpty(that.dataDetails.freight)) {
  421. that.$refs.uToast.show({
  422. type: 'error',
  423. message: "运费不能为空!",
  424. })
  425. return
  426. }
  427. if (uni.$u.test.isEmpty(that.dataDetails.tranStartDate)) {
  428. that.$refs.uToast.show({
  429. type: 'error',
  430. message: "运输起始日期不能为空!",
  431. })
  432. return
  433. }
  434. if (uni.$u.test.isEmpty(that.dataDetails.tranEndDate)) {
  435. that.$refs.uToast.show({
  436. type: 'error',
  437. message: "运输截止日期不能为空!",
  438. })
  439. return
  440. }
  441. if (uni.$u.test.isEmpty(that.dataDetails.driverName)) {
  442. that.$refs.uToast.show({
  443. type: 'error',
  444. message: "联络人姓名不能为空!",
  445. })
  446. return
  447. }
  448. if (uni.$u.test.isEmpty(that.dataDetails.driverPhone)) {
  449. that.$refs.uToast.show({
  450. type: 'error',
  451. message: "联络人电话不能为空!",
  452. })
  453. return
  454. }
  455. if (uni.$u.test.isEmpty(that.dataDetails.advanceCharge) && that.dataDetails.advanceCharge != 0) {
  456. that.$refs.uToast.show({
  457. type: 'error',
  458. message: "装车后预付款不能为空!",
  459. })
  460. return
  461. }
  462. if (uni.$u.test.isEmpty(that.dataDetails.bankDeposit)) {
  463. that.$refs.uToast.show({
  464. type: 'error',
  465. message: "收款账号不能为空!",
  466. })
  467. return
  468. }
  469. _obj.trailerNumber = that.dataDetails.trailerNumber
  470. _obj.tranStartDate = that.dataDetails.tranStartDate
  471. _obj.tranEndDate = that.dataDetails.tranEndDate
  472. _obj.contactPersonName = that.dataDetails.driverName
  473. _obj.contactPersonPhone = that.dataDetails.driverPhone
  474. _obj.freightCars = that.dataDetails.freight
  475. // _obj.advanceCharge = that.dataDetails.advanceCharge
  476. _obj.id = that.dataDetails.id
  477. _obj.carNumber = that.dataDetails.carrierInfo.carNo
  478. _obj.weight = that.dataDetails.weight
  479. _obj.advanceCharge = that.dataDetails.advanceCharge
  480. _obj.bankCard = that.dataDetails.bankCard
  481. _obj.bankDeposit = that.dataDetails.bankDeposit
  482. _obj.bankDepositBranch = that.dataDetails.bankDepositBranch
  483. _obj.payeeName = that.dataDetails.payeeName
  484. _obj.typeFlag = 2
  485. uni.canvasToTempFilePath({
  486. canvasId: 'handWriting',
  487. fileType: 'png',
  488. quality: 1, //图片质量
  489. success(res) {
  490. uploadImage('image', res.tempFilePath, 'appData/',
  491. result => {
  492. // 上传成功
  493. that.dataDetails.cargoOwnerAutograph = result
  494. _obj.driverAutograph = result
  495. uni.showLoading({
  496. title: '加载中',
  497. mask: true
  498. })
  499. that.$request.baseRequest('get', '/orderInfo/setPdf', _obj).then(
  500. res => {
  501. if (res.code == 200) {
  502. uni.hideLoading()
  503. that.contractSrc = res.data
  504. uni.downloadFile({
  505. url: res.data,
  506. success: function(res) {
  507. var filePath = res.tempFilePath;
  508. uni.openDocument({
  509. filePath: filePath,
  510. showMenu: true,
  511. success: function(res) {
  512. console.log('打开文档成功');
  513. }
  514. });
  515. }
  516. });
  517. if (that.contractCheck) { //提交
  518. that.$refs.uToast.show({
  519. type: 'success',
  520. message: "提交成功",
  521. complete() {
  522. uni.removeStorageSync(
  523. "payInfo") //如果要有银行卡缓存就删除
  524. uni.$u.route(
  525. '/pages/order/confirmLoading', {
  526. obj: JSON.stringify(that
  527. .dataDetails),
  528. });
  529. // that.upCallback({
  530. // size: 10,
  531. // num: 1
  532. // })
  533. }
  534. })
  535. }
  536. } else {
  537. uni.$u.toast(res.message);
  538. uni.hideLoading()
  539. }
  540. })
  541. .catch(res => {
  542. uni.$u.toast(res.message);
  543. });
  544. }
  545. )
  546. }
  547. });
  548. },
  549. // change(e){
  550. // if(this.value){
  551. // this.$set(this.dataDetails,'advanceFreightService',1)
  552. // }else{
  553. // this.$set(this.dataDetails,'advanceFreightService',0)
  554. // }
  555. // },
  556. // 笔迹开始
  557. uploadScaleStart(e) {
  558. this.isScaleStart = true
  559. this.startX = e.changedTouches[0].x
  560. this.startY = e.changedTouches[0].y
  561. //设置画笔参数
  562. //画笔颜色
  563. this.ctx.setStrokeStyle(this.lineColor)
  564. //设置线条粗细
  565. this.ctx.setLineWidth(this.lineSize)
  566. //设置线条的结束端点样式
  567. this.ctx.setLineCap("round") //'butt'、'round'、'square'
  568. //开始画笔
  569. this.ctx.beginPath()
  570. },
  571. // 笔迹移动
  572. uploadScaleMove(e) {
  573. //取点
  574. let temX = e.changedTouches[0].x
  575. let temY = e.changedTouches[0].y
  576. //画线条
  577. this.ctx.moveTo(this.startX, this.startY)
  578. this.ctx.lineTo(temX, temY)
  579. this.ctx.stroke()
  580. this.startX = temX
  581. this.startY = temY
  582. this.ctx.draw(true)
  583. },
  584. /**
  585. * 重写
  586. */
  587. retDraw() {
  588. this.ctx.clearRect(0, 0, 700, 730);
  589. this.ctx.draw();
  590. //设置canvas背景
  591. this.setCanvasBg('#fff');
  592. },
  593. /**
  594. * @param {Object} str
  595. * @param {Object} color
  596. * 选择颜色
  597. */
  598. selectColorEvent(str, color) {
  599. this.selectColor = str;
  600. this.lineColor = color;
  601. },
  602. //完成
  603. subCanvas() {
  604. uni.canvasToTempFilePath({
  605. canvasId: 'handWriting',
  606. fileType: 'png',
  607. quality: 1, //图片质量
  608. success(res) {
  609. // console.log(res.tempFilePath, 'canvas生成图片地址');
  610. uni.showToast({
  611. title: '以保存'
  612. });
  613. //保存到系统相册
  614. uni.saveImageToPhotosAlbum({
  615. filePath: res.tempFilePath,
  616. success(res) {
  617. uni.showToast({
  618. title: '已成功保存到相册',
  619. duration: 2000
  620. });
  621. }
  622. });
  623. }
  624. });
  625. },
  626. //保存到相册
  627. saveCanvasAsImg() {
  628. uni.canvasToTempFilePath({
  629. canvasId: 'handWriting',
  630. fileType: 'png',
  631. quality: 1, //图片质量
  632. success(res) {
  633. console.log(res.tempFilePath, 'canvas生成图片地址');
  634. uni.saveImageToPhotosAlbum({
  635. filePath: res.tempFilePath,
  636. success(res) {
  637. uni.showToast({
  638. title: '已保存到相册',
  639. duration: 2000
  640. });
  641. }
  642. });
  643. }
  644. });
  645. },
  646. //预览
  647. previewCanvasImg() {
  648. uni.canvasToTempFilePath({
  649. canvasId: 'handWriting',
  650. fileType: 'jpg',
  651. quality: 1, //图片质量
  652. success(res) {
  653. uni.previewImage({
  654. urls: [res.tempFilePath] //预览图片 数组
  655. });
  656. }
  657. });
  658. },
  659. //设置canvas背景色 不设置 导出的canvas的背景为透明
  660. //@params:字符串 color
  661. setCanvasBg(color) {
  662. /* 将canvas背景设置为 白底,不设置 导出的canvas的背景为透明 */
  663. //rect() 参数说明 矩形路径左上角的横坐标,左上角的纵坐标, 矩形路径的宽度, 矩形路径的高度
  664. //这里是 canvasHeight - 4 是因为下边盖住边框了,所以手动减了写
  665. this.ctx.rect(0, 0, this.canvasWidth, this.canvasHeight - 4);
  666. // ctx.setFillStyle('red')
  667. this.ctx.setFillStyle(color);
  668. this.ctx.fill(); //设置填充
  669. this.ctx.draw(); //开画
  670. }
  671. }
  672. };
  673. </script>
  674. <style lang="scss" scoped>
  675. page {
  676. background: #fbfbfb;
  677. height: auto;
  678. }
  679. .content1 {
  680. background: white;
  681. border-radius: 20rpx;
  682. margin: 20rpx;
  683. padding: 30rpx 20rpx;
  684. display: flex;
  685. justify-content: space-between;
  686. .right {
  687. display: flex;
  688. }
  689. }
  690. .content2 {
  691. background: white;
  692. border-radius: 20rpx;
  693. margin: 20rpx;
  694. padding: 30rpx 20rpx;
  695. .title {
  696. font-size: 36rpx;
  697. font-weight: 700;
  698. margin-bottom: 20rpx;
  699. width: 50%;
  700. }
  701. .preview {
  702. width: 50%;
  703. text-align: right;
  704. color: #2772FB;
  705. font-size: 26rpx;
  706. }
  707. .row-between {
  708. margin-bottom: 20rpx;
  709. }
  710. .left-text {
  711. margin-right: 20rpx;
  712. }
  713. .yf-input {
  714. padding-right: 10rpx;
  715. }
  716. }
  717. .content3 {
  718. background: white;
  719. border-radius: 20rpx;
  720. margin: 20rpx;
  721. padding: 30rpx 20rpx;
  722. }
  723. .place {
  724. width: 80%;
  725. text-align: right;
  726. }
  727. .handCenter {
  728. border: 4rpx dashed #e9e9e9;
  729. overflow: hidden;
  730. box-sizing: border-box;
  731. height: 500rpx;
  732. }
  733. .handWriting {
  734. background: #F9F9FB;
  735. width: 100%;
  736. height: 100%;
  737. }
  738. .handRight {
  739. display: inline-flex;
  740. align-items: center;
  741. }
  742. .handCenter {
  743. border: 4rpx dashed #e9e9e9;
  744. flex: 5;
  745. overflow: hidden;
  746. box-sizing: border-box;
  747. }
  748. .handTitle {
  749. font-size: 36rpx;
  750. color: #666;
  751. font-weight: 700;
  752. color: #333333;
  753. margin-bottom: 20rpx;
  754. }
  755. .retDraw-image {
  756. width: 50rpx;
  757. }
  758. .qm-row {
  759. display: flex;
  760. justify-content: space-between;
  761. }
  762. .saveBtn {
  763. width: 80%;
  764. background: #2772FB;
  765. color: white;
  766. text-align: center;
  767. border-radius: 50rpx;
  768. padding: 20rpx;
  769. }
  770. .handBtn {
  771. display: flex;
  772. justify-content: center;
  773. }
  774. /*
  775. .wrapper {
  776. width: 100%;
  777. height: 95vh;
  778. margin: 30rpx 0;
  779. overflow: hidden;
  780. display: flex;
  781. align-content: center;
  782. flex-direction: row;
  783. justify-content: center;
  784. font-size: 28rpx;
  785. }
  786. .handBtn button {
  787. font-size: 28rpx;
  788. }
  789. .handBtn {
  790. height: 95vh;
  791. display: inline-flex;
  792. flex-direction: column;
  793. justify-content: space-between;
  794. align-content: space-between;
  795. flex: 1;
  796. }
  797. .delBtn {
  798. position: absolute;
  799. top: 250rpx;
  800. left: 0rpx;
  801. transform: rotate(90deg);
  802. color: #666;
  803. }
  804. .delBtn image {
  805. position: absolute;
  806. top: 13rpx;
  807. left: 25rpx;
  808. }
  809. .subBtn {
  810. position: absolute;
  811. bottom: 52rpx;
  812. left: -3rpx;
  813. display: inline-flex;
  814. transform: rotate(90deg);
  815. background: #008ef6;
  816. color: #fff;
  817. margin-bottom: 30rpx;
  818. text-align: center;
  819. justify-content: center;
  820. }
  821. .saveBtn {
  822. position: absolute;
  823. top: 375rpx;
  824. left: 0rpx;
  825. transform: rotate(90deg);
  826. color: #666;
  827. }
  828. .previewBtn {
  829. position: absolute;
  830. top: 500rpx;
  831. left: 0rpx;
  832. transform: rotate(90deg);
  833. color: #666;
  834. }
  835. .uploadBtn {
  836. position: absolute;
  837. top: 625rpx;
  838. left: 0rpx;
  839. transform: rotate(90deg);
  840. color: #666;
  841. }
  842. .black-select {
  843. width: 60rpx;
  844. height: 60rpx;
  845. position: absolute;
  846. top: 30rpx;
  847. left: 25rpx;
  848. }
  849. .black-select.color_select {
  850. width: 90rpx;
  851. height: 90rpx;
  852. top: 100rpx;
  853. left: 10rpx;
  854. }
  855. .red-select {
  856. width: 60rpx;
  857. height: 60rpx;
  858. position: absolute;
  859. top: 140rpx;
  860. left: 25rpx;
  861. }
  862. .red-select.color_select {
  863. width: 90rpx;
  864. height: 90rpx;
  865. top: 120rpx;
  866. left: 10rpx;
  867. } */
  868. // /deep/.uni-input-input:disabled {
  869. // background:#fff;
  870. // }
  871. </style>