signContract.vue 24 KB

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