123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402 |
- <template>
- <u-popup
- v-model="show"
- safe-area-inset-bottom
- border-radius="20"
- closeable
- mode="bottom">
- <view class="container">
- <view class="title">
- 签名
- </view>
- <view class="handCenter" :style="getStyle">
- <!-- v-if="show" -->
- <canvas
- class="hand-writing"
- disable-scroll
- canvas-id="__signature__canvas"
- @touchstart="uploadScaleStart"
- @touchmove="uploadScaleMove"
- @touchend="uploadScaleEnd"
- />
- </view>
- <view class="buttons">
- <text class="button button_rewrite" @click="rewrite">
- 重签
- </text>
- <text class="button button_submit linear-gradient" @click="submit">
- 提交
- </text>
- </view>
-
- <view class="safe-area" />
- </view>
- </u-popup>
- </template>
- <script>
- /**
- * this code copy from github
- * Modify by yxk
- * @see https://github.com/aoobao/signature/tree/master/components/SignaturePad
- */
- import { FileQueryOneByBatch, FileDeleteById } from 'API/file.js'
- import UPopup from './u-popup.vue'
- import Handwriting from './signature.js'
- import { BASE_URL_FN } from '@/config.js'
- const CANVAS_ID = '__signature__canvas'
- const WIDTH = 710
- export default {
- name: 'WkPopupSign',
- components: {UPopup},
- props: {
- value: {
- type: String,
- default: null
- }
- },
- data() {
- return {
- canvasId: CANVAS_ID,
- show: false,
- width: '100%',
- height: '500rpx',
-
- fileData: null,
- tempFilePath: null
- };
- },
- computed: {
- getStyle() {
- return `width:${this.width};height:${this.height};`;
- }
- },
- watch: {
- show(val) {
- if (!val) {
- // 关闭
- if (this.reject) {
- this.reject();
- }
- this.fileData = null
- this.tempFilePath = null
- }
- }
- },
- methods: {
- sign() {
- return new Promise((resolve, reject) => {
- this.resolve = resolve;
- this.reject = reject;
- if (this.value) {
- this.getImage()
- } else {
- this.initDraw()
- }
- })
- },
- initDraw(scale = 1) {
- const width = uni.upx2px(WIDTH)
- const color = '#000'
- this.width = width + 'px';
- this.height = (width / 2.6) + 'px';
- this.show = true;
- setTimeout(() => {
- let query = uni.createSelectorQuery().in(this);
- let ctx = uni.createCanvasContext(CANVAS_ID, this);
-
- this.handwriting = new Handwriting({
- lineColor: color,
- slideValue: scale,
- canvasName: CANVAS_ID,
- ctx: ctx
- });
- query
- .select('.handCenter')
- .boundingClientRect(rect => {
- this.handwriting.setSize(rect);
- this.handwriting.setBgColor('#FFFFFF')
- if (this.tempFilePath) {
- this.$nextTick(() => {
- ctx.drawImage(this.tempFilePath, 0, 0, rect.width, rect.height)
- ctx.draw() // 绘制
- this.handwriting.linePrack.push('')
- })
- }
- })
- .exec();
- }, 500);
- },
- getUrl(path) {
- let url = BASE_URL_FN() + (path.startsWith('/') ? path.replace('/', '') : path)
- const token = uni.getStorageSync('token') || ''
- const appid = uni.getStorageSync('appid') || ''
- const arr = []
-
- if (token) {
- arr.push(`c=${token}`)
- }
- if (appid) {
- arr.push(`k=${appid}`)
- }
- if (arr.length > 0) {
- return url + '?' + arr.join('&')
- } else {
- return url
- }
- },
- /**
- * 通过请求挂载图片
- */
- getImage() {
- const appid = uni.getStorageSync('appid') || ''
- const header = {
- 'Admin-Token': uni.getStorageSync('token') || ''
- }
- if (appid) {
- header.k = appid
- }
- const that = this
- FileQueryOneByBatch({
- batchId: this.value
- }).then(res => {
- if (res) {
- let path = that.getUrl(res.url)
- that.fileData = res
-
- uni.downloadFile({
- url: path,
- header,
- success: fileRes => {
- that.tempFilePath = fileRes.tempFilePath
- uni.getImageInfo({
- src: that.tempFilePath,
- success: data => {
- // console.log('imageInfo: ', data)
- uni.getSystemInfo({
- success: info => {
- const scale = uni.upx2px(WIDTH) * info.pixelRatio / data.width
- that.initDraw(scale)
- }
- })
- },
- fail: () => {
- that.initDraw()
- }
- })
- },
- fail: () => {
- that.tempFilePath = null
- that.initDraw()
- }
- })
- } else {
- that.tempFilePath = null
- that.initSign()
- }
- }).catch(() => {})
- },
-
- /**
- * 删除文件
- */
- deleteImgFile() {
- if (!this.fileData || !this.fileData.fileId) return
- const id = this.fileData.fileId
- this.fileData = null
- FileDeleteById({
- id: id
- })
- },
-
- /**
- * 上传签名图
- */
- uploadSignature(path) {
- const header = {
- 'Admin-Token': uni.getStorageSync('token') || ''
- }
- const appid = uni.getStorageSync('appid') || ''
- if (appid) {
- header.k = appid
- }
- const formData = {
- type: 'img'
- }
- if (this.value) {
- formData.batchId = this.value
- }
-
- const that = this
- const requestConfig = {
- url: BASE_URL_FN() + 'adminFile/uploadBySingle',
- fileType: 'image',
- name: 'file',
- header,
- formData,
- success: res => {
- // console.log('ddd', res)
- uni.hideLoading()
- let data = res.data
- if (typeof res.data === 'string') {
- try {
- data = JSON.parse(res.data)
- } catch (e) {
- that.$toast('网络异常,请稍后重试')
- that.reject('网络异常,请稍后重试')
- return
- }
- }
- that.fileData = data.data
- that.$emit('input', data.data.batchId)
- that.resolve(data.data.batchId)
- },
- fail: () => {
- uni.hideLoading()
- that.$toast('上传失败')
- that.reject('上传失败')
- }
- }
- requestConfig.filePath = path
-
- uni.uploadFile(requestConfig)
- },
-
- close() {
- this.show = false;
- },
- rewrite() {
- this.handwriting.clear();
- },
- submit() {
- let self = this;
- if (this.handwriting.isEmpty()) {
- // 未签字
- self.deleteImgFile()
- self.$emit('input', null)
- self.resolve(null)
- self.reject = null
- self.show = false
- return
- }
- uni.getSystemInfo({
- success: info => {
- self.canvasToTempPath(info.pixelRatio)
- },
- fail: () => {
- self.canvasToTempPath(3)
- }
- })
- },
- canvasToTempPath(pixelRatio = 3) {
- let self = this;
- const w = Number(self.width.replace('px', ''))
- const h = Number(self.height.replace('px', ''))
- uni.canvasToTempFilePath(
- {
- canvasId: CANVAS_ID,
- quality: 1.0,
- fileType: 'png',
- x: 0,
- y: 0,
- width: w,
- height: h,
- destWidth: w * pixelRatio,
- destHeight: h * pixelRatio,
- success(res) {
- console.log(res.tempFilePath)
- let path = res.tempFilePath;
- self.reject = null;
- self.uploadSignature(path);
- },
- fail(err) {
- let reject = self.reject;
- self.reject = null;
- reject({ type: 'err', err: err });
- },
- complete() {
- // 失败关闭
- self.show = false;
- }
- },
- this
- );
- },
- uploadScaleStart(event) {
- this.handwriting.uploadScaleStart(event);
- },
- uploadScaleMove(event) {
- this.handwriting.uploadScaleMove(event);
- },
- uploadScaleEnd(event) {
- this.handwriting.uploadScaleEnd(event);
- }
- }
- };
- </script>
- <style scoped lang="scss">
- .container {
- width: 100%;
- /* height: 822rpx; */
- position: relative;
- background-color: #fff;
- overflow: hidden;
- }
- .title {
- width: 100%;
- display: flex;
- justify-content: center;
- color: $dark;
- font-size: $wk-font-large;
- font-weight: bold;
- margin-top: 25rpx;
- }
- .handCenter {
- margin: 25rpx auto 0;
- border: 1px dashed #979797;
- }
- .hand-writing {
- width: 100%;
- height: 100%;
- }
- .safe-area {
- width: 100%;
- height: 0;
- height: constant(safe-area-inset-bottom);
- height: env(safe-area-inset-bottom);
- }
- .buttons {
- width: 80%;
- margin: 25rpx auto;
- display: flex;
- justify-content: space-between;
- }
- .buttons .button {
- width: 200rpx;
- height: 60rpx;
- display: flex;
- justify-content: center;
- align-items: center;
- border-radius: 14rpx;
- font-size: $wk-font-base;
- }
- .buttons .button.button_rewrite {
- border: 1px solid $theme-color;
- background-color: #ffffff;
- color: $theme-color;
- }
- .buttons .button.button_submit {
- color: #fff;
- border: 0 none;
- }
- </style>
|