fhrons-mobile-next 2.0.0 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.poc +8 -0
- package/assets/css/colors.js +6 -0
- package/assets/css/customVant.less +60 -0
- package/assets/css/extra.css +32 -0
- package/assets/css/global.css +1 -0
- package/assets/css/global.less +1637 -0
- package/assets/css/index.js +63 -0
- package/assets/css/static.less +607 -0
- package/assets/js/func.js +361 -0
- package/assets/js/globalData.js +18 -0
- package/assets/js/qywxapi.js +484 -0
- package/{packages → assets/js}/storage.js +1 -20
- package/assets/js/upload.js +269 -0
- package/assets/js/validate.js +48 -0
- package/assets/js/vant.js +39 -0
- package/assets/js/wxapi.js +297 -0
- package/assets/vantLang/index.js +172 -0
- package/assets/vantLang/lib/en-US.js +95 -0
- package/assets/vantLang/lib/es-ES.js +95 -0
- package/assets/vantLang/lib/pt-PT.js +96 -0
- package/assets/vantLang/lib/zh-CN.js +96 -0
- package/assets/vantLang/lib/zh-HK.js +96 -0
- package/assets/vantLang/locales/en_US.js +102 -0
- package/assets/vantLang/locales/es_ES.js +102 -0
- package/assets/vantLang/locales/index.js +12 -0
- package/assets/vantLang/locales/pt_PT.js +102 -0
- package/assets/vantLang/locales/zh_CN.js +102 -0
- package/assets/vantLang/locales/zh_T.js +102 -0
- package/babel.config.js +15 -0
- package/index.js +68 -33
- package/inject-env-plugin.js +29 -0
- package/package.json +46 -32
- package/packages/areaMobile/index.js +5 -0
- package/packages/areaMobile/index.vue +260 -0
- package/packages/autoGraph/VueEsign.vue +309 -0
- package/packages/autoGraph/index.js +5 -0
- package/packages/autoGraph/index.vue +472 -0
- package/packages/commonForm/CommonAsyncAreaPicker.vue +223 -0
- package/packages/commonForm/CommonDatePicker.vue +152 -0
- package/packages/commonForm/CommonForm.vue +786 -0
- package/packages/commonForm/CommonFullTimePicker.vue +137 -0
- package/packages/commonForm/CommonSinglePicker.vue +121 -0
- package/packages/commonForm/CommonYearMonthPicker.vue +127 -0
- package/packages/commonForm/index.js +33 -0
- package/packages/dialog/index.js +32 -0
- package/packages/dialog/index.vue +379 -0
- package/packages/index.js +7 -3
- package/packages/introduce/index.js +5 -0
- package/packages/introduce/index.vue +31 -0
- package/packages/loading/Loading.vue +70 -0
- package/packages/loading/index.js +43 -0
- package/packages/mindMap/index.js +5 -0
- package/packages/mindMap/index.vue +437 -0
- package/packages/pdfViewer/index.js +12 -0
- package/packages/pdfViewer/index.vue +131 -0
- package/packages/sharePanel/SheetPanel.vue +316 -0
- package/packages/sharePanel/index.js +5 -0
- package/packages/sharePanel/index.vue +476 -0
- package/packages/sharePanel/props.js +58 -0
- package/packages/sharePanel/utils/QyWxShareMixin.js +93 -0
- package/packages/sharePanel/utils/shareWay.js +81 -0
- package/packages/theme/index copy.js +89 -0
- package/packages/theme/index.js +38 -0
- package/packages/theme/theme.css +910 -0
- package/packages/theme/theme.less +26 -0
- package/packages/uploadFile/VanUploadFile.vue +80 -0
- package/packages/uploadFile/index.js +5 -0
- package/packages/uploadFile/index.vue +725 -0
- package/packages/uploadFile/vanUpload.js +5 -0
- package/packages/verify/Verify/VerifyPoints.vue +247 -0
- package/packages/verify/Verify/VerifySlide.vue +364 -0
- package/packages/verify/index.js +5 -0
- package/packages/verify/index.vue +416 -0
- package/packages/verify/utils/verify.js +53 -0
- package/packages/videoPage/index.js +5 -0
- package/packages/videoPage/index.vue +440 -0
- package/plugins/sensors/fhsensors.js +84 -0
- package/plugins/sensors/sensors.js +175 -0
- package/plugins/sensors/sensorsFun.js +1387 -0
- package/fhrons-mobile-next-2.0.0.tgz +0 -0
- package/packages/fhImage/index.js +0 -5
- package/packages/fhImage/index.vue +0 -57
- package/packages/fhPresetImage/index.js +0 -5
- package/packages/fhPresetImage/index.vue +0 -39
- package/packages/html2canvas/index.js +0 -29
- package/upload copy.js +0 -468
- package/utils/tools.js +0 -22
- /package/{dist → fhcommon/dist}/fhcommon.min.js +0 -0
- /package/{dist → fhcommon/dist}/fhcommon.min.js.LICENSE.txt +0 -0
- /package/{upload.js → fhcommon/upload.js} +0 -0
|
@@ -0,0 +1,472 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div id="Autograph" class="ps-r">
|
|
3
|
+
<!-- 横屏 -->
|
|
4
|
+
<div v-if="showLandscape" class="landscape pd20 border-box resolve-ios">
|
|
5
|
+
<vue-esign id="myCanvas" ref="esign" class="my-canvas border-radius8 full-content" :width="canvasWidth" :height="canvasHeight" :is-crop="isCrop" :line-width="lineWidth" :line-color="lineColor" :bg-color.sync="bgColor" @getStrokeCount="(val)=>$emit('getStrokeCount',val)">
|
|
6
|
+
<!-- 全屏按钮 -->
|
|
7
|
+
<template slot="fullscreen">
|
|
8
|
+
<button v-show="!imgUrl" class="verticalscape-btn-item ft14" round size="mini" @click.prevent.stop="backClick">
|
|
9
|
+
<i class="iconfont icon-shuping ft16 c-7f808a"></i>
|
|
10
|
+
{{ $t("autograph.index.d1ck6g") }}
|
|
11
|
+
</button>
|
|
12
|
+
</template>
|
|
13
|
+
<!-- 遮罩层 -->
|
|
14
|
+
<template slot="cover">
|
|
15
|
+
<div v-show="showCover" class="cover ps-a border-radius8 full-content" />
|
|
16
|
+
</template>
|
|
17
|
+
<!-- 背景 -->
|
|
18
|
+
<template slot="background">
|
|
19
|
+
<div class="ps-a top0 full-content flex-center z-index-1 watermark">
|
|
20
|
+
<div class="ta-c c-e8e8e8 ft32 line-height36 fw-500">
|
|
21
|
+
<p class="mg0">{{$t('autograph.index.2spt3x')}}</p>
|
|
22
|
+
<p class="mg0">{{$t('autograph.index.uc44d7')}}</p>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
</template>
|
|
26
|
+
</vue-esign>
|
|
27
|
+
</div>
|
|
28
|
+
<!-- 竖屏 -->
|
|
29
|
+
<div v-else>
|
|
30
|
+
<!-- content-width -->
|
|
31
|
+
<vue-esign id="myCanvas" ref="esign" class="mtb20 border-radius8" :class="[esignClass]" :width="width" :height="height ? height : width / ratio" :is-crop="isCrop" :line-width="lineWidth" :line-color="lineColor" :bg-color.sync="bgColor" @getStrokeCount="(val)=>$emit('getStrokeCount',val)">
|
|
32
|
+
<!-- 全屏按钮 -->
|
|
33
|
+
<template v-if="fullscreen" slot="fullscreen">
|
|
34
|
+
<button v-show="!imgUrl" class="landscape-btn-item ft14" round size="mini" @click.prevent.stop="landspaceClick">
|
|
35
|
+
{{ $t("team.vueorg.25kc2t") }}
|
|
36
|
+
<i class="iconfont icon-hengping ft16 c-7f808a"></i>
|
|
37
|
+
</button>
|
|
38
|
+
</template>
|
|
39
|
+
<!-- 遮罩层 -->
|
|
40
|
+
<template slot="cover">
|
|
41
|
+
<div v-show="showCover" class="cover ps-a border-radius8 full-content" />
|
|
42
|
+
</template>
|
|
43
|
+
<!-- 背景 -->
|
|
44
|
+
<template v-if="showBgText" slot="background">
|
|
45
|
+
<div class="ps-a top0 full-content flex-center z-index-1">
|
|
46
|
+
<div class="ta-c c-e8e8e8 ft24 line-height36 fw-500">
|
|
47
|
+
<p v-if="bgText" class="mg0">{{ bgText }}</p>
|
|
48
|
+
<div>
|
|
49
|
+
<p class="mg0">{{$t('autograph.index.2spt3x')}}</p>
|
|
50
|
+
<p class="mg0">{{$t('autograph.index.uc44d7')}}</p>
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
</template>
|
|
55
|
+
<!-- 回显图 -->
|
|
56
|
+
<template slot="backView">
|
|
57
|
+
<img v-if="judgeEmpty(imgUrl)" class="cover ps-a border-radius8 full-content" :src="imgUrl" alt="" />
|
|
58
|
+
</template>
|
|
59
|
+
</vue-esign>
|
|
60
|
+
</div>
|
|
61
|
+
<!-- 按钮组 -->
|
|
62
|
+
<div class="btn-list flex-center-end" :class="showLandscape ? 'btn-landscape' : ''">
|
|
63
|
+
<van-button v-if="showLandscape" class="btn-item" :disabled="backBtnDisabled" round size="mini" @click="backClick">{{ backText }}</van-button>
|
|
64
|
+
<van-button class="btn-item" round size="mini" :disabled="resetBtnDisabled" @click="handleReset">{{ resetText }}</van-button>
|
|
65
|
+
<van-button class="btn-item fw-500" round :color="originColor ? '#158CFF' : ''" :loading="judgeEmpty(loadingText) && showLandscape" type="info" :disabled="confirmBtnDisabled" size="mini" :loading-text="loadingText" @click="handleGenerate">{{ confirmText }}</van-button>
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|
|
68
|
+
</template>
|
|
69
|
+
|
|
70
|
+
<script>
|
|
71
|
+
import { dataURLtoFile, getRootFontSize, notEmpty } from "../../assets/js/func";
|
|
72
|
+
// import upload, { compressFile } from "../../assets/js/upload";
|
|
73
|
+
import vueEsign from "./VueEsign.vue";
|
|
74
|
+
export default {
|
|
75
|
+
// 组件名称
|
|
76
|
+
name: "AutoGraph",
|
|
77
|
+
components: { vueEsign },
|
|
78
|
+
// 组件参数 接收来自父组件的数据
|
|
79
|
+
props: {
|
|
80
|
+
imgUrl: {
|
|
81
|
+
// 需要回显图片时的图片地址
|
|
82
|
+
type: String,
|
|
83
|
+
default: () => "",
|
|
84
|
+
},
|
|
85
|
+
originColor: {
|
|
86
|
+
// 确认按钮是否使用默认的蓝色
|
|
87
|
+
type: Boolean,
|
|
88
|
+
default: false,
|
|
89
|
+
},
|
|
90
|
+
width: {
|
|
91
|
+
type: Number,
|
|
92
|
+
default: 800,
|
|
93
|
+
},
|
|
94
|
+
height: {
|
|
95
|
+
type: Number,
|
|
96
|
+
default: 300,
|
|
97
|
+
},
|
|
98
|
+
ratio: {
|
|
99
|
+
type: Number,
|
|
100
|
+
default: 16 / 9,
|
|
101
|
+
},
|
|
102
|
+
confirmText: {
|
|
103
|
+
type: String,
|
|
104
|
+
default: function () {
|
|
105
|
+
return this.$t("productcomponents.compareproup.tg417c");
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
resetText: {
|
|
109
|
+
type: String,
|
|
110
|
+
default: function () {
|
|
111
|
+
return this.$t("database.database.5t6384");
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
backText: {
|
|
115
|
+
type: String,
|
|
116
|
+
default: function () {
|
|
117
|
+
return this.$t("orderfind.creatfind.3ss7pp");
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
fullscreen: {
|
|
121
|
+
type: Boolean,
|
|
122
|
+
default: function () {
|
|
123
|
+
return true;
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
showBgText: {
|
|
127
|
+
type: Boolean,
|
|
128
|
+
default: function () {
|
|
129
|
+
return true;
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
bgText: {
|
|
133
|
+
type: String,
|
|
134
|
+
default: () => "",
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
// 组件状态值
|
|
138
|
+
data() {
|
|
139
|
+
return {
|
|
140
|
+
rem: getRootFontSize(),
|
|
141
|
+
lineWidth: 3,
|
|
142
|
+
lineColor: "#000000",
|
|
143
|
+
bgColor: "rgba(0,0,0,0)",
|
|
144
|
+
resultImg: "",
|
|
145
|
+
isCrop: false,
|
|
146
|
+
confirmBtnDisabled: true,
|
|
147
|
+
backBtnDisabled: false,
|
|
148
|
+
resetBtnDisabled: false,
|
|
149
|
+
showWaterMark: true, // 是否展示水印
|
|
150
|
+
showCover: false,
|
|
151
|
+
// 横屏
|
|
152
|
+
showLandscape: false,
|
|
153
|
+
loadingText: "",
|
|
154
|
+
canvasWidth: 286,
|
|
155
|
+
canvasHeight: 619,
|
|
156
|
+
screenWidth: document.documentElement.clientWidth || document.body.clientWidth,
|
|
157
|
+
screenHeight: document.documentElement.clientHeight || document.body.clientHeight,
|
|
158
|
+
isTranslateImg: false,
|
|
159
|
+
eventName: "touchstart",
|
|
160
|
+
esignClass: "",
|
|
161
|
+
};
|
|
162
|
+
},
|
|
163
|
+
// 侦听器
|
|
164
|
+
watch: {
|
|
165
|
+
imgUrl: {
|
|
166
|
+
handler(newVal, oldVal) {
|
|
167
|
+
if (newVal) {
|
|
168
|
+
this.showCover = true;
|
|
169
|
+
this.landscapeBtnDisabled = true;
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
screenWidth(val) {
|
|
174
|
+
this.canvasWidth = parseInt(val) - (89 / 37.5) * this.rem;
|
|
175
|
+
},
|
|
176
|
+
screenHeight(val) {
|
|
177
|
+
this.canvasHeight = parseInt(val) - (48 / 37.5) * this.rem;
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
mounted() {
|
|
181
|
+
this.eventName = this.$globalData.isWeb() ? "mousedown" : "touchstart";
|
|
182
|
+
this.addEvent(this.eventName);
|
|
183
|
+
|
|
184
|
+
// 计算已渲染的签名区域的宽度
|
|
185
|
+
this.esignClass = this.$refs.esign.$el.clientWidth > this.width ? "content-width" : "";
|
|
186
|
+
},
|
|
187
|
+
beforeDestroy() {
|
|
188
|
+
window.removeEventListener(this.eventName, this.resetMarkClick);
|
|
189
|
+
},
|
|
190
|
+
// 组件方法
|
|
191
|
+
methods: {
|
|
192
|
+
addEvent(eventName) {
|
|
193
|
+
this.$refs.esign.$el.addEventListener(eventName, this.resetMarkClick);
|
|
194
|
+
},
|
|
195
|
+
judgeEmpty(val) {
|
|
196
|
+
return notEmpty(val);
|
|
197
|
+
},
|
|
198
|
+
resetMarkClick() {
|
|
199
|
+
if (this.showCover) return;
|
|
200
|
+
// debugger
|
|
201
|
+
this.setStatus(false);
|
|
202
|
+
},
|
|
203
|
+
setStatus(status) {
|
|
204
|
+
this.showWaterMark = status;
|
|
205
|
+
this.confirmBtnDisabled = status;
|
|
206
|
+
},
|
|
207
|
+
// 点击返回
|
|
208
|
+
backClick() {
|
|
209
|
+
this.showLandscape = false;
|
|
210
|
+
this.setStatus(true);
|
|
211
|
+
this.$nextTick(() => {
|
|
212
|
+
this.$refs.esign.$el.addEventListener(this.eventName, this.resetMarkClick);
|
|
213
|
+
});
|
|
214
|
+
this.showCover = notEmpty(this.imgUrl);
|
|
215
|
+
if (notEmpty(this.imgUrl)) {
|
|
216
|
+
this.isTranslateImg = true;
|
|
217
|
+
}
|
|
218
|
+
},
|
|
219
|
+
// 点击此处签名
|
|
220
|
+
markClick() {
|
|
221
|
+
this.showWaterMark = false;
|
|
222
|
+
},
|
|
223
|
+
handleReset() {
|
|
224
|
+
if (this.$refs.esign) {
|
|
225
|
+
this.$refs.esign.reset();
|
|
226
|
+
}
|
|
227
|
+
this.isTranslateImg = false;
|
|
228
|
+
this.showWaterMark = true;
|
|
229
|
+
this.confirmBtnDisabled = true;
|
|
230
|
+
this.showCover = false;
|
|
231
|
+
this.$emit("handleSignImgUrl", "", "reset");
|
|
232
|
+
},
|
|
233
|
+
handleGenerate() {
|
|
234
|
+
this.$loading(this.$t("commonpage.autograph.idx683"));
|
|
235
|
+
this.$refs.esign
|
|
236
|
+
.generate()
|
|
237
|
+
.then(async (res) => {
|
|
238
|
+
if (this.showLandscape) res = await this.rotateBase64Img(res, -90);
|
|
239
|
+
const blob = dataURLtoFile(res);
|
|
240
|
+
let file = new window.File([blob], `${new Date().valueOf()}.jpg`, {
|
|
241
|
+
type: blob.type,
|
|
242
|
+
});
|
|
243
|
+
file = await FHCommon.compressFile(file);
|
|
244
|
+
// this.$loading('上传图片中...');
|
|
245
|
+
this.loadingText = this.$t("aqcomponents.copyimage.6v3rh2");
|
|
246
|
+
this.setBtnDisabledStatus(true);
|
|
247
|
+
// return;
|
|
248
|
+
try {
|
|
249
|
+
const data = await FHCommon.upload({ file });
|
|
250
|
+
console.log(axios.interceptors.request);
|
|
251
|
+
console.log(data);
|
|
252
|
+
// 上传成功
|
|
253
|
+
this.$loading(false);
|
|
254
|
+
this.loadingText = "";
|
|
255
|
+
this.confirmBtnDisabled = true;
|
|
256
|
+
this.showCover = true;
|
|
257
|
+
this.setBtnDisabledStatus(false);
|
|
258
|
+
// 提交图片到父页面
|
|
259
|
+
this.$emit("handleSignImgUrl", data, "handle");
|
|
260
|
+
} catch (err) {
|
|
261
|
+
this.setBtnDisabledStatus(false);
|
|
262
|
+
this.confirmBtnDisabled = false;
|
|
263
|
+
this.$loading(false);
|
|
264
|
+
this.loadingText = "";
|
|
265
|
+
this.$toast(this.$t('autograph.index.2lkog6'));
|
|
266
|
+
}
|
|
267
|
+
})
|
|
268
|
+
.catch((err) => {
|
|
269
|
+
this.$loading(false);
|
|
270
|
+
this.$toast(err); // 画布没有签字时会执行这里 'Not Signned'
|
|
271
|
+
});
|
|
272
|
+
},
|
|
273
|
+
landspaceClick() {
|
|
274
|
+
this.showLandscape = true;
|
|
275
|
+
this.showCover = false;
|
|
276
|
+
this.canvasWidth = parseInt(this.screenWidth - 56 - 20); // 横屏的签名区域宽度是设备宽度减去左右padding
|
|
277
|
+
this.canvasHeight = parseInt(this.screenHeight - 20 * 2); // 横屏高度等于设备高度减去上下padding
|
|
278
|
+
this.setStatus(true);
|
|
279
|
+
this.showWaterMark = false;
|
|
280
|
+
this.$nextTick(() => {
|
|
281
|
+
this.$refs.esign.$el.addEventListener(this.eventName, this.resetMarkClick);
|
|
282
|
+
});
|
|
283
|
+
},
|
|
284
|
+
setBtnDisabledStatus(status) {
|
|
285
|
+
this.resetBtnDisabled = status;
|
|
286
|
+
this.backBtnDisabled = status;
|
|
287
|
+
},
|
|
288
|
+
rotateBase64Img(src, edg) {
|
|
289
|
+
return new Promise((resolve, reject) => {
|
|
290
|
+
const canvas = document.createElement("canvas");
|
|
291
|
+
const ctx = canvas.getContext("2d");
|
|
292
|
+
|
|
293
|
+
let imgW; // 图片宽度
|
|
294
|
+
let imgH; // 图片高度
|
|
295
|
+
let size; // canvas初始大小
|
|
296
|
+
|
|
297
|
+
if (edg % 90 !== 0) {
|
|
298
|
+
console.error(this.$t("commonpage.autograph.06tb77"));
|
|
299
|
+
throw this.$t("commonpage.autograph.06tb77");
|
|
300
|
+
}
|
|
301
|
+
edg < 0 && (edg = (edg % 360) + 360);
|
|
302
|
+
const quadrant = (edg / 90) % 4; // 旋转象限
|
|
303
|
+
const cutCoor = { sx: 0, sy: 0, ex: 0, ey: 0 }; // 裁剪坐标
|
|
304
|
+
|
|
305
|
+
const image = new Image();
|
|
306
|
+
image.crossOrigin = "anonymous";
|
|
307
|
+
image.src = src;
|
|
308
|
+
|
|
309
|
+
image.onload = function () {
|
|
310
|
+
imgW = image.width;
|
|
311
|
+
imgH = image.height;
|
|
312
|
+
size = imgW > imgH ? imgW : imgH;
|
|
313
|
+
|
|
314
|
+
canvas.width = size * 2;
|
|
315
|
+
canvas.height = size * 2;
|
|
316
|
+
switch (quadrant) {
|
|
317
|
+
case 0:
|
|
318
|
+
cutCoor.sx = size;
|
|
319
|
+
cutCoor.sy = size;
|
|
320
|
+
cutCoor.ex = size + imgW;
|
|
321
|
+
cutCoor.ey = size + imgH;
|
|
322
|
+
break;
|
|
323
|
+
case 1:
|
|
324
|
+
cutCoor.sx = size - imgH;
|
|
325
|
+
cutCoor.sy = size;
|
|
326
|
+
cutCoor.ex = size;
|
|
327
|
+
cutCoor.ey = size + imgW;
|
|
328
|
+
break;
|
|
329
|
+
case 2:
|
|
330
|
+
cutCoor.sx = size - imgW;
|
|
331
|
+
cutCoor.sy = size - imgH;
|
|
332
|
+
cutCoor.ex = size;
|
|
333
|
+
cutCoor.ey = size;
|
|
334
|
+
break;
|
|
335
|
+
case 3:
|
|
336
|
+
cutCoor.sx = size;
|
|
337
|
+
cutCoor.sy = size - imgW;
|
|
338
|
+
cutCoor.ex = size + imgH;
|
|
339
|
+
cutCoor.ey = size + imgW;
|
|
340
|
+
break;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
ctx.translate(size, size);
|
|
344
|
+
ctx.rotate((edg * Math.PI) / 180);
|
|
345
|
+
ctx.drawImage(image, 0, 0);
|
|
346
|
+
|
|
347
|
+
const imgData = ctx.getImageData(cutCoor.sx, cutCoor.sy, cutCoor.ex, cutCoor.ey);
|
|
348
|
+
if (quadrant % 2 === 0) {
|
|
349
|
+
canvas.width = imgW;
|
|
350
|
+
canvas.height = imgH;
|
|
351
|
+
} else {
|
|
352
|
+
canvas.width = imgH;
|
|
353
|
+
canvas.height = imgW;
|
|
354
|
+
}
|
|
355
|
+
ctx.putImageData(imgData, 0, 0);
|
|
356
|
+
resolve(canvas.toDataURL());
|
|
357
|
+
};
|
|
358
|
+
});
|
|
359
|
+
},
|
|
360
|
+
},
|
|
361
|
+
};
|
|
362
|
+
</script>
|
|
363
|
+
<style scoped lang="less">
|
|
364
|
+
#Autograph {
|
|
365
|
+
.btn-list {
|
|
366
|
+
.btn-item {
|
|
367
|
+
min-width: 68px;
|
|
368
|
+
height: 24px;
|
|
369
|
+
margin-left: 0.3rem;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// 签名区域
|
|
374
|
+
#myCanvas {
|
|
375
|
+
display: block;
|
|
376
|
+
box-sizing: border-box;
|
|
377
|
+
background-color: transparent;
|
|
378
|
+
z-index: 2;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
.watermark {
|
|
382
|
+
transform: rotate(90deg);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
.cover {
|
|
386
|
+
left: 0;
|
|
387
|
+
top: 0;
|
|
388
|
+
background-color: rgba(224, 224, 224, 0.5);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
.landscape-btn-item {
|
|
392
|
+
font-size: 14px;
|
|
393
|
+
line-height: 20px;
|
|
394
|
+
position: absolute;
|
|
395
|
+
right: 12px;
|
|
396
|
+
top: 17px;
|
|
397
|
+
z-index: 5;
|
|
398
|
+
background: transparent;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
.verticalscape-btn-item {
|
|
402
|
+
position: absolute;
|
|
403
|
+
font-size: 14px;
|
|
404
|
+
transform: rotate(90deg);
|
|
405
|
+
bottom: 24px;
|
|
406
|
+
right: -8px;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
.hengping-icon {
|
|
410
|
+
width: 16px;
|
|
411
|
+
height: 16px;
|
|
412
|
+
position: relative;
|
|
413
|
+
top: -2px;
|
|
414
|
+
margin-left: 5px;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
.landscape {
|
|
418
|
+
position: fixed;
|
|
419
|
+
width: 100vw;
|
|
420
|
+
height: 100vh;
|
|
421
|
+
left: 0;
|
|
422
|
+
top: 0;
|
|
423
|
+
right: 0;
|
|
424
|
+
bottom: 0;
|
|
425
|
+
z-index: 9999;
|
|
426
|
+
background: #fff;
|
|
427
|
+
padding-left: 56px;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
.resolve-ios {
|
|
431
|
+
-webkit-transform: translateZ(1px);
|
|
432
|
+
-moz-transform: translateZ(1px);
|
|
433
|
+
-o-transform: translateZ(1px);
|
|
434
|
+
transform: translateZ(1px);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
.my-canvas {
|
|
438
|
+
margin-left: 0;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
// .landscape .cover {
|
|
442
|
+
// margin-left: 49px + 20px;
|
|
443
|
+
// margin-top: 20px;
|
|
444
|
+
// }
|
|
445
|
+
|
|
446
|
+
.btn-landscape,
|
|
447
|
+
.mark-landscape {
|
|
448
|
+
position: fixed;
|
|
449
|
+
left: -80px;
|
|
450
|
+
z-index: 99999;
|
|
451
|
+
bottom: 133px;
|
|
452
|
+
-webkit-transform: translateZ(1px) rotate(90deg);
|
|
453
|
+
-moz-transform: translateZ(1px) rotate(90deg);
|
|
454
|
+
-o-transform: translateZ(1px) rotate(90deg);
|
|
455
|
+
transform: translateZ(1px) rotate(90deg);
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
.mark-landscape {
|
|
459
|
+
transform: rotate(90deg);
|
|
460
|
+
top: calc(50% - 0.4rem);
|
|
461
|
+
left: 0px !important;
|
|
462
|
+
transform-origin: calc(100vw - 40px) 20px;
|
|
463
|
+
width: calc(100vh - 40px) !important;
|
|
464
|
+
height: 2.4rem;
|
|
465
|
+
line-height: 2.4rem;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
.border-radius8 {
|
|
469
|
+
border-radius: 8px;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
</style>
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
<!-- 功能:功能描述; 作者:LZJ; 时间:2021年11月11日 20:39:12-->
|
|
2
|
+
<template>
|
|
3
|
+
<div id="CommonAsyncAreaPicker">
|
|
4
|
+
<van-field v-show="item.show !== false" :ref="item['prop']" v-model="model[item['prop']]" :label-class="item.labelClass" :label-width="item.labelWidth" :class="[item.class, underLine ? 'underLine' : '']" :input-align="item.inputAlign || 'right'" class="field-select" :required="item.required" readonly :type="item.displayType || 'textarea'" :rows="item.displayRows || '1'" :autosize="typeof item.autosize === 'function' ? item.autosize() : true" :right-icon="item.readOnly ? '' : item.rightIcon ? item.rightIcon : 'arrow'" :label="item.title" :name="item.prop" :rules="item.rule" :value="value" :placeholder="item.placeholder || $t('financialinfo.carinfo.42bfwl')" @input="fieldChange($event, item, model)" @click="clickEvent($event, item)">
|
|
5
|
+
<template #label>
|
|
6
|
+
<span v-if="item.rule && item.rule[0].required" class="c-ff5c5c ft14 line-height21">*</span>
|
|
7
|
+
<span>{{ item.title }}</span>
|
|
8
|
+
</template>
|
|
9
|
+
</van-field>
|
|
10
|
+
<van-popup v-model="showPop" round position="bottom" :closeable="true" get-container="#app" class="over-hidden ps-f" :item-height="`${48 / 37.5}rem`" :close-icon="'https://dop-pro-1251973116.file.myqcloud.com/upload/img/funzg/icon_zhankailine.png'" :style="{ height: '40%' }">
|
|
11
|
+
<van-picker :value-key="addressValueKey" show-toolbar :confirm-button-text="$t('productcomponents.compareproup.tg417c')" :cancel-button-text="$t('dataenrichcompoentns.basicinfoform.434f5b')" :title="item.pickerTitle" :columns="addressSlots" @change="onAddressChange" @confirm="(value, pIdx) => onConfirm(value, pIdx, index, item, model)" @cancel="showPop = false" />
|
|
12
|
+
</van-popup>
|
|
13
|
+
</div>
|
|
14
|
+
</template>
|
|
15
|
+
|
|
16
|
+
<script>
|
|
17
|
+
export default {
|
|
18
|
+
// 组件名称
|
|
19
|
+
name: "CommonAsyncAreaPicker",
|
|
20
|
+
// 局部注册的组件
|
|
21
|
+
components: {},
|
|
22
|
+
// 组件参数 接收来自父组件的数据
|
|
23
|
+
props: {
|
|
24
|
+
item: {
|
|
25
|
+
type: Object,
|
|
26
|
+
default: () => {},
|
|
27
|
+
},
|
|
28
|
+
index: {
|
|
29
|
+
type: Number,
|
|
30
|
+
default: 0,
|
|
31
|
+
},
|
|
32
|
+
model: {
|
|
33
|
+
type: Object,
|
|
34
|
+
default: () => {},
|
|
35
|
+
},
|
|
36
|
+
cellData: {
|
|
37
|
+
type: Array,
|
|
38
|
+
default: () => [],
|
|
39
|
+
},
|
|
40
|
+
underLine: {
|
|
41
|
+
type: Boolean,
|
|
42
|
+
default: () => false,
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
// 组件状态值
|
|
46
|
+
data() {
|
|
47
|
+
return {
|
|
48
|
+
addressValueKey: "areaName",
|
|
49
|
+
// addressSlots: [],
|
|
50
|
+
value: "",
|
|
51
|
+
showPop: false,
|
|
52
|
+
currentCode: "",
|
|
53
|
+
provinces: [],
|
|
54
|
+
cities: [],
|
|
55
|
+
countries: [],
|
|
56
|
+
provinceIndex: 0,
|
|
57
|
+
cityIndex: 0,
|
|
58
|
+
countryIndex: 0,
|
|
59
|
+
loaded: false,
|
|
60
|
+
};
|
|
61
|
+
},
|
|
62
|
+
computed: {
|
|
63
|
+
provinceCity() {
|
|
64
|
+
const { province = "", city = "", country = "", district = "" } = this.model;
|
|
65
|
+
return { province, city, country: country || district };
|
|
66
|
+
},
|
|
67
|
+
/**
|
|
68
|
+
* // deepLevel由数据源带出,表示选择的省市区级别,目前有三个级别
|
|
69
|
+
* 1、只选省级
|
|
70
|
+
* 2、只选省市级
|
|
71
|
+
* 3、全部选择,包括省市区三级
|
|
72
|
+
*/
|
|
73
|
+
deepLevel() {
|
|
74
|
+
return this.item.deepLevel;
|
|
75
|
+
},
|
|
76
|
+
addressSlots() {
|
|
77
|
+
const result = [
|
|
78
|
+
{
|
|
79
|
+
values: this.provinces,
|
|
80
|
+
className: "slot1",
|
|
81
|
+
textAlign: "center",
|
|
82
|
+
defaultIndex: this.provinceIndex || 0,
|
|
83
|
+
},
|
|
84
|
+
];
|
|
85
|
+
if (this.deepLevel > 1) {
|
|
86
|
+
result.push({
|
|
87
|
+
values: this.cities,
|
|
88
|
+
className: "slot2",
|
|
89
|
+
textAlign: "center",
|
|
90
|
+
defaultIndex: this.cityIndex || 0,
|
|
91
|
+
});
|
|
92
|
+
if (this.deepLevel > 2) {
|
|
93
|
+
result.push({
|
|
94
|
+
values: this.countries,
|
|
95
|
+
className: "slot3",
|
|
96
|
+
textAlign: "center",
|
|
97
|
+
defaultIndex: this.countryIndex || 0,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return result;
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
watch: {
|
|
105
|
+
provinceCity: {
|
|
106
|
+
handler(newVal, oldVal) {
|
|
107
|
+
if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) this.getDefaultData(newVal);
|
|
108
|
+
},
|
|
109
|
+
deep: true,
|
|
110
|
+
immediate: true,
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
methods: {
|
|
114
|
+
// 分级查询省市
|
|
115
|
+
queryAsyncArea(params, dynamicSaaS) {
|
|
116
|
+
if (dynamicSaaS) {
|
|
117
|
+
return axios.post(`/funapi/user/V1/queryExhibitionArea`, { saasId: dynamicSaaS });
|
|
118
|
+
}
|
|
119
|
+
return axios.get(`/funapi/config/sysArea/list/${params}`);
|
|
120
|
+
},
|
|
121
|
+
async getDefaultData(model) {
|
|
122
|
+
const { dynamicSaaS } = this.item;
|
|
123
|
+
this.loaded = "loading";
|
|
124
|
+
let { province = "", city = "", country = "" } = model;
|
|
125
|
+
let cbParam = {};
|
|
126
|
+
const value = [];
|
|
127
|
+
const pIdx = [];
|
|
128
|
+
try {
|
|
129
|
+
const provinces = (this.provinces = await this.queryAsyncArea("0", dynamicSaaS));
|
|
130
|
+
this.provinceIndex = provinces.findIndex((pvc) => pvc.areaCode === province);
|
|
131
|
+
value.push(provinces[this.provinceIndex]);
|
|
132
|
+
pIdx.push(this.provinceIndex);
|
|
133
|
+
if (this.deepLevel > 1) {
|
|
134
|
+
province = province || provinces[0].areaCode;
|
|
135
|
+
const cities = (this.cities = await this.queryAsyncArea(province));
|
|
136
|
+
this.cityIndex = cities.findIndex((ct) => ct.areaCode === city);
|
|
137
|
+
value.push(cities[this.cityIndex]);
|
|
138
|
+
pIdx.push(this.cityIndex);
|
|
139
|
+
if (this.deepLevel > 2) {
|
|
140
|
+
city = city || cities[0].areaCode;
|
|
141
|
+
const countries = (this.countries = await this.queryAsyncArea(city));
|
|
142
|
+
this.countryIndex = countries.findIndex((cty) => cty.areaCode === country);
|
|
143
|
+
value.push(countries[this.countryIndex]);
|
|
144
|
+
pIdx.push(this.countryIndex);
|
|
145
|
+
} else {
|
|
146
|
+
this.loaded = true;
|
|
147
|
+
}
|
|
148
|
+
} else {
|
|
149
|
+
this.loaded = true;
|
|
150
|
+
}
|
|
151
|
+
cbParam = Object.assign(cbParam, {
|
|
152
|
+
value,
|
|
153
|
+
pIdx,
|
|
154
|
+
index: this.index,
|
|
155
|
+
item: this.item,
|
|
156
|
+
model: this.model,
|
|
157
|
+
});
|
|
158
|
+
// 如果省级数据都没有就不触发onConfirmPicker了
|
|
159
|
+
if (value[0]) this.$emit("onConfirmPicker", cbParam);
|
|
160
|
+
} catch (err) {
|
|
161
|
+
console.log(err);
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
onConfirm(value, pIdx, index, item, model) {
|
|
165
|
+
const obj = {
|
|
166
|
+
value,
|
|
167
|
+
pIdx,
|
|
168
|
+
index,
|
|
169
|
+
item,
|
|
170
|
+
model,
|
|
171
|
+
};
|
|
172
|
+
// 异地增员选中不可选地区时做出拦截
|
|
173
|
+
const noSelectVal = value.find((val) => val["noSelect"] === "1");
|
|
174
|
+
if (noSelectVal) {
|
|
175
|
+
this.$toast(this.$t("commonform.commonasyncareapicker.ws0srk"));
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
this.value = value;
|
|
179
|
+
this.showPop = false;
|
|
180
|
+
this.$emit("onConfirmPicker", obj);
|
|
181
|
+
},
|
|
182
|
+
// 选择地址的时候
|
|
183
|
+
onAddressChange(picker, values, index) {
|
|
184
|
+
const targetCode = values[index].areaCode; // 省级编码
|
|
185
|
+
if (index === 0) {
|
|
186
|
+
this.queryAsyncArea(targetCode).then((res) => {
|
|
187
|
+
picker.setColumnValues(index + 1, res);
|
|
188
|
+
if (index + 1 < this.deepLevel) {
|
|
189
|
+
this.queryAsyncArea(res[0].areaCode).then((res1) => {
|
|
190
|
+
picker.setColumnValues(index + 2, res1);
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
if (index === 1) {
|
|
196
|
+
this.queryAsyncArea(targetCode).then((res1) => {
|
|
197
|
+
picker.setColumnValues(index + 1, res1);
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
},
|
|
201
|
+
fieldChange(val, item, model, allDataArr = this.cellData) {
|
|
202
|
+
const obj = {
|
|
203
|
+
val,
|
|
204
|
+
item,
|
|
205
|
+
model,
|
|
206
|
+
allDataArr,
|
|
207
|
+
};
|
|
208
|
+
this.$emit("pickerFieldChange", obj);
|
|
209
|
+
},
|
|
210
|
+
clickEvent(e, item) {
|
|
211
|
+
if (item.readOnly) {
|
|
212
|
+
e.preventDefault();
|
|
213
|
+
e.stopPropagation();
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
this.showPop = true;
|
|
217
|
+
},
|
|
218
|
+
},
|
|
219
|
+
};
|
|
220
|
+
</script>
|
|
221
|
+
|
|
222
|
+
<!--使用了scoped属性之后,父组件的style样式将不会渗透到子组件中,-->
|
|
223
|
+
<style scoped lang="less"></style>
|