From 9b04108927c093a7f5c77610b0f5e091308b7c01 Mon Sep 17 00:00:00 2001
From: Tevin <tingquanren@163.com>
Date: Fri, 04 Mar 2022 10:16:21 +0800
Subject: [PATCH] 实现签名组件

---
 forms/userSignature/cUserSignature.scss |   52 ++++++++--------
 bases/Fetcher.js                        |    2 
 forms/userSignature/CUserSignature.vue  |  120 ++++++++++++++++++++++++++++++++++++---
 3 files changed, 136 insertions(+), 38 deletions(-)

diff --git a/bases/Fetcher.js b/bases/Fetcher.js
index d850bd8..8d6a045 100644
--- a/bases/Fetcher.js
+++ b/bases/Fetcher.js
@@ -510,7 +510,7 @@
                     return path;
                 }
                 // 绝对路径
-                if (/^(\/upload|\/static|\/mini)/.test(path)) {
+                if (/^(\/upload|\/static|\/mini|\/assets)/.test(path)) {
                     return Fetcher.host + path;
                 }
                 // 部分路径
diff --git a/forms/userSignature/CUserSignature.vue b/forms/userSignature/CUserSignature.vue
index 09dbbc2..7f33abd 100644
--- a/forms/userSignature/CUserSignature.vue
+++ b/forms/userSignature/CUserSignature.vue
@@ -5,11 +5,6 @@
 
 <template>
     <view class="c-user-signature">
-        <!-- <AtSwitch
-            :title="itemRes.label"
-            :checked="itemRes.formData[itemRes.name]"
-            :onChange="evt=>itemRes.onChange(evt)"
-        /> -->
         <AtInput
             ref="input"
             :name="itemRes.name"
@@ -21,17 +16,33 @@
             ref="drawing"
             class="c-user-signature-drawing"
         >
-            <view class="button">
-                <AtIcon value="edit" />
+            <view
+                class="c-user-signature-button"
+                @tap="evt => handleStartEdit()"
+            >
+                <image
+                    class="c-user-signature-preview"
+                    v-if="itemRes.formData[itemRes.name]"
+                    mode="aspectFit"
+                    :src="itemRes.formData[itemRes.name]"
+                />
+                <AtIcon
+                    v-if="!itemRes.formData[itemRes.name]"
+                    value="edit"
+                />
             </view>
-            <text class="tips">(点击修改)</text>
         </view>
     </view>
 </template>
 
 <script>
+import Taro from '@tarojs/taro';
 import { AtInput, AtIcon } from 'taro-ui-vue';
 import { $ } from '@tarojs/extend';
+import { Fetcher } from '@components/bases/Fetcher';
+import { $fetchCommon } from '@fetchers/FCommon';
+import { $bridge } from '@components/common/Bridge';
+import project from '@project';
 import './cUserSignature.scss';
 
 export default {
@@ -45,10 +56,97 @@
         itemRes: Object,
     },
     data() {
-        return {};
+        return {
+            id: 'CUserSignatureCanvas' + Date.now() + parseInt(Math.random() * 10000),
+            cavWidth: 1000,
+            cavHeight: 1600,
+        };
     },
-    computed: {
-        className() {},
+    computed: {},
+    methods: {
+        handleStartEdit() {
+            // 混合App中
+            if (project.appHybrid) {
+                $bridge.invoking('_get_user_sign', sign => {
+                    if (!sign) {
+                        return;
+                    }
+                    const url = this._transBase64ToBlob(sign.result);
+                    this.itemRes.onChange(url);
+                });
+            }
+            // TODO: 普通h5、小程序中,使用 canvas 签名
+        },
+        _transBase64ToBlob(base64) {
+            const arr = base64.split(',');
+            const mime = arr[0].match(/:(.*?);/)[1];
+            const bstr = atob(arr[1]);
+            let n = bstr.length;
+            const u8arr = new Uint8Array(n);
+            while (n--) {
+                u8arr[n] = bstr.charCodeAt(n);
+            }
+            const blob = new Blob([u8arr], { type: mime });
+            return URL.createObjectURL(blob);
+        },
+        $uploadImage(callback) {
+            const file = {
+                url: this.itemRes.formData[this.itemRes.name],
+                fileName: 'file-' + Date.now() + '.png',
+            };
+            // 没有上传内容,视为上传成功
+            if (!file.url) {
+                callback('success');
+                return;
+            }
+            // 不是临时文件,视为上传成功
+            if (
+                file.url.indexOf('blob') < 0 &&
+                file.url.indexOf('wxfile') < 0 &&
+                file.url.indexOf('http://tmp/') < 0
+            ) {
+                callback('success');
+                return;
+            }
+            // 开始上传
+            let header = {};
+            if (process.env.TARO_ENV === 'weapp') {
+                const localCookies = JSON.parse(Taro.getStorageSync('cookies') || '{}');
+                const cookiesArr = [];
+                Object.keys(localCookies).forEach(key => {
+                    cookiesArr.push(key + '=' + localCookies[key]);
+                });
+                header['Cookie'] = cookiesArr.join('; ');
+            }
+            Taro.uploadFile({
+                url: Fetcher.host + $fetchCommon.getUploadImgURL(),
+                header,
+                filePath: file.url,
+                fileName: file.fileName,
+                name: 'file',
+                formData: {},
+                success: res => {
+                    const res2 =
+                        typeof res.data === 'string' ? JSON.parse(res.data) : res.data;
+                    if (res2.state.code === 2000) {
+                        const serverUrl = $fetchCommon.transImgPath(
+                            'fix',
+                            res2.data.src || res2.data.file || res2.data.url
+                        );
+                        this.itemRes.onChange(serverUrl);
+                        callback('success');
+                    } else {
+                        callback('error', res2.state.msg);
+                    }
+                },
+                cancel() {
+                    callback('error', '上传图片已取消!');
+                },
+                fail() {
+                    callback('error', '上传图片失败!');
+                },
+            });
+        },
     },
     mounted() {
         if (process.env.TARO_ENV === 'h5') {
diff --git a/forms/userSignature/cUserSignature.scss b/forms/userSignature/cUserSignature.scss
index 110deac..73d8c5b 100644
--- a/forms/userSignature/cUserSignature.scss
+++ b/forms/userSignature/cUserSignature.scss
@@ -16,34 +16,34 @@
     }
     .c-user-signature-drawing {
         padding: 18px 18px 18px 0;
-        .button {
+
+    }
+    .c-user-signature-button {
+        display: inline-block;
+        width: 154px;
+        height: 154px;
+        margin-left: 10px;
+        text-align: center;
+        line-height: 140px;
+        vertical-align: middle;
+        border: 1PX #d6e4ef solid;
+        border-radius: 8px;
+        .at-icon {
             display: inline-block;
-            width: 150px;
-            height: 150px;
-            margin-left: 10px;
-            text-align: center;
-            line-height: 140px;
+            width: 76px;
+            height: 76px;
+            text-transform: none;
+            text-rendering: auto;
+            line-height: 1;
+            font-size: 76px;
+            color: #cfe0ed;
+            -webkit-font-smoothing: antialiased;
             vertical-align: middle;
-            border: 1PX #d6e4ef solid;
-            border-radius: 8px;
-            .at-icon {
-                display: inline-block;
-                width: 76px;
-                height: 76px;
-                text-transform: none;
-                text-rendering: auto;
-                line-height: 1;
-                font-size: 76px;
-                color: #cfe0ed;
-                -webkit-font-smoothing: antialiased;
-                vertical-align: middle;
-                background: none;
-            }
+            background: none;
         }
-        .tips {
-            line-height: 160px;
-            vertical-align: middle;
-            color: $colorIgnore;
-        }
+    }
+    .c-user-signature-preview {
+        width: 100%;
+        height: 100%;
     }
 }
\ No newline at end of file

--
Gitblit v1.9.1