87d7b854 by 华明祺

feat(personal): 完善个人会员申请及支付流程

- 协议勾选区域固定在页面底部,优化用户体验
- 联系方式改为非必填,但填写时验证手机号格式
- 支付逻辑使用 await-to-js 重构,统一错误处理
- 支付流程添加 loading 状态,防止重复提交
- 支付成功后传递 orderId,跳转时获取并展示订单详情
- 支付成功页面优化:标签不换行、值支持自动换行
- 新增获取订单详情接口 /common/order/{orderId}
1 parent 7d54d38d
...@@ -195,11 +195,11 @@ export function regionsList(params) { ...@@ -195,11 +195,11 @@ export function regionsList(params) {
195 export function carUrl(data, type) { 195 export function carUrl(data, type) {
196 return uni.uploadFile({ 196 return uni.uploadFile({
197 url: `${config.baseUrl_api}/person/info/getPersonInfoFromCert/${type}`, 197 url: `${config.baseUrl_api}/person/info/getPersonInfoFromCert/${type}`,
198 header: { 198 // header: {
199 'Authorization': uni.getStorageSync('token'), 199 // 'Authorization': uni.getStorageSync('token'),
200 'Content-Language': 'zh_CN', 200 // 'Content-Language': 'zh_CN',
201 'Accept-Language': 'zh-CN,zh', 201 // 'Accept-Language': 'zh-CN,zh',
202 }, 202 // },
203 name: 'pic', 203 name: 'pic',
204 filePath: data 204 filePath: data
205 }).then(res => { 205 }).then(res => {
...@@ -1415,3 +1415,11 @@ export function createMemberPayRange(data) { ...@@ -1415,3 +1415,11 @@ export function createMemberPayRange(data) {
1415 data 1415 data
1416 }) 1416 })
1417 } 1417 }
1418
1419 // 获取订单详情
1420 export function getOrderInfo(orderId) {
1421 return request({
1422 url: `/common/order/${orderId}`,
1423 method: 'get'
1424 })
1425 }
...\ No newline at end of file ...\ No newline at end of file
......
1 { 1 {
2 "dependencies": { 2 "dependencies": {
3 "await-to-js": "^3.0.0",
3 "crypto-js": "^4.1.1", 4 "crypto-js": "^4.1.1",
4 "dayjs": "^1.11.6", 5 "dayjs": "^1.11.6",
5 "lodash": "^4.17.21", 6 "lodash": "^4.17.21",
......
...@@ -53,7 +53,7 @@ ...@@ -53,7 +53,7 @@
53 </uni-forms-item> 53 </uni-forms-item>
54 54
55 55
56 <uni-forms-item label="所在地区"> 56 <!-- <uni-forms-item label="所在地区">
57 <uni-data-picker class="fixUniFormItemStyle" v-model="baseFormData.cityId" 57 <uni-data-picker class="fixUniFormItemStyle" v-model="baseFormData.cityId"
58 :localdata="regionsList" popup-title="请选择所在地区"></uni-data-picker> 58 :localdata="regionsList" popup-title="请选择所在地区"></uni-data-picker>
59 </uni-forms-item> 59 </uni-forms-item>
...@@ -65,10 +65,12 @@ ...@@ -65,10 +65,12 @@
65 <uni-file-picker v-model="photoArr" @delete="delPhoto" return-type="object" limit="1" 65 <uni-file-picker v-model="photoArr" @delete="delPhoto" return-type="object" limit="1"
66 @select="upPhoto" :del-ico="false" :image-styles="imageStylesTx"></uni-file-picker> 66 @select="upPhoto" :del-ico="false" :image-styles="imageStylesTx"></uni-file-picker>
67 <image mode="aspectFill" v-if="baseFormData.photo2" style="height:200rpx;width:200rpx;" :src="config.baseUrl_api + baseFormData.photo2"/> 67 <image mode="aspectFill" v-if="baseFormData.photo2" style="height:200rpx;width:200rpx;" :src="config.baseUrl_api + baseFormData.photo2"/>
68 </uni-forms-item> 68 </uni-forms-item> -->
69 </view> 69 </view>
70 </uni-forms> 70 </uni-forms>
71 </view> 71 </view>
72 </view>
73 <view class="fixed-agreeline">
72 <view class="agreeline"> 74 <view class="agreeline">
73 <image @click="changeAgree(agree)" v-if="agree" 75 <image @click="changeAgree(agree)" v-if="agree"
74 :src="config.baseUrl_api+'/fs/static/login/xz_dwn@2x.png'"></image> 76 :src="config.baseUrl_api+'/fs/static/login/xz_dwn@2x.png'"></image>
...@@ -80,7 +82,8 @@ ...@@ -80,7 +82,8 @@
80 <view class="fixedBottom"><button class="btn-red" @click="goSubmit">确 定</button></view> 82 <view class="fixedBottom"><button class="btn-red" @click="goSubmit">确 定</button></view>
81 83
82 <!-- 会员须知 --> 84 <!-- 会员须知 -->
83 <uni-popup ref="popup" type="bottom" background-color="#fff" animation :disable-scroll="true" :mask-click="false"> 85 <uni-popup ref="popup" type="bottom" background-color="#fff" animation :disable-scroll="true"
86 :mask-click="false">
84 <view class="tt">入会须知</view> 87 <view class="tt">入会须知</view>
85 <view class="popBody"> 88 <view class="popBody">
86 _{{baseFormData.name}}_欢迎您申请成为中国跆拳道协会(以下简称中国跆协)会员,请确保本次申请是经过您本人或监护人授权同意后的自愿行为,请您务必仔细阅读本入会须知。 89 _{{baseFormData.name}}_欢迎您申请成为中国跆拳道协会(以下简称中国跆协)会员,请确保本次申请是经过您本人或监护人授权同意后的自愿行为,请您务必仔细阅读本入会须知。
...@@ -150,13 +153,15 @@ ...@@ -150,13 +153,15 @@
150 value: '1', 153 value: '1',
151 text: "来往大陆(内地)通行证" 154 text: "来往大陆(内地)通行证"
152 }, 155 },
156 // {
157 // value: '3',
158 // text: "护照"
159 // },
153 { 160 {
154 value: '3',
155 text: "护照"
156 }, {
157 value: '4', 161 value: '4',
158 text: '户口本' 162 text: '户口本'
159 }, { 163 },
164 {
160 value: '5', 165 value: '5',
161 text: '香港身份证' 166 text: '香港身份证'
162 } 167 }
...@@ -200,7 +205,7 @@ ...@@ -200,7 +205,7 @@
200 } 205 }
201 } 206 }
202 // console.log(current.value,option.tab) 207 // console.log(current.value,option.tab)
203 getRegionsList() 208 // getRegionsList()
204 }) 209 })
205 210
206 function getRegionsList() { 211 function getRegionsList() {
...@@ -246,33 +251,26 @@ ...@@ -246,33 +251,26 @@
246 title: '加载中' 251 title: '加载中'
247 }); 252 });
248 baseFormData.value.card = e.tempFiles; 253 baseFormData.value.card = e.tempFiles;
254
249 // console.log(e) 255 // console.log(e)
250 // const formData = new FormData() 256 // const formData = new FormData()
251 // formData.append('pic', e.tempFiles[0].file) 257 // formData.append('pic', e.tempFiles[0].file)
252 api.carUrl(e.tempFilePaths[0], baseFormData.value.idcType).then(res => { 258 api.carUrl(e.tempFilePaths[0], baseFormData.value.idcType).then(res => {
253 console.log(res) 259 uni.hideLoading()
260
254 if (res.data) { 261 if (res.data) {
255 baseFormData.value.sex = res.data.sex 262 baseFormData.value.sex = res.data.sex
256 baseFormData.value.birth = res.data.birth 263 baseFormData.value.birth = res.data.birth
257 baseFormData.value.idcCode = res.data.code 264 baseFormData.value.idcCode = res.data.code
258 baseFormData.value.name = res.data.name 265 baseFormData.value.name = res.data.name
259 baseFormData.value.uuid = res.data.uuid 266 baseFormData.value.uuid = res.data.uuid
260 baseFormData.value.cityId = res.data.cityId 267 // baseFormData.value.cityId = res.data.cityId
261 baseFormData.value.address = res.data.address 268 // baseFormData.value.address = res.data.address
262 photoArr.value = {}
263 getExtractInfo({
264 idcCode: baseFormData.value.idcCode,
265 idcType: baseFormData.value.idcType,
266 perType: baseFormData.value.perType
267 })
268
269 } else { 269 } else {
270 uni.hideLoading() 270 uni.showToast({
271 uni.showModal({ 271 title: res.msg,
272 content: res.msg, 272 duration: 2000,
273 success: function(modalRes) { 273 icon: 'none'
274
275 }
276 }) 274 })
277 } 275 }
278 276
...@@ -297,7 +295,7 @@ ...@@ -297,7 +295,7 @@
297 baseFormData.value.photo = data.data.fang; 295 baseFormData.value.photo = data.data.fang;
298 baseFormData.value.photo2 = data.data.yuan; 296 baseFormData.value.photo2 = data.data.yuan;
299 photoArr.value = { 297 photoArr.value = {
300 url: config.baseUrl_api+baseFormData.value.photo, 298 url: config.baseUrl_api + baseFormData.value.photo,
301 name: '头像', 299 name: '头像',
302 extname: 'jpg' 300 extname: 'jpg'
303 } 301 }
...@@ -352,8 +350,8 @@ ...@@ -352,8 +350,8 @@
352 baseFormData.value.birth = res.data.birth 350 baseFormData.value.birth = res.data.birth
353 baseFormData.value.name = res.data.name 351 baseFormData.value.name = res.data.name
354 baseFormData.value.phone = res.data.phone 352 baseFormData.value.phone = res.data.phone
355 baseFormData.value.cityId = res.data.cityId 353 // baseFormData.value.cityId = res.data.cityId
356 baseFormData.value.address = res.data.address 354 // baseFormData.value.address = res.data.address
357 if (res.data.photo) { 355 if (res.data.photo) {
358 console.log(res.data.photo) 356 console.log(res.data.photo)
359 if (res.data.photo.indexOf('http') == -1) { 357 if (res.data.photo.indexOf('http') == -1) {
...@@ -398,6 +396,10 @@ ...@@ -398,6 +396,10 @@
398 396
399 397
400 function giveBirthDay() { 398 function giveBirthDay() {
399 if (!baseFormData.value.idcCode) {
400 return
401 }
402
401 // 判断身份证正确性/赋值生日 403 // 判断身份证正确性/赋值生日
402 if (baseFormData.value.idcType == 0) { 404 if (baseFormData.value.idcType == 0) {
403 if (!(/(^\d{15}$)|(^\d{17}([0-9]|X)$)/.test(baseFormData.value.idcCode))) { 405 if (!(/(^\d{15}$)|(^\d{17}([0-9]|X)$)/.test(baseFormData.value.idcCode))) {
...@@ -480,21 +482,33 @@ ...@@ -480,21 +482,33 @@
480 }) 482 })
481 return 483 return
482 } 484 }
483 console.log(baseFormData.value.photo) 485
484 if (baseFormData.value.photo == '' || baseFormData.value.photo == undefined || !baseFormData.value.photo) { 486 if (baseFormData.value.phone) {
487 const phoneReg = /^1[3-9]\d{9}$/
488 if (!phoneReg.test(baseFormData.value.phone)) {
485 uni.showToast({ 489 uni.showToast({
486 title: `请上传头像`, 490 title: '请输入正确的联系方式',
487 icon: 'none' 491 icon: 'none'
488 }) 492 })
489 return 493 return
490 } 494 }
495 }
496
497 // if (baseFormData.value.photo == '' || baseFormData.value.photo == undefined || !baseFormData.value.photo) {
498 // uni.showToast({
499 // title: `请上传头像`,
500 // icon: 'none'
501 // })
502 // return
503 // }
504
491 //信息确认弹出 505 //信息确认弹出
492 uni.showModal({ 506 uni.showModal({
493 content: '请确认信息正确', 507 content: '请确认信息正确',
494 success: function(res) { 508 success: function(res) {
495 if (res.confirm) { 509 if (res.confirm) {
496 if(baseFormData.value.idcType=='4'){ 510 if (baseFormData.value.idcType == '4') {
497 baseFormData.value.idcType='0' 511 baseFormData.value.idcType = '0'
498 } 512 }
499 delete baseFormData.value.card 513 delete baseFormData.value.card
500 514
...@@ -547,18 +561,17 @@ ...@@ -547,18 +561,17 @@
547 } 561 }
548 }); 562 });
549 } 563 }
564
550 function getUserInfo() { 565 function getUserInfo() {
551 api.getInfo(perId.value).then(res => { 566 api.getInfo(perId.value).then(res => {
552 baseFormData.value = res.data 567 baseFormData.value = res.data
553 if (baseFormData.areaAssName) baseFormData.ancestorNameList = baseFormData.value.ancestorNameList.join( 568 if (baseFormData.areaAssName) baseFormData.ancestorNameList = baseFormData.value.ancestorNameList.join(
554 ',').replaceAll(',', 569 ',').replaceAll(',', '/')
555 '/')
556 }) 570 })
557 } 571 }
558 </script> 572 </script>
559 573
560 <style lang="scss"> 574 <style lang="scss">
561
562 /* 字段名左对齐 */ 575 /* 字段名左对齐 */
563 .uni-forms-item .uni-forms-item__label { 576 .uni-forms-item .uni-forms-item__label {
564 text-align: left !important; 577 text-align: left !important;
...@@ -587,11 +600,10 @@ ...@@ -587,11 +600,10 @@
587 600
588 /* 文本内容右对齐 */ 601 /* 文本内容右对齐 */
589 .uni-forms-item .uni-forms-item__content text, 602 .uni-forms-item .uni-forms-item__content text,
590 .uni-forms-item .uni-forms-item__content > text { 603 .uni-forms-item .uni-forms-item__content>text {
591 display: inline-block !important; 604 display: inline-block !important;
592 white-space: nowrap !important; 605 white-space: nowrap !important;
593 } 606 }
594
595 </style> 607 </style>
596 608
597 <style lang="scss" scoped> 609 <style lang="scss" scoped>
...@@ -603,9 +615,11 @@ ...@@ -603,9 +615,11 @@
603 right: 0; 615 right: 0;
604 bottom: 0; 616 bottom: 0;
605 } 617 }
618
606 :deep(.uni-popup) { 619 :deep(.uni-popup) {
607 overflow: hidden !important; 620 overflow: hidden !important;
608 } 621 }
622
609 :deep(.segmented-control) { 623 :deep(.segmented-control) {
610 height: 100rpx; 624 height: 100rpx;
611 } 625 }
...@@ -636,13 +650,24 @@ ...@@ -636,13 +650,24 @@
636 } 650 }
637 } 651 }
638 652
653 .hasfixedbottom {
654 padding-bottom: 200rpx;
655 }
656
657 .fixed-agreeline {
658 position: fixed;
659 bottom: 150rpx;
660 left: 0;
661 right: 0;
662 z-index: 1;
663 }
664
639 .agreeline { 665 .agreeline {
640 padding: 20rpx 40rpx; 666 padding: 20rpx 40rpx;
641 box-sizing: border-box; 667 box-sizing: border-box;
642 display: flex; 668 display: flex;
643 font-size: 30rpx; 669 font-size: 30rpx;
644 670
645
646 text { 671 text {
647 color: #014A9F; 672 color: #014A9F;
648 } 673 }
...@@ -681,6 +706,7 @@ ...@@ -681,6 +706,7 @@
681 :deep(.item-text-overflow) { 706 :deep(.item-text-overflow) {
682 text-align: left; 707 text-align: left;
683 } 708 }
709
684 :deep(.fixUniFormItemStyle .uni-data-picker__input-box) { 710 :deep(.fixUniFormItemStyle .uni-data-picker__input-box) {
685 justify-content: flex-start !important; 711 justify-content: flex-start !important;
686 text-align: left !important; 712 text-align: left !important;
......
...@@ -5,11 +5,13 @@ ...@@ -5,11 +5,13 @@
5 <view class="yearRow"> 5 <view class="yearRow">
6 <view class="label">缴费年限</view> 6 <view class="label">缴费年限</view>
7 <view class="control"> 7 <view class="control">
8 <image class="icon" @click="minusYear" src="/static/dd_02.png" mode="widthFix" v-if="form.payYear > 1" ></image> 8 <image class="icon" @click="minusYear" src="/static/dd_02.png" mode="widthFix"
9 <image class="icon" src="/static/dd_02_g.png" mode="widthFix" v-else ></image> 9 v-if="form.payYear > 1"></image>
10 <image class="icon" src="/static/dd_02_g.png" mode="widthFix" v-else></image>
10 <text class="num">{{ form.payYear }}</text> 11 <text class="num">{{ form.payYear }}</text>
11 <image class="icon" src="/static/btn_03.png" mode="widthFix" @click="plusYear" v-if="form.payYear < 5" ></image> 12 <image class="icon" src="/static/btn_03.png" mode="widthFix" @click="plusYear"
12 <image class="icon" src="/static/btn_03_g.png" mode="widthFix" v-else ></image> 13 v-if="form.payYear < 5"></image>
14 <image class="icon" src="/static/btn_03_g.png" mode="widthFix" v-else></image>
13 </view> 15 </view>
14 </view> 16 </view>
15 </view> 17 </view>
...@@ -49,25 +51,32 @@ ...@@ -49,25 +51,32 @@
49 </template> 51 </template>
50 52
51 <script setup> 53 <script setup>
52 import { ref, computed, onMounted } from 'vue' 54 import {
53 import { onLoad } from '@dcloudio/uni-app'; 55 ref,
54 import * as api from '@/common/api.js' 56 computed,
57 onMounted
58 } from 'vue'
59 import {
60 onLoad
61 } from '@dcloudio/uni-app';
62 import to from 'await-to-js'
63 import * as api from '@/common/api.js'
55 64
56 const form = ref({ 65 const form = ref({
57 payYear: 1 66 payYear: 1
58 }) 67 })
59 68
60 // 支付方式 69 // 支付方式
61 const payType = ref('1') 70 const payType = ref('1')
62 const isPaying = ref(false) 71 const isPaying = ref(false)
63 72
64 // 费用与优惠 73 // 费用与优惠
65 const memberFee = ref(0) 74 const memberFee = ref(0)
66 const memberTotalFee = computed(() => { 75 const memberTotalFee = computed(() => {
67 return memberFee.value * form.value.payYear 76 return memberFee.value * form.value.payYear
68 77
69 }) 78 })
70 onLoad((options) => { 79 onLoad((options) => {
71 if (options.baseFormData) { 80 if (options.baseFormData) {
72 const data = JSON.parse(decodeURIComponent(options.baseFormData)) 81 const data = JSON.parse(decodeURIComponent(options.baseFormData))
73 form.value = { 82 form.value = {
...@@ -77,37 +86,45 @@ onLoad((options) => { ...@@ -77,37 +86,45 @@ onLoad((options) => {
77 } 86 }
78 // 初始化接口 87 // 初始化接口
79 getMyMemberCertUnitFeeApi() 88 getMyMemberCertUnitFeeApi()
80 }) 89 })
81 90
82 91
83 92
84 // 减年限 93 // 减年限
85 const minusYear = () => { 94 const minusYear = () => {
86 if (form.value.payYear > 1) { 95 if (form.value.payYear > 1) {
87 form.value.payYear-- 96 form.value.payYear--
88 } 97 }
89 } 98 }
90 99
91 // 加年限(最大 5 年) 100 // 加年限(最大 5 年)
92 const plusYear = () => { 101 const plusYear = () => {
93 if (form.value.payYear < 5) { 102 if (form.value.payYear < 5) {
94 form.value.payYear++ 103 form.value.payYear++
95 } 104 }
96 } 105 }
97 106
98 // 支付方式切换 107 // 支付方式切换
99 const onPayTypeChange = (e) => { 108 const onPayTypeChange = (e) => {
100 payType.value = e.detail.value 109 payType.value = e.detail.value
101 } 110 }
102 111
103 const handelPay = async () => { 112 const handelPay = async () => {
104 if (memberTotalFee.value <= 0) { 113 if (memberTotalFee.value <= 0) {
105 uni.showToast({ title: '支付金额异常', icon: 'none' }) 114 uni.showToast({
115 title: '支付金额异常',
116 icon: 'none'
117 })
106 return 118 return
107 } 119 }
108 120
121 // 显示 loading
122 uni.showLoading({
123 title: '支付中...',
124 mask: true
125 })
109 isPaying.value = true 126 isPaying.value = true
110 try { 127
111 // 拼接完整参数 128 // 拼接完整参数
112 const postData = { 129 const postData = {
113 ...form.value, 130 ...form.value,
...@@ -116,100 +133,126 @@ const handelPay = async () => { ...@@ -116,100 +133,126 @@ const handelPay = async () => {
116 totalFee: memberTotalFee.value 133 totalFee: memberTotalFee.value
117 } 134 }
118 135
119 const res = await api.insertSinglePay(postData) 136 // 创建订单
120 console.log(777,res) 137 const [orderErr, orderRes] = await to(api.insertSinglePay(postData))
121 if (res.data?.orderId) { 138 if (orderErr) {
122 api.pcallBack2(res.data.orderId) 139 uni.hideLoading()
123 uni.navigateTo({ 140 isPaying.value = false
124 url: `/personal/sucPay` 141 uni.showToast({
142 title: '创建订单失败',
143 icon: 'none'
125 }) 144 })
145 return
146 }
147
148 if (!orderRes.data?.orderId) {
149 uni.hideLoading()
150 isPaying.value = false
151 uni.showToast({
152 title: '订单创建异常',
153 icon: 'none'
154 })
155 return
126 } 156 }
127 // if (data.payFlag == 0 || data.orderId) { 157
128 // data.orderId && api.callBack2(data.orderId) 158 // 等待支付回调
129 // uni.navigateTo({ url: `/personal/submitPay?price=${res.data.price}` }) 159 await to(api.pcallBack2(orderRes.data.orderId))
130 // } 160 uni.hideLoading()
131 } catch (err) {
132 uni.showToast({ title: '支付失败', icon: 'none' })
133 } finally {
134 isPaying.value = false 161 isPaying.value = false
162
163 // 支付成功,跳转页面
164 uni.navigateTo({
165 url: `/personal/sucPay?orderId=${orderRes.data.orderId}`
166 })
135 } 167 }
136 }
137 168
138 169
139 170
140 // 获取会员费 171 // 获取会员费
141 async function getMyMemberCertUnitFeeApi() { 172 async function getMyMemberCertUnitFeeApi() {
142 const res = await api.getZtxFeeConfig() 173 const res = await api.getZtxFeeConfig()
143 memberFee.value = Number(res.data.personMemberFee || 1500) 174 memberFee.value = Number(res.data.personMemberFee || 1500)
144 } 175 }
145
146 </script> 176 </script>
147 177
148 <style scoped> 178 <style scoped>
149 .container { 179 .container {
150 min-height: 100vh; 180 min-height: 100vh;
151 background-color: #f7f7f7; 181 background-color: #f7f7f7;
152 } 182 }
153 .content { 183
184 .content {
154 padding: 20rpx 20rpx 120rpx; 185 padding: 20rpx 20rpx 120rpx;
155 } 186 }
156 .card { 187
188 .card {
157 background: #fff; 189 background: #fff;
158 border-radius: 8rpx; 190 border-radius: 8rpx;
159 padding: 25rpx 20rpx; 191 padding: 25rpx 20rpx;
160 margin-bottom: 20rpx; 192 margin-bottom: 20rpx;
161 } 193 }
162 .yearRow { 194
195 .yearRow {
163 display: flex; 196 display: flex;
164 align-items: center; 197 align-items: center;
165 justify-content: space-between; 198 justify-content: space-between;
166 margin-bottom: 20rpx; 199 margin-bottom: 20rpx;
167 } 200 }
168 .yearRow .label { 201
202 .yearRow .label {
169 font-size: 28rpx; 203 font-size: 28rpx;
170 color: #333; 204 color: #333;
171 } 205 }
172 .yearRow .control { 206
207 .yearRow .control {
173 display: flex; 208 display: flex;
174 align-items: center; 209 align-items: center;
175 } 210 }
176 .control image { 211
212 .control image {
177 width: 50rpx; 213 width: 50rpx;
178 height: 50rpx; 214 height: 50rpx;
179 } 215 }
180 .yearRow .num { 216
217 .yearRow .num {
181 font-size: 28rpx; 218 font-size: 28rpx;
182 color: #333; 219 color: #333;
183 min-width: 80rpx; 220 min-width: 80rpx;
184 text-align: center; 221 text-align: center;
185 margin: 0 10rpx; 222 margin: 0 10rpx;
186 } 223 }
187 .row { 224
225 .row {
188 display: flex; 226 display: flex;
189 justify-content: space-between; 227 justify-content: space-between;
190 align-items: center; 228 align-items: center;
191 } 229 }
192 .row .label { 230
231 .row .label {
193 font-size: 28rpx; 232 font-size: 28rpx;
194 color: #333; 233 color: #333;
195 } 234 }
196 .row .value { 235
236 .row .value {
197 font-size: 30rpx; 237 font-size: 30rpx;
198 color: #C4121B; 238 color: #C4121B;
199 font-weight: 500; 239 font-weight: 500;
200 } 240 }
201 .hintRow { 241
242 .hintRow {
202 display: flex; 243 display: flex;
203 align-items: flex-start; 244 align-items: flex-start;
204 font-size: 24rpx; 245 font-size: 24rpx;
205 line-height: 1.4; 246 line-height: 1.4;
206 } 247 }
207 .hintRow .hintText { 248
249 .hintRow .hintText {
208 color: #FF8124; 250 color: #FF8124;
209 flex: 1; 251 flex: 1;
210 margin-top: 10rpx; 252 margin-top: 10rpx;
211 } 253 }
212 .deductRow { 254
255 .deductRow {
213 background: #fff; 256 background: #fff;
214 padding: 20rpx 20rpx; 257 padding: 20rpx 20rpx;
215 display: flex; 258 display: flex;
...@@ -217,40 +260,48 @@ async function getMyMemberCertUnitFeeApi() { ...@@ -217,40 +260,48 @@ async function getMyMemberCertUnitFeeApi() {
217 align-items: center; 260 align-items: center;
218 margin-bottom: 10rpx; 261 margin-bottom: 10rpx;
219 border-radius: 8rpx; 262 border-radius: 8rpx;
220 } 263 }
221 .deductRow .label { 264
265 .deductRow .label {
222 font-size: 28rpx; 266 font-size: 28rpx;
223 color: #333; 267 color: #333;
224 } 268 }
225 .deductRow .value { 269
270 .deductRow .value {
226 font-size: 30rpx; 271 font-size: 30rpx;
227 color: #C4121B; 272 color: #C4121B;
228 } 273 }
229 .payRow { 274
275 .payRow {
230 background: #fff; 276 background: #fff;
231 border-radius: 8rpx; 277 border-radius: 8rpx;
232 padding: 20rpx 20rpx; 278 padding: 20rpx 20rpx;
233 margin-bottom: 20rpx; 279 margin-bottom: 20rpx;
234 } 280 }
235 .radioItem { 281
282 .radioItem {
236 display: flex; 283 display: flex;
237 align-items: center; 284 align-items: center;
238 } 285 }
239 .payInfo { 286
287 .payInfo {
240 display: flex; 288 display: flex;
241 align-items: center; 289 align-items: center;
242 margin-left: 15rpx; 290 margin-left: 15rpx;
243 } 291 }
244 .payInfo .icon { 292
293 .payInfo .icon {
245 width: 40rpx; 294 width: 40rpx;
246 height: 40rpx; 295 height: 40rpx;
247 margin-right: 10rpx; 296 margin-right: 10rpx;
248 } 297 }
249 .payInfo text { 298
299 .payInfo text {
250 font-size: 28rpx; 300 font-size: 28rpx;
251 color: #333; 301 color: #333;
252 } 302 }
253 .totalRow { 303
304 .totalRow {
254 background: #fff; 305 background: #fff;
255 border-radius: 8rpx; 306 border-radius: 8rpx;
256 padding: 20rpx 20rpx; 307 padding: 20rpx 20rpx;
...@@ -258,17 +309,20 @@ async function getMyMemberCertUnitFeeApi() { ...@@ -258,17 +309,20 @@ async function getMyMemberCertUnitFeeApi() {
258 justify-content: space-between; 309 justify-content: space-between;
259 align-items: center; 310 align-items: center;
260 margin-top: 10rpx; 311 margin-top: 10rpx;
261 } 312 }
262 .totalRow .label { 313
314 .totalRow .label {
263 font-size: 28rpx; 315 font-size: 28rpx;
264 color: #333; 316 color: #333;
265 } 317 }
266 .redBig { 318
319 .redBig {
267 font-size: 32rpx; 320 font-size: 32rpx;
268 color: #C4121B; 321 color: #C4121B;
269 font-weight: bold; 322 font-weight: bold;
270 } 323 }
271 .bottomBtn { 324
325 .bottomBtn {
272 position: fixed; 326 position: fixed;
273 bottom: 0; 327 bottom: 0;
274 left: 0; 328 left: 0;
...@@ -276,8 +330,9 @@ async function getMyMemberCertUnitFeeApi() { ...@@ -276,8 +330,9 @@ async function getMyMemberCertUnitFeeApi() {
276 padding: 20rpx 20rpx; 330 padding: 20rpx 20rpx;
277 background: #fff; 331 background: #fff;
278 border-top: 1rpx solid #eee; 332 border-top: 1rpx solid #eee;
279 } 333 }
280 .payBtn { 334
335 .payBtn {
281 width: 100%; 336 width: 100%;
282 height: 88rpx; 337 height: 88rpx;
283 line-height: 88rpx; 338 line-height: 88rpx;
...@@ -287,25 +342,30 @@ async function getMyMemberCertUnitFeeApi() { ...@@ -287,25 +342,30 @@ async function getMyMemberCertUnitFeeApi() {
287 font-size: 32rpx; 342 font-size: 32rpx;
288 text-align: center; 343 text-align: center;
289 border: none; 344 border: none;
290 } 345 }
291 .payBtn[disabled] { 346
347 .payBtn[disabled] {
292 background-color: #ccc; 348 background-color: #ccc;
293 color: #999; 349 color: #999;
294 } 350 }
295 .red { 351
352 .red {
296 color: #C4121B; 353 color: #C4121B;
297 } 354 }
298 .icon{ 355
299 width:30px; 356 .icon {
300 } 357 width: 30px;
301 ::v-deep .custom-radio .wx-radio-input { 358 }
359
360 ::v-deep .custom-radio .wx-radio-input {
302 width: 30rpx; 361 width: 30rpx;
303 height: 30rpx; 362 height: 30rpx;
304 border-radius: 50%; 363 border-radius: 50%;
305 border: 2rpx solid #ccc; 364 border: 2rpx solid #ccc;
306 } 365 }
307 ::v-deep .custom-radio .wx-radio-input.wx-radio-input-checked { 366
367 ::v-deep .custom-radio .wx-radio-input.wx-radio-input-checked {
308 border-color: #C4121B !important; 368 border-color: #C4121B !important;
309 background: #C4121B !important; 369 background: #C4121B !important;
310 } 370 }
311 </style> 371 </style>
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -14,28 +14,16 @@ ...@@ -14,28 +14,16 @@
14 <!-- 订单信息卡片(带阴影) --> 14 <!-- 订单信息卡片(带阴影) -->
15 <view class="info-card"> 15 <view class="info-card">
16 <view class="info-item"> 16 <view class="info-item">
17 <text class="label">付款账户</text>
18 <text class="value">(5437)</text>
19 </view>
20 <view class="info-item">
21 <text class="label">交易流水号</text> 17 <text class="label">交易流水号</text>
22 <text class="value">2205051351076117833</text> 18 <text class="value">{{ orderInfo.tradeNo }}</text>
23 </view> 19 </view>
24 <view class="info-item"> 20 <view class="info-item">
25 <text class="label">商户名称</text> 21 <text class="label">商户名称</text>
26 <text class="value">中国跆拳道协会</text> 22 <text class="value">{{ orderInfo.merchantName || '中国跆拳道协会' }}</text>
27 </view> 23 </view>
28 <view class="info-item"> 24 <view class="info-item">
29 <text class="label">订单金额</text> 25 <text class="label">订单金额</text>
30 <text class="value amount">1500.00元</text> 26 <text class="value amount">{{ orderInfo.price ? orderInfo.price + '元' : '--' }}</text>
31 </view>
32 <view class="info-item">
33 <text class="label">会员编号</text>
34 <text class="value">CTA00004</text>
35 </view>
36 <view class="info-item">
37 <text class="label">会员有效期</text>
38 <text class="value">2028年1月25日</text>
39 </view> 27 </view>
40 </view> 28 </view>
41 29
...@@ -47,20 +35,43 @@ ...@@ -47,20 +35,43 @@
47 </template> 35 </template>
48 36
49 <script setup> 37 <script setup>
50 import { onLoad } from '@dcloudio/uni-app' 38 import {
51 const goBack = () => { 39 ref
52 uni.navigateTo({ 40 } from 'vue'
53 url: `/personal/home` 41 import {
42 onLoad
43 } from '@dcloudio/uni-app'
44 import to from 'await-to-js'
45 import * as api from '@/common/api.js'
46
47 const orderInfo = ref({
48 id: '',
49 tradeNo: '',
50 merchantName: '中国跆拳道协会',
51 price: ''
54 }) 52 })
55 }
56 53
57 onLoad((option) => { 54 const goBack = () => {
58 }) 55 uni.reLaunch({
56 url: '/login/login'
57 })
58 }
59
60 onLoad(async (option) => {
61 if (option.orderId) {
62 const [err, res] = await to(api.getOrderInfo(option.orderId))
63 if (!err && res.data) {
64 orderInfo.value = res.data
65 } else {
66 orderInfo.value.id = option.orderId
67 }
68 }
69 })
59 </script> 70 </script>
60 71
61 <style scoped> 72 <style scoped>
62 /* 全局容器 */ 73 /* 全局容器 */
63 .success-container { 74 .success-container {
64 display: flex; 75 display: flex;
65 flex-direction: column; 76 flex-direction: column;
66 align-items: center; 77 align-items: center;
...@@ -68,16 +79,16 @@ onLoad((option) => { ...@@ -68,16 +79,16 @@ onLoad((option) => {
68 min-height: 100vh; 79 min-height: 100vh;
69 background-color: #f8f9fa; 80 background-color: #f8f9fa;
70 box-sizing: border-box; 81 box-sizing: border-box;
71 } 82 }
72 83
73 /* 成功图标容器 */ 84 /* 成功图标容器 */
74 .success-icon { 85 .success-icon {
75 margin-bottom: 40rpx; 86 margin-bottom: 40rpx;
76 animation: fadeIn 0.6s ease-out; 87 animation: fadeIn 0.6s ease-out;
77 } 88 }
78 89
79 /* 渐变圆形背景 */ 90 /* 渐变圆形背景 */
80 .icon-circle { 91 .icon-circle {
81 width: 180rpx; 92 width: 180rpx;
82 height: 180rpx; 93 height: 180rpx;
83 border-radius: 50%; 94 border-radius: 50%;
...@@ -89,34 +100,34 @@ onLoad((option) => { ...@@ -89,34 +100,34 @@ onLoad((option) => {
89 box-shadow: 0 8rpx 30rpx rgba(6, 193, 174, 0.3); 100 box-shadow: 0 8rpx 30rpx rgba(6, 193, 174, 0.3);
90 /* 轻微上浮动效 */ 101 /* 轻微上浮动效 */
91 animation: scaleIn 0.8s ease-out; 102 animation: scaleIn 0.8s ease-out;
92 } 103 }
93 104
94 /* 对勾图标 */ 105 /* 对勾图标 */
95 .check-icon { 106 .check-icon {
96 font-size: 90rpx; 107 font-size: 90rpx;
97 color: #ffffff; 108 color: #ffffff;
98 font-weight: bold; 109 font-weight: bold;
99 } 110 }
100 111
101 /* 支付成功标题 */ 112 /* 支付成功标题 */
102 .success-title { 113 .success-title {
103 font-size: 48rpx; 114 font-size: 48rpx;
104 font-weight: 700; 115 font-weight: 700;
105 color: #333333; 116 color: #333333;
106 margin-bottom: 12rpx; 117 margin-bottom: 12rpx;
107 animation: slideUp 0.6s ease-out; 118 animation: slideUp 0.6s ease-out;
108 } 119 }
109 120
110 /* 副标题 */ 121 /* 副标题 */
111 .success-subtitle { 122 .success-subtitle {
112 font-size: 28rpx; 123 font-size: 28rpx;
113 color: #666666; 124 color: #666666;
114 margin-bottom: 60rpx; 125 margin-bottom: 60rpx;
115 animation: slideUp 0.8s ease-out; 126 animation: slideUp 0.8s ease-out;
116 } 127 }
117 128
118 /* 订单信息卡片 */ 129 /* 订单信息卡片 */
119 .info-card { 130 .info-card {
120 width: 100%; 131 width: 100%;
121 background: #ffffff; 132 background: #ffffff;
122 border-radius: 20rpx; 133 border-radius: 20rpx;
...@@ -124,48 +135,55 @@ onLoad((option) => { ...@@ -124,48 +135,55 @@ onLoad((option) => {
124 box-shadow: 0 6rpx 20rpx rgba(0, 0, 0, 0.05); 135 box-shadow: 0 6rpx 20rpx rgba(0, 0, 0, 0.05);
125 margin-bottom: 80rpx; 136 margin-bottom: 80rpx;
126 animation: fadeIn 1s ease-out; 137 animation: fadeIn 1s ease-out;
127 } 138 }
128 139
129 /* 单个信息项 */ 140 /* 单个信息项 */
130 .info-item { 141 .info-item {
131 display: flex; 142 display: flex;
132 justify-content: space-between; 143 justify-content: space-between;
133 align-items: center; 144 align-items: center;
134 padding: 24rpx 0; 145 padding: 24rpx 0;
135 border-bottom: 1rpx solid #f5f5f5; 146 border-bottom: 1rpx solid #f5f5f5;
136 } 147 }
137 /* 最后一项去掉下划线 */ 148
138 .info-item:last-child { 149 /* 最后一项去掉下划线 */
150 .info-item:last-child {
139 border-bottom: none; 151 border-bottom: none;
140 } 152 }
141 153
142 /* 标签样式 */ 154 /* 标签样式 */
143 .label { 155 .label {
144 font-size: 32rpx; 156 font-size: 32rpx;
145 color: #666666; 157 color: #666666;
146 } 158 white-space: nowrap;
159 margin-right: 20rpx;
160 flex-shrink: 0;
161 }
147 162
148 /* 值样式 */ 163 /* 值样式 */
149 .value { 164 .value {
150 font-size: 32rpx; 165 font-size: 32rpx;
151 color: #333333; 166 color: #333333;
152 text-align: right; 167 text-align: right;
153 } 168 word-break: break-all;
154 /* 金额特殊样式 */ 169 word-wrap: break-word;
155 .amount { 170 }
171
172 /* 金额特殊样式 */
173 .amount {
156 color: #cd1e27; 174 color: #cd1e27;
157 font-weight: 600; 175 font-weight: 600;
158 } 176 }
159 177
160 /* 确定按钮区域 */ 178 /* 确定按钮区域 */
161 .confirm-btn-area { 179 .confirm-btn-area {
162 width: 100%; 180 width: 100%;
163 padding: 0 20rpx; 181 padding: 0 20rpx;
164 box-sizing: border-box; 182 box-sizing: border-box;
165 } 183 }
166 184
167 /* 确定按钮(渐变+动效) */ 185 /* 确定按钮(渐变+动效) */
168 .confirm-btn { 186 .confirm-btn {
169 width: 100%; 187 width: 100%;
170 height: 90rpx; 188 height: 90rpx;
171 line-height: 90rpx; 189 line-height: 90rpx;
...@@ -180,28 +198,52 @@ onLoad((option) => { ...@@ -180,28 +198,52 @@ onLoad((option) => {
180 /* 禁止默认样式 */ 198 /* 禁止默认样式 */
181 position: relative; 199 position: relative;
182 overflow: hidden; 200 overflow: hidden;
183 } 201 }
184 /* 按钮点击反馈 */ 202
185 .confirm-btn::after { 203 /* 按钮点击反馈 */
204 .confirm-btn::after {
186 border: none; 205 border: none;
187 } 206 }
188 .confirm-btn:active { 207
208 .confirm-btn:active {
189 transform: scale(0.98); 209 transform: scale(0.98);
190 box-shadow: 0 4rpx 10rpx rgba(6, 193, 174, 0.2); 210 box-shadow: 0 4rpx 10rpx rgba(6, 193, 174, 0.2);
191 } 211 }
192 212
193 /* 动画定义 */ 213 /* 动画定义 */
194 @keyframes fadeIn { 214 @keyframes fadeIn {
195 0% { opacity: 0; } 215 0% {
196 100% { opacity: 1; } 216 opacity: 0;
197 } 217 }
198 @keyframes scaleIn { 218
199 0% { transform: scale(0); } 219 100% {
200 70% { transform: scale(1.1); } 220 opacity: 1;
201 100% { transform: scale(1); } 221 }
202 } 222 }
203 @keyframes slideUp { 223
204 0% { opacity: 0; transform: translateY(30rpx); } 224 @keyframes scaleIn {
205 100% { opacity: 1; transform: translateY(0); } 225 0% {
206 } 226 transform: scale(0);
227 }
228
229 70% {
230 transform: scale(1.1);
231 }
232
233 100% {
234 transform: scale(1);
235 }
236 }
237
238 @keyframes slideUp {
239 0% {
240 opacity: 0;
241 transform: translateY(30rpx);
242 }
243
244 100% {
245 opacity: 1;
246 transform: translateY(0);
247 }
248 }
207 </style> 249 </style>
...\ No newline at end of file ...\ No newline at end of file
......
1 ## 2.1.6(2023-04-16)
2 * 修复 组件使用 v-show 指令会导致选择图片后初始位置严重偏位的问题
3 ## 2.1.5(2023-04-16)
4 * 新增 兼容APP平台
5
6 ## 2.1.4(2023-03-13)
7 * 新增 fileType 属性,用于指定生成文件的类型,只支持 'jpg' 或 'png',默认为 'png'
8 * 新增 delay 属性,微信小程序平台使用 `Canvas 2D` 绘制时控制图片从绘制到生成所需时间
9 * 优化 当生成图片的尺寸宽/高超过 Canvas 2D 最大限制(1365*1365)则将画布尺寸缩放在限制范围内绘制完成后输出目标尺寸
10 * 优化 旋转图标指示方向与实际旋转方向不符
11
12 ## 2.1.3(2023-02-06)
13 * 优化 vue3支持
14
15 ## 2.1.2(2023-02-03)
16 * 新增 navigation 属性,H5平台当 showAngle 为 true 时,使用插件的页面在 `page.json` 中配置了 "navigationStyle": "custom" 时,必须将此值设为 false ,否则四个可拉伸角的触发位置会有偏差
17 * 修复 H5平台部分设备(已知iPhone11以下机型)拍照的图片缩放时会闪动的问题
18
19 ## 2.1.1(2022-12-06)
20 * 修复 横屏适配问题
21
22 ## 2.1.0(2022-12-06)
23 * 新增 兼容H5平台,使用 renderjs 响应手势事件
24
25 ## 2.0.0(2022-12-05)
26 * 重构 插件,使用 WXS 响应手势事件
27 * 新增 图片翻转
28 * 新增 拉伸裁剪框放大图片
29 * 新增 监听PC鼠标滚轮触发缩放
30 * 新增 圆形、圆角矩形的图片裁剪
31 * 优化 图片缩放,移动端以双指触摸中心点为缩放中心点,PC端以鼠标所在点为缩放中心点
32 * 优化 裁剪框样式
33 * 优化 图片位置拖动 支持边界回弹效果(滑动时可滑出边界,释放时回弹到边界)
34 * 优化 生成图片使用新版 Canvas 2D 接口
1 {
2 "id": "qf-image-cropper",
3 "displayName": "图片裁剪插件",
4 "version": "2.1.6",
5 "description": "图片裁剪插件,支持自定义尺寸、定点等比例缩放、拖动、图片翻转、剪切圆形/圆角图片、定制样式,功能多性能高体验好注释全。",
6 "keywords": [
7 "qf-image-cropper",
8 "图片裁剪",
9 "图片编辑",
10 "头像裁剪",
11 "小程序"
12 ],
13 "repository": "",
14 "engines": {
15 "HBuilderX": "^3.1.0"
16 },
17 "dcloudext": {
18 "type": "component-vue",
19 "sale": {
20 "regular": {
21 "price": "0.00"
22 },
23 "sourcecode": {
24 "price": "0.00"
25 }
26 },
27 "contact": {
28 "qq": ""
29 },
30 "declaration": {
31 "ads": "无",
32 "data": "插件不采集任何数据",
33 "permissions": "无"
34 },
35 "npmurl": ""
36 },
37 "uni_modules": {
38 "dependencies": [],
39 "encrypt": [],
40 "platforms": {
41 "client": {
42 "Vue": {
43 "vue2": "y",
44 "vue3": "y"
45 },
46 "App": {
47 "app-vue": "y",
48 "app-nvue": "n"
49 },
50 "H5-mobile": {
51 "Safari": "y",
52 "Android Browser": "y",
53 "微信浏览器(Android)": "y",
54 "QQ浏览器(Android)": "u"
55 },
56 "H5-pc": {
57 "Chrome": "u",
58 "IE": "u",
59 "Edge": "u",
60 "Firefox": "u",
61 "Safari": "u"
62 },
63 "小程序": {
64 "微信": "y",
65 "阿里": "n",
66 "百度": "n",
67 "字节跳动": "n",
68 "QQ": "u",
69 "钉钉": "n",
70 "快手": "n",
71 "飞书": "n",
72 "京东": "n"
73 },
74 "快应用": {
75 "华为": "n",
76 "联盟": "n"
77 }
78 }
79 }
80 }
81 }
...\ No newline at end of file ...\ No newline at end of file
1 # qf-image-cropper
2 ## 图片裁剪插件
3 uniapp微信小程序图片裁剪插件,支持自定义尺寸、定点等比例缩放、拖动、图片翻转、剪切圆形/圆角图片、定制样式,功能多性能高体验好注释全。
4
5 ### 平台支持:
6 1. 支持微信小程序:移动端、PC端、开发者工具
7 2. 支持H5平台(2.1.0版本起)
8 3. 支持APP平台(2.1.5版本起):Android、IOS
9 4. 其他平台暂未测试兼容性未知
10
11 ### 支持功能:
12 1. 自定义裁剪尺寸
13 2. 定点等比例缩放:移动端以双指触摸中心点为缩放中心点,PC端以鼠标所在点为缩放中心点
14 3. 自由拖动:支持限制滑出边界,也支持回弹效果(滑动时可滑出边界,释放时回弹到边界)
15 4. 图片翻转:在裁剪尺寸非 1:1 的情况下,翻转时宽高无法铺满裁剪区域时,图片会自动放大到合适尺寸
16 5. 裁剪生成新图片
17 6. 本地选择图片
18 7. 可定制样式:可自由选择是否渲染裁剪边框、可伸缩裁剪顶角、参考线
19 8. 裁剪圆角图片:圆形、圆角矩形
20
21 ### 属性说明
22 | 属性名 | 类型 | 默认值 | 说明 |
23 |:---|:---|:---|:---|
24 | src | String | | 图片资源地址 |
25 | width | Number | 300 | 裁剪宽度 |
26 | height | Number | 300 | 裁剪高度 |
27 | showBorder | Boolean | true | 是否绘制裁剪区域边框 |
28 | showGrid | Boolean | true | 是否绘制裁剪区域网格参考线 |
29 | showAngle | Boolean | true | 是否展示四个支持伸缩的角 |
30 | areaScale | Number | 0.3 | 裁剪区域最小缩放倍数 |
31 | maxScale | Number | 5 | 图片最大缩放倍数 |
32 | bounce | Boolean | true | 是否有回弹效果:拖动时可以拖出边界,释放时会弹回边界 |
33 | rotatable | Boolean | true | 是否支持翻转 |
34 | choosable | Boolean | true | 是否支持从本地选择素材 |
35 | angleSize | Number | 20 | 四个角尺寸,单位px |
36 | angleBorderWidth | Number | 2 | 四个角边框宽度,单位px |
37 | radius | Number | | 裁剪图片圆角半径,单位px |
38 | fileType | String | png | 生成文件的类型,只支持 'jpg' 或 'png'。默认为 'png' |
39 | delay | Number | 1000 | 图片从绘制到生成所需时间,单位ms<br>微信小程序平台使用 `Canvas 2D` 绘制时有效<br>如绘制大图或出现裁剪图片空白等情况应适当调大该值,因 `Canvas 2d` 采用同步绘制,需自己把控绘制完成时间 |
40 | navigation | Boolean | true | 页面是否是原生标题栏:<br>H5平台当 showAngle 为 true 时,使用插件的页面在 `page.json` 中配置了 `"navigationStyle": "custom"` 时,必须将此值设为 false ,否则四个可拉伸角的触发位置会有偏差。<br>注:因H5平台的窗口高度是包含标题栏的,而屏幕触摸点的坐标是不包含的 |
41 | @crop | EventHandle | | 剪裁完成后触发,event = { tempFilePath }。在H5平台下,tempFilePath 为 base64 |
42
43 ### 基本用法
44 ```
45 <template>
46 <div>
47 <qf-image-cropper :width="500" :height="500" :radius="30" @crop="handleCrop"></qf-image-cropper>
48 </div>
49 </template>
50
51 <script>
52 import QfImageCropper from '@/components/qf-image-cropper/qf-image-cropper.vue';
53 export default {
54 components: {
55 QfImageCropper
56 },
57 methods: {
58 handleCrop(e) {
59 uni.previewImage({
60 urls: [e.tempFilePath],
61 current: 0
62 });
63 }
64 }
65 }
66 </script>
67 ```
68 ### 使用说明
69 1.建议在`pages.json`中将引用插件的页面添加一下配置禁止下拉刷新和禁止页面滑动,防止出现性能或页面抖动等问题。
70 ```
71 {
72 "enablePullDownRefresh": false,
73 "disableScroll": true
74 }
75 ```
76 2.建议使用本插件不要设置过大宽高的目标图片尺寸,建议1365x1365以内,否则可能会导致如下问题:
77 ```
78 1.界面卡顿,内存占用过高
79 2.生成图片失真(模糊)
80 3.确定裁剪后一直显示 `裁剪中...`,该问题是由 `uni.canvasToTempFilePath` 无法回调导致,不同平台不同设备限制可能有所不同。
81 ```
82 3.如裁剪后的图片存在偏移的问题,请检查是否受自己项目中父组件或全局样式影响。
83 4.src属性设置网络图片时,图片资源必须是能触发 `getImageInfo` API 的 success 回调才可用于插件裁剪。因此小程序平台获取网络图片信息需先配置download域名白名单才能生效。
...\ No newline at end of file ...\ No newline at end of file
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!