WebApp【公共组件库】@前端(For Git Submodule)
Tevin
2022-03-04 9b04108927c093a7f5c77610b0f5e091308b7c01
实现签名组件
3 files modified
174 ■■■■ changed files
bases/Fetcher.js 2 ●●● patch | view | raw | blame | history
forms/userSignature/CUserSignature.vue 120 ●●●●● patch | view | raw | blame | history
forms/userSignature/cUserSignature.scss 52 ●●●● patch | view | raw | blame | history
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;
                }
                // 部分路径
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') {
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%;
    }
}