feat:抖音支付
This commit is contained in:
@@ -113,6 +113,8 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view @click="aaa">亲星星</view>
|
||||
|
||||
<view class="home_actived_warp">
|
||||
<view class="home_actived_item_warp" v-for="item in homeActivedList" :key="item.id">
|
||||
<view class="home_actived_item">
|
||||
@@ -215,7 +217,66 @@
|
||||
</view>
|
||||
</view>
|
||||
</up-overlay>
|
||||
|
||||
<!-- 专属优惠券弹窗 -->
|
||||
<up-overlay :show="showCouponPop" @click="showCouponPop = false" zIndex="10090">
|
||||
<view class="coupon_pop_wrapper">
|
||||
<view class="coupon_pop_card" @tap.stop>
|
||||
<!-- 头部标题与关闭按钮 -->
|
||||
<view class="coupon_pop_header">
|
||||
<view class="coupon_pop_title">专属优惠券已到账</view>
|
||||
<view class="coupon_pop_close" @click="showCouponPop = false">
|
||||
<text class="close_x">✕</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 优惠券列表 -->
|
||||
<scroll-view class="coupon_pop_list" scroll-y>
|
||||
<view class="coupon_item" v-for="(item, index) in popCouponList"
|
||||
:key="item.couponUserId || item.templateId || index">
|
||||
<!-- 左侧金额与门槛 -->
|
||||
<view class="coupon_left">
|
||||
<view class="price_wrap">
|
||||
<text class="currency">¥</text>
|
||||
<text class="amount">{{ item.discountAmount }}</text>
|
||||
</view>
|
||||
<view class="threshold_tag">{{ formatThresholdText(item) }}</view>
|
||||
</view>
|
||||
|
||||
<!-- 垂直虚线分割线 -->
|
||||
<view class="coupon_divider">
|
||||
<view class="notch notch_top"></view>
|
||||
<view class="dashed_line"></view>
|
||||
<view class="notch notch_bottom"></view>
|
||||
</view>
|
||||
|
||||
<!-- 右侧优惠券信息 -->
|
||||
<view class="coupon_right">
|
||||
<view class="coupon_name">{{ item.title || '限时秒杀优惠券' }}</view>
|
||||
<view class="coupon_scope_box">
|
||||
<text class="scope_badge">{{ formatScopeBadge(item) }}</text>
|
||||
<text class="scope_text">{{ item.scopeText || (item.scopeType === 1 ? '所有商品可用' : '部分商品可用') }}</text>
|
||||
</view>
|
||||
<view class="coupon_validity">{{ formatValidityText(item) }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<!-- 立即收下按钮 -->
|
||||
<view class="coupon_pop_btn" @click="showCouponPop = false">
|
||||
立即收下
|
||||
</view>
|
||||
|
||||
<!-- 底部说明文案 -->
|
||||
<view class="coupon_pop_tip">
|
||||
优惠券详情可在【我的-优惠券】中查看
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</up-overlay>
|
||||
|
||||
<HomePopup :show="homeShow" :dataObj="curData" @jumpShop="onJumpShop" @close="homeShow = false"></HomePopup>
|
||||
<GuidePopup />
|
||||
<qiaobao-assistant page-key="pages/home/home" title="商城首页" />
|
||||
</view>
|
||||
</template>
|
||||
@@ -238,6 +299,7 @@ import useTabber from "tabber-component";
|
||||
import { getNewsList } from "@/api/news.js";
|
||||
import { comparisonVersionHandler } from "@/utils/index.js";
|
||||
import HomePopup from "@/components/common/home-popup.vue";
|
||||
import GuidePopup from "@/components/common/guide-popup.vue";
|
||||
import productSeckillCard from "@/components/common/product-seckill-card.vue";
|
||||
import { SHARE_URL } from "@/utils/config.js";
|
||||
import { getUnreadCount as getKefuUnreadCount } from "@/uni_modules/hashmall-customer-service/js_sdk/api.js";
|
||||
@@ -246,12 +308,14 @@ import {
|
||||
startKefuRealtime,
|
||||
} from "@/uni_modules/hashmall-customer-service/js_sdk/kefu-realtime.js";
|
||||
import { getStorageFun, TOKEN_NAME, USER_DATA } from "@/utils/auth.js";
|
||||
import { getPopNotifyList } from "@/api/coupon.js";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
choiceness,
|
||||
CustomTabBar,
|
||||
HomePopup,
|
||||
GuidePopup,
|
||||
productSeckillCard,
|
||||
},
|
||||
data() {
|
||||
@@ -304,6 +368,8 @@ export default {
|
||||
kefuUnreadRefreshTimer: null,
|
||||
isScrolled: false,
|
||||
scrollTop: 0,
|
||||
showCouponPop: false,
|
||||
popCouponList: [],
|
||||
};
|
||||
},
|
||||
onPageScroll(e) {
|
||||
@@ -337,6 +403,7 @@ export default {
|
||||
this.querySearchList(SEARCH_TYPE.EXPLOSIVE); // 爆单专区
|
||||
this.onNews(); // 获取公告
|
||||
this.getCarouselImage();
|
||||
this.fetchPopNotifyList(); // 获取专属优惠券弹窗通知
|
||||
|
||||
|
||||
// 秒杀
|
||||
@@ -394,6 +461,11 @@ export default {
|
||||
// #endif
|
||||
},
|
||||
methods: {
|
||||
aaa() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/other_package/douyin_pay_test/douyin_pay_test'
|
||||
});
|
||||
},
|
||||
getScrollTop(e) {
|
||||
let top = 0;
|
||||
if (typeof e === "number") {
|
||||
@@ -885,6 +957,47 @@ export default {
|
||||
url: "/pages/other_package/productInfo/productInfo?id=" + item.id,
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 查询专属优惠券弹窗通知
|
||||
*/
|
||||
fetchPopNotifyList() {
|
||||
if (!getStorageFun(TOKEN_NAME)) {
|
||||
return;
|
||||
}
|
||||
getPopNotifyList({ page: 1, pageSize: 100 })
|
||||
.then((res) => {
|
||||
if (res && res.bizcode === 100) {
|
||||
const list = res.data?.entitys || res.data || [];
|
||||
if (Array.isArray(list) && list.length > 0) {
|
||||
this.popCouponList = list;
|
||||
this.showCouponPop = true;
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error("获取首页优惠券弹窗失败", err);
|
||||
});
|
||||
},
|
||||
formatThresholdText(item) {
|
||||
if (!item || !item.thresholdAmount || Number(item.thresholdAmount) === 0) {
|
||||
return "无门槛";
|
||||
}
|
||||
return "满减券";
|
||||
},
|
||||
formatScopeBadge(item) {
|
||||
if (item && item.scopeType === 1) {
|
||||
return "通用券";
|
||||
}
|
||||
return "满减券";
|
||||
},
|
||||
formatValidityText(item) {
|
||||
if (item && item.startTime && item.endTime) {
|
||||
const start = dayjs(item.startTime).format("YYYY.MM.DD");
|
||||
const end = dayjs(item.endTime).format("YYYY.MM.DD");
|
||||
return `${start}-${end}`;
|
||||
}
|
||||
return "领取之日起30天有效";
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
isBlockedDate() {
|
||||
@@ -1657,4 +1770,211 @@ export default {
|
||||
bottom: 60rpx;
|
||||
}
|
||||
}
|
||||
|
||||
/* 专属优惠券弹窗 */
|
||||
.coupon_pop_wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.coupon_pop_card {
|
||||
width: 620rpx;
|
||||
background: #ffffff;
|
||||
border-radius: 32rpx;
|
||||
padding: 36rpx 32rpx 36rpx;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
|
||||
.coupon_pop_header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
margin-bottom: 28rpx;
|
||||
|
||||
.coupon_pop_title {
|
||||
font-size: 34rpx;
|
||||
font-weight: bold;
|
||||
color: #333333;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.coupon_pop_close {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 44rpx;
|
||||
height: 44rpx;
|
||||
// border: 2rpx solid #dcdcdc;
|
||||
border-radius: 8rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.close_x {
|
||||
color: #999999;
|
||||
font-size: 24rpx;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.coupon_pop_list {
|
||||
max-height: 520rpx;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.coupon_item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: #fff5f5;
|
||||
border-radius: 20rpx;
|
||||
height: 160rpx;
|
||||
margin-bottom: 20rpx;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.coupon_left {
|
||||
width: 200rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.price_wrap {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
color: #ff1e27;
|
||||
|
||||
.currency {
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
margin-right: 2rpx;
|
||||
}
|
||||
|
||||
.amount {
|
||||
font-size: 56rpx;
|
||||
font-weight: bold;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.threshold_tag {
|
||||
font-size: 24rpx;
|
||||
color: #ff1e27;
|
||||
font-weight: bold;
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.coupon_divider {
|
||||
width: 1rpx;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
|
||||
.dashed_line {
|
||||
position: absolute;
|
||||
top: 16rpx;
|
||||
bottom: 16rpx;
|
||||
width: 0;
|
||||
border-left: 2rpx dashed #ffcdcd;
|
||||
}
|
||||
|
||||
.notch {
|
||||
width: 20rpx;
|
||||
height: 20rpx;
|
||||
background-color: #ffffff;
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
|
||||
&.notch_top {
|
||||
top: -10rpx;
|
||||
}
|
||||
|
||||
&.notch_bottom {
|
||||
bottom: -10rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.coupon_right {
|
||||
flex: 1;
|
||||
padding-left: 24rpx;
|
||||
padding-right: 16rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
|
||||
.coupon_name {
|
||||
font-size: 30rpx;
|
||||
font-weight: bold;
|
||||
color: #222222;
|
||||
margin-bottom: 8rpx;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.coupon_scope_box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 8rpx;
|
||||
|
||||
.scope_badge {
|
||||
font-size: 20rpx;
|
||||
color: #ff2437;
|
||||
border: 1rpx solid #ff8d96;
|
||||
background: #fff0f0;
|
||||
border-radius: 6rpx;
|
||||
padding: 2rpx 10rpx;
|
||||
margin-right: 12rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.scope_text {
|
||||
font-size: 22rpx;
|
||||
color: #666666;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.coupon_validity {
|
||||
font-size: 22rpx;
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
|
||||
.coupon_pop_btn {
|
||||
width: 100%;
|
||||
height: 88rpx;
|
||||
line-height: 88rpx;
|
||||
background: #ff1e27;
|
||||
border-radius: 44rpx;
|
||||
color: #ffffff;
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
|
||||
.coupon_pop_tip {
|
||||
font-size: 24rpx;
|
||||
color: #999999;
|
||||
text-align: center;
|
||||
margin-top: 24rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
<template>
|
||||
<view class="news_warp">
|
||||
<Header leftTitle="商学院" left-path-type="switchTab" left-path="/pages/mine/mine"
|
||||
<Header leftTitle="资讯" left-path-type="switchTab" left-path="/pages/mine/mine"
|
||||
style="background-color: #FFFFFF;" />
|
||||
<view class="news_content_warp">
|
||||
<view class="heder_">
|
||||
<view v-for="item in titleList" :key="item.key"
|
||||
:class="form.type === item.key ? 'heder_item_sel heder_item' : 'heder_item'" @click="headerClick(item)">
|
||||
:class="form.type === item.key ? 'heder_item_sel heder_item' : 'heder_item'"
|
||||
@click="headerClick(item)">
|
||||
{{ item.value }}
|
||||
</view>
|
||||
</view>
|
||||
@@ -15,8 +16,8 @@
|
||||
<template #indicator>
|
||||
<view class="indicator-num">
|
||||
<text class="indicator-num__text">{{ currentNum + 1 }}/{{ swiperList.length }}</text>
|
||||
<qiaobao-assistant page-key="pages/login_package/news/news" title="商城公告" />
|
||||
</view>
|
||||
<qiaobao-assistant page-key="pages/login_package/news/news" title="商城公告" />
|
||||
</view>
|
||||
</template>
|
||||
</up-swiper>
|
||||
</view>
|
||||
@@ -32,8 +33,8 @@
|
||||
</template>
|
||||
</up-input>
|
||||
|
||||
<view class="news_content_item" v-for="item in newsList" :key="item.id" v-if="newsList && newsList.length !== 0"
|
||||
@click="jumpInfo(item)">
|
||||
<view class="news_content_item" v-for="item in newsList" :key="item.id"
|
||||
v-if="newsList && newsList.length !== 0" @click="jumpInfo(item)">
|
||||
<view class="news_content_item_warp">
|
||||
<view class="news_content_item_title">{{ item.title }}</view>
|
||||
<view v-html="item.subTitle" class="news_content_item_content"></view>
|
||||
@@ -41,14 +42,16 @@
|
||||
<view>{{ formatDate(item.ctdate) }}</view>
|
||||
<view class="browses_">
|
||||
<view>
|
||||
<up-image src="/pages/login_package/static/login/show.png" width="20" height="20" bgColor="#f1f6ff00"></up-image>
|
||||
<up-image src="/pages/login_package/static/login/show.png" width="20" height="20"
|
||||
bgColor="#f1f6ff00"></up-image>
|
||||
</view>
|
||||
<view style="margin-left: 8rpx;">{{ item.browses }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view>
|
||||
<up-image :src="item.coverImage" width="100" height="100" bgColor="#f1f6ff00" radius="8"></up-image>
|
||||
<up-image :src="item.coverImage" width="100" height="100" bgColor="#f1f6ff00"
|
||||
radius="8"></up-image>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else class="not_order_warp">
|
||||
|
||||
+1
-1
@@ -381,7 +381,7 @@ export default {
|
||||
// },
|
||||
{
|
||||
id: 8,
|
||||
title: '商学院资讯',
|
||||
title: '资讯',
|
||||
url: 'https://static.tbmall.xin/static/mine/tool_sxy.png',
|
||||
path: '/pages/login_package/news/news'
|
||||
},
|
||||
|
||||
@@ -1,32 +1,18 @@
|
||||
<template>
|
||||
<view class="address_add_warp">
|
||||
<Header
|
||||
:leftTitle="titleText"
|
||||
leftPath="1"
|
||||
/>
|
||||
<Header :leftTitle="titleText" leftPath="1" />
|
||||
<view class="address_form">
|
||||
<view class="add_form_item add_form_item_but">
|
||||
<view class="add_form_title">收货人</view>
|
||||
<up-input
|
||||
placeholder="收货人"
|
||||
border="surround"
|
||||
v-model="form.name"
|
||||
:customStyle="{
|
||||
border: '0rpx',
|
||||
}"
|
||||
></up-input>
|
||||
<up-input placeholder="收货人" border="surround" v-model="form.name" :customStyle="{
|
||||
border: '0rpx',
|
||||
}"></up-input>
|
||||
</view>
|
||||
<view class="add_form_item add_form_item_but">
|
||||
<view class="add_form_title">手机号码</view>
|
||||
<up-input
|
||||
placeholder="请填写收货人手机号"
|
||||
border="surround"
|
||||
v-model="form.mobile"
|
||||
:customStyle="{
|
||||
border: '0rpx',
|
||||
}"
|
||||
type="number"
|
||||
></up-input>
|
||||
<up-input placeholder="请填写收货人手机号" border="surround" v-model="form.mobile" :customStyle="{
|
||||
border: '0rpx',
|
||||
}" type="number" maxlength="11"></up-input>
|
||||
</view>
|
||||
<view class="add_form_item add_form_item_but">
|
||||
<view class="add_form_title">所在地区</view>
|
||||
@@ -34,25 +20,15 @@
|
||||
<view style="color: #808080; margin-left: 22rpx; font-size: 28rpx">{{
|
||||
(form.regionStr && form.regionStr.join("/")) || "所在地区"
|
||||
}}</view>
|
||||
<up-image
|
||||
src="/static/common/right_soild.png"
|
||||
width="14"
|
||||
height="14"
|
||||
bgColor="#f1f6ff00"
|
||||
></up-image>
|
||||
<up-image src="/static/common/right_soild.png" width="14" height="14" bgColor="#f1f6ff00"></up-image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="add_form_item">
|
||||
<view class="add_form_title">详细地址</view>
|
||||
<up-input
|
||||
placeholder="门牌号、小区、楼栋号、单元室等"
|
||||
border="surround"
|
||||
v-model="form.address"
|
||||
:customStyle="{
|
||||
border: '0rpx',
|
||||
height: '100rpx',
|
||||
}"
|
||||
></up-input>
|
||||
<up-input placeholder="门牌号、小区、楼栋号、单元室等" border="surround" v-model="form.address" :customStyle="{
|
||||
border: '0rpx',
|
||||
height: '100rpx',
|
||||
}"></up-input>
|
||||
</view>
|
||||
</view>
|
||||
<!-- <view class="address_default">
|
||||
@@ -78,10 +54,10 @@
|
||||
@cancel="regionShow = false"
|
||||
@close="regionShow = false"
|
||||
></up-picker> -->
|
||||
<AddressPopup @ok="onOk"
|
||||
:show="regionShow" @itemSelect="onItemSelect" @select="onSelect" :curSelect="curSelect" :selectList="curSelectList" :dataList="addressList" @close="onClose"></AddressPopup>
|
||||
<qiaobao-assistant page-key="pages/mine_package/mine_address_add/mine_address_add" title="编辑收货地址" />
|
||||
</view>
|
||||
<AddressPopup @ok="onOk" :show="regionShow" @itemSelect="onItemSelect" @select="onSelect" :curSelect="curSelect"
|
||||
:selectList="curSelectList" :dataList="addressList" @close="onClose"></AddressPopup>
|
||||
<qiaobao-assistant page-key="pages/mine_package/mine_address_add/mine_address_add" title="编辑收货地址" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -91,10 +67,10 @@ import AddressPopup from '@/components/common/address-popup.vue'
|
||||
import Header from "@/components/header.vue";
|
||||
|
||||
export default {
|
||||
components: { Header,AddressPopup },
|
||||
components: { Header, AddressPopup },
|
||||
data() {
|
||||
return {
|
||||
titleText:'添加地址',
|
||||
titleText: '添加地址',
|
||||
form: {
|
||||
id: 0,
|
||||
name: null, // 收货人
|
||||
@@ -108,9 +84,9 @@ export default {
|
||||
address: null, // 详细地址
|
||||
},
|
||||
regionShow: false,
|
||||
curSelect:-1,
|
||||
addressList:[],
|
||||
curSelectList:[],
|
||||
curSelect: -1,
|
||||
addressList: [],
|
||||
curSelectList: [],
|
||||
regionColumns: [],
|
||||
regionLoading: false,
|
||||
// leftPath: "/pages/mine_package/mine_address/mine_address",
|
||||
@@ -122,81 +98,81 @@ export default {
|
||||
const detail = option.detail;
|
||||
if (id && id !== 0) {
|
||||
this.getById(id);
|
||||
this.titleText = '修改地址';
|
||||
this.titleText = '修改地址';
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onItemSelect(item,xItem){
|
||||
this.curSelectList.push(xItem);
|
||||
this.curSelect++;
|
||||
this.getAddressList(xItem.id).then(() => {
|
||||
if (!this.addressList.length) {
|
||||
this.onOk();
|
||||
}
|
||||
});
|
||||
},
|
||||
onSelect(item,index){
|
||||
this.curSelectList.splice(index + 1);
|
||||
this.curSelect = index;
|
||||
this.getAddressList(this.curSelectList[this.curSelectList.length - 1].id);
|
||||
},
|
||||
async getAddressList(id = 0){
|
||||
const params = {
|
||||
parentId: id,
|
||||
};
|
||||
const resp = await getCascadeRegion(params);
|
||||
if (resp.bizcode === 100) {
|
||||
|
||||
this.addressList = [];
|
||||
resp.data.forEach(item=>{
|
||||
if(this.addressList.length){
|
||||
let index = this.addressList.findIndex(i=>i.zi == item.firstLetter);
|
||||
if(index != -1){
|
||||
this.addressList[index].data.push({id:item.id,pId:item.parentId,name:item.name});
|
||||
}else{
|
||||
this.addressList.push({zi:item.firstLetter,data:[{id:item.id,pId:item.parentId,name:item.name}]});
|
||||
}
|
||||
}else{
|
||||
this.addressList.push({zi:item.firstLetter,data:[{id:item.id,pId:item.parentId,name:item.name}]});
|
||||
}
|
||||
})
|
||||
this.addressList.sort((a,b)=>{
|
||||
if (a.zi < b.zi) return -1;
|
||||
if (a.zi > b.zi) return 1;
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
},
|
||||
onOk(){
|
||||
this.form.regionStr = [];
|
||||
this.curSelectList.forEach((item,index)=>{
|
||||
if(index == 0){
|
||||
this.form.countryId = item.id;
|
||||
this.form.regionStr.push(item.name);
|
||||
}else if(index == 1){
|
||||
this.form.provinceId = item.id;
|
||||
this.form.regionStr.push(item.name);
|
||||
}else if(index == 2){
|
||||
this.form.cityId = item.id;
|
||||
this.form.regionStr.push(item.name);
|
||||
}else if(index == 3){
|
||||
this.form.areaId = item.id;
|
||||
this.form.regionStr.push(item.name);
|
||||
}else if(index == 4){
|
||||
this.form.townshipId = item.id;
|
||||
this.form.regionStr.push(item.name);
|
||||
}
|
||||
})
|
||||
|
||||
console.log('areaId',this.form)
|
||||
this.onClose();
|
||||
},
|
||||
onClose(){
|
||||
this.regionShow=false;
|
||||
this.curSelect=false;
|
||||
this.addressList=[];
|
||||
this.curSelectList=[];
|
||||
},
|
||||
onItemSelect(item, xItem) {
|
||||
this.curSelectList.push(xItem);
|
||||
this.curSelect++;
|
||||
this.getAddressList(xItem.id).then(() => {
|
||||
if (!this.addressList.length) {
|
||||
this.onOk();
|
||||
}
|
||||
});
|
||||
},
|
||||
onSelect(item, index) {
|
||||
this.curSelectList.splice(index + 1);
|
||||
this.curSelect = index;
|
||||
this.getAddressList(this.curSelectList[this.curSelectList.length - 1].id);
|
||||
},
|
||||
async getAddressList(id = 0) {
|
||||
const params = {
|
||||
parentId: id,
|
||||
};
|
||||
const resp = await getCascadeRegion(params);
|
||||
if (resp.bizcode === 100) {
|
||||
|
||||
this.addressList = [];
|
||||
resp.data.forEach(item => {
|
||||
if (this.addressList.length) {
|
||||
let index = this.addressList.findIndex(i => i.zi == item.firstLetter);
|
||||
if (index != -1) {
|
||||
this.addressList[index].data.push({ id: item.id, pId: item.parentId, name: item.name });
|
||||
} else {
|
||||
this.addressList.push({ zi: item.firstLetter, data: [{ id: item.id, pId: item.parentId, name: item.name }] });
|
||||
}
|
||||
} else {
|
||||
this.addressList.push({ zi: item.firstLetter, data: [{ id: item.id, pId: item.parentId, name: item.name }] });
|
||||
}
|
||||
})
|
||||
this.addressList.sort((a, b) => {
|
||||
if (a.zi < b.zi) return -1;
|
||||
if (a.zi > b.zi) return 1;
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
},
|
||||
onOk() {
|
||||
this.form.regionStr = [];
|
||||
this.curSelectList.forEach((item, index) => {
|
||||
if (index == 0) {
|
||||
this.form.countryId = item.id;
|
||||
this.form.regionStr.push(item.name);
|
||||
} else if (index == 1) {
|
||||
this.form.provinceId = item.id;
|
||||
this.form.regionStr.push(item.name);
|
||||
} else if (index == 2) {
|
||||
this.form.cityId = item.id;
|
||||
this.form.regionStr.push(item.name);
|
||||
} else if (index == 3) {
|
||||
this.form.areaId = item.id;
|
||||
this.form.regionStr.push(item.name);
|
||||
} else if (index == 4) {
|
||||
this.form.townshipId = item.id;
|
||||
this.form.regionStr.push(item.name);
|
||||
}
|
||||
})
|
||||
|
||||
console.log('areaId', this.form)
|
||||
this.onClose();
|
||||
},
|
||||
onClose() {
|
||||
this.regionShow = false;
|
||||
this.curSelect = false;
|
||||
this.addressList = [];
|
||||
this.curSelectList = [];
|
||||
},
|
||||
/**
|
||||
* 用作编辑
|
||||
*/
|
||||
@@ -241,41 +217,41 @@ export default {
|
||||
|
||||
// 选择地址的弹框
|
||||
async regionShowCheck() {
|
||||
this.curSelectList = [];
|
||||
this.curSelect = -1;
|
||||
if(this.form.townshipId){
|
||||
this.curSelectList.push({id:this.form.countryId,name:this.form.regionStr[0]});
|
||||
this.curSelectList.push({id:this.form.provinceId,name:this.form.regionStr[1]});
|
||||
this.curSelectList.push({id:this.form.cityId,name:this.form.regionStr[2]});
|
||||
this.curSelectList.push({id:this.form.areaId,name:this.form.regionStr[3]});
|
||||
this.curSelectList.push({id:this.form.townshipId,name:this.form.regionStr[4]});
|
||||
this.curSelect = 4;
|
||||
await this.getAddressList(this.form.townshipId);
|
||||
}else if(this.form.areaId){
|
||||
this.curSelectList.push({id:this.form.countryId,name:this.form.regionStr[0]});
|
||||
this.curSelectList.push({id:this.form.provinceId,name:this.form.regionStr[1]});
|
||||
this.curSelectList.push({id:this.form.cityId,name:this.form.regionStr[2]});
|
||||
this.curSelectList.push({id:this.form.areaId,name:this.form.regionStr[3]});
|
||||
this.curSelect = 3;
|
||||
await this.getAddressList(this.form.areaId);
|
||||
}else if(this.form.cityId){
|
||||
this.curSelectList.push({id:this.form.countryId,name:this.form.regionStr[0]});
|
||||
this.curSelectList.push({id:this.form.provinceId,name:this.form.regionStr[1]});
|
||||
this.curSelectList.push({id:this.form.cityId,name:this.form.regionStr[2]});
|
||||
this.curSelect = 2;
|
||||
await this.getAddressList(this.form.cityId);
|
||||
}else if(this.form.provinceId){
|
||||
this.curSelectList.push({id:this.form.countryId,name:this.form.regionStr[0]});
|
||||
this.curSelectList.push({id:this.form.provinceId,name:this.form.regionStr[1]});
|
||||
this.curSelect = 1;
|
||||
await this.getAddressList(this.form.provinceId);
|
||||
}else if(this.form.countryId){
|
||||
this.curSelectList.push({id:this.form.countryId,name:this.form.regionStr[0]});
|
||||
this.curSelect = 0;
|
||||
await this.getAddressList(this.form.countryId);
|
||||
}else{
|
||||
await this.getAddressList();
|
||||
}
|
||||
this.curSelectList = [];
|
||||
this.curSelect = -1;
|
||||
if (this.form.townshipId) {
|
||||
this.curSelectList.push({ id: this.form.countryId, name: this.form.regionStr[0] });
|
||||
this.curSelectList.push({ id: this.form.provinceId, name: this.form.regionStr[1] });
|
||||
this.curSelectList.push({ id: this.form.cityId, name: this.form.regionStr[2] });
|
||||
this.curSelectList.push({ id: this.form.areaId, name: this.form.regionStr[3] });
|
||||
this.curSelectList.push({ id: this.form.townshipId, name: this.form.regionStr[4] });
|
||||
this.curSelect = 4;
|
||||
await this.getAddressList(this.form.townshipId);
|
||||
} else if (this.form.areaId) {
|
||||
this.curSelectList.push({ id: this.form.countryId, name: this.form.regionStr[0] });
|
||||
this.curSelectList.push({ id: this.form.provinceId, name: this.form.regionStr[1] });
|
||||
this.curSelectList.push({ id: this.form.cityId, name: this.form.regionStr[2] });
|
||||
this.curSelectList.push({ id: this.form.areaId, name: this.form.regionStr[3] });
|
||||
this.curSelect = 3;
|
||||
await this.getAddressList(this.form.areaId);
|
||||
} else if (this.form.cityId) {
|
||||
this.curSelectList.push({ id: this.form.countryId, name: this.form.regionStr[0] });
|
||||
this.curSelectList.push({ id: this.form.provinceId, name: this.form.regionStr[1] });
|
||||
this.curSelectList.push({ id: this.form.cityId, name: this.form.regionStr[2] });
|
||||
this.curSelect = 2;
|
||||
await this.getAddressList(this.form.cityId);
|
||||
} else if (this.form.provinceId) {
|
||||
this.curSelectList.push({ id: this.form.countryId, name: this.form.regionStr[0] });
|
||||
this.curSelectList.push({ id: this.form.provinceId, name: this.form.regionStr[1] });
|
||||
this.curSelect = 1;
|
||||
await this.getAddressList(this.form.provinceId);
|
||||
} else if (this.form.countryId) {
|
||||
this.curSelectList.push({ id: this.form.countryId, name: this.form.regionStr[0] });
|
||||
this.curSelect = 0;
|
||||
await this.getAddressList(this.form.countryId);
|
||||
} else {
|
||||
await this.getAddressList();
|
||||
}
|
||||
this.regionShow = true;
|
||||
},
|
||||
// 数据交互
|
||||
@@ -332,8 +308,8 @@ export default {
|
||||
this.form.areaId = regionId[3] ? regionId[3] : null;
|
||||
this.form.townshipId = regionId[4] ? regionId[4] : null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
this.regionShowCheck(false);
|
||||
},
|
||||
|
||||
@@ -356,6 +332,13 @@ export default {
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (!/^1[3-9]\d{9}$/.test(params.mobile)) {
|
||||
this.$refs.uToastRef.show({
|
||||
type: "error",
|
||||
message: "请输入正确的手机号码",
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (!params.regionStr) {
|
||||
this.$refs.uToastRef.show({
|
||||
type: "error",
|
||||
@@ -388,15 +371,15 @@ export default {
|
||||
if (!params.countryId || params.countryId === 0) {
|
||||
delete params.countryId;
|
||||
}
|
||||
|
||||
|
||||
delete params.regionStr;
|
||||
if(params.countryId != 47021){
|
||||
this.$refs.uToastRef.show({
|
||||
type: "error",
|
||||
message: '选择地址错误'
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (params.countryId != 47021) {
|
||||
this.$refs.uToastRef.show({
|
||||
type: "error",
|
||||
message: '选择地址错误'
|
||||
});
|
||||
return;
|
||||
}
|
||||
const res = await editAddress(params);
|
||||
if (res && res.bizcode === 100) {
|
||||
uni.$emit("refreshAddressList");
|
||||
|
||||
@@ -96,26 +96,25 @@
|
||||
<template v-if="orderInfo.orderPackages && orderInfo.orderPackages.length > 0">
|
||||
<view class="express_header_row">
|
||||
<view class="express_title">运单号</view>
|
||||
<view
|
||||
class="express_toggle_btn"
|
||||
v-if="orderInfo.orderPackages.length > 1"
|
||||
@click="isExpandExpress = !isExpandExpress"
|
||||
>
|
||||
<text>{{ isExpandExpress ? '收起' : `展开全部(${orderInfo.orderPackages.length})` }}</text>
|
||||
<u-icon :name="isExpandExpress ? 'arrow-up' : 'arrow-down'" color="#7934F6" size="12" style="margin-left: 4rpx;"></u-icon>
|
||||
<view class="express_toggle_btn" v-if="orderInfo.orderPackages.length > 1"
|
||||
@click="isExpandExpress = !isExpandExpress">
|
||||
<text>{{ isExpandExpress ? '收起' : `展开全部(${orderInfo.orderPackages.length})`
|
||||
}}</text>
|
||||
<u-icon :name="isExpandExpress ? 'arrow-up' : 'arrow-down'" color="#7934F6"
|
||||
size="12" style="margin-left: 4rpx;"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
<view
|
||||
class="express_item_row"
|
||||
<view class="express_item_row"
|
||||
v-for="(pkg, pkgIdx) in (isExpandExpress ? orderInfo.orderPackages : orderInfo.orderPackages.slice(0, 1))"
|
||||
:key="pkg.id || pkgIdx"
|
||||
>
|
||||
:key="pkg.id || pkgIdx">
|
||||
<view class="express_info_text">
|
||||
<text class="express_name_tag" v-if="pkg.expressName">{{ pkg.expressName }}</text>
|
||||
<text class="express_name_tag" v-if="pkg.expressName">{{ pkg.expressName
|
||||
}}</text>
|
||||
<text class="express_no_num">{{ pkg.expressNo }}</text>
|
||||
</view>
|
||||
<view class="express_copy_btn" @click="copyData(pkg.expressNo)">
|
||||
<up-image src="/static/common/copy.png" width="12" height="12" bgColor="#f1f6ff00"></up-image>
|
||||
<up-image src="/static/common/copy.png" width="12" height="12"
|
||||
bgColor="#f1f6ff00"></up-image>
|
||||
<text class="copy_text">复制</text>
|
||||
</view>
|
||||
</view>
|
||||
@@ -130,7 +129,8 @@
|
||||
<text class="express_no_num">{{ pItem.expressNo }}</text>
|
||||
</view>
|
||||
<view class="express_copy_btn" @click="copyData(pItem.expressNo)">
|
||||
<up-image src="/static/common/copy.png" width="12" height="12" bgColor="#f1f6ff00"></up-image>
|
||||
<up-image src="/static/common/copy.png" width="12" height="12"
|
||||
bgColor="#f1f6ff00"></up-image>
|
||||
<text class="copy_text">复制</text>
|
||||
</view>
|
||||
</view>
|
||||
@@ -225,8 +225,8 @@
|
||||
<view class="operate_comm operate_but_2" v-if="orderInfo.status === ORDER_TYPE.UNPAID" @click="goPay">去付款
|
||||
</view>
|
||||
<!-- <view class="operate_comm operate_but_1" v-if="orderInfo.status === ORDER_TYPE.COMPLETED">申请退款</view> -->
|
||||
<view class="operate_comm operate_but_1" style="border-color: #7732ff" v-if="orderInfo.status === ORDER_TYPE.NOT_RECEIVE"
|
||||
@click="onExpress(orderInfo.id)">
|
||||
<view class="operate_comm operate_but_1" style="border-color: #7732ff"
|
||||
v-if="orderInfo.status === ORDER_TYPE.NOT_RECEIVE" @click="onExpress(orderInfo.id)">
|
||||
<text class="text-zi">查看物流</text>
|
||||
</view>
|
||||
<view class="operate_comm operate_but_2" v-if="orderInfo.status === ORDER_TYPE.NOT_RECEIVE"
|
||||
@@ -285,6 +285,7 @@ import {
|
||||
import {
|
||||
appWxpayFun,
|
||||
zfbPayFun,
|
||||
douyinPayFun,
|
||||
jumpWayOk,
|
||||
jumpWayError,
|
||||
} from "@/utils/payUtils.js";
|
||||
@@ -358,6 +359,10 @@ export default {
|
||||
let params = {
|
||||
types: "1,2,3",
|
||||
};
|
||||
// #ifdef APP-PLUS
|
||||
params.types = "1,2,3,6"
|
||||
// #endif
|
||||
|
||||
const result = await getSupportPay(params);
|
||||
if (result && result.bizcode === 100) {
|
||||
const data = result.data || [];
|
||||
@@ -433,6 +438,9 @@ export default {
|
||||
item.alipay
|
||||
) {
|
||||
this.zfbPay(item.alipay, item.orderId, item.orderNum);
|
||||
} else if (item.douyin && Object.keys(item.douyin).length !== 0) {
|
||||
// 抖音支付
|
||||
this.appDouying(item.douyin, item.orderId, item.orderNum);
|
||||
} else {
|
||||
this.$refs.uToastRef.show({
|
||||
type: "error",
|
||||
@@ -446,6 +454,18 @@ export default {
|
||||
this.getOrderInfo();
|
||||
}
|
||||
},
|
||||
// app 抖音支付
|
||||
async appDouying(douyin, orderId, orderNum) {
|
||||
try {
|
||||
const result = await douyinPayFun(douyin, orderId, orderNum);
|
||||
console.log("抖音支付发起成功", result);
|
||||
// 处理支付发起成功后的逻辑
|
||||
} catch (error) {
|
||||
console.error("抖音支付失败", error);
|
||||
// 处理支付失败后的逻辑
|
||||
}
|
||||
},
|
||||
|
||||
// app 微信支付
|
||||
async appWxpay(alipay, orderId, orderNum) {
|
||||
try {
|
||||
@@ -457,6 +477,7 @@ export default {
|
||||
// 处理支付失败后的逻辑,如提示用户等
|
||||
}
|
||||
},
|
||||
|
||||
// 支付宝支付
|
||||
async zfbPay(alipay, orderId, orderNum) {
|
||||
try {
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
<up-image :src="`https://static.tbmall.xin/static/mine-purse/${item.categoty}.png`" width="22" height="22"
|
||||
bgColor="#f1f6ff00" class="purse_amount"></up-image>
|
||||
<view class="title">{{ item.name }}</view>
|
||||
<up-image v-if="item.categoty != 'balance'" src="/pages/rwa_package/static/tips.png" width="16" height="16"
|
||||
bgColor="#f1f6ff00" @click.stop="openTip(item.categoty)" />
|
||||
<up-image src="/static/common/right_soild.png" width="10" height="10" bgColor="#fff"
|
||||
class="right_soild"></up-image>
|
||||
</view>
|
||||
@@ -31,17 +33,20 @@
|
||||
</view>
|
||||
|
||||
<view class="bottom_item" v-if="item.categoty == 'vcoin'">
|
||||
<view class="bottom_item_amount">{{ item.bonusAmount || 0 }}</view>
|
||||
<view class="bottom_item_title">消费者权益</view>
|
||||
<view class="bottom_item_amount bottom_item_amount_center">{{ item.bonusAmount || 0 }}</view>
|
||||
<view class="bottom_item_title bottom_item_title_center">
|
||||
<text class="title_text">消费者权益</text>
|
||||
<up-image v-if="item.categoty != 'balance'" src="/pages/rwa_package/static/tips.png" width="12" height="12"
|
||||
bgColor="#f1f6ff00" class="tip_icon" @click.stop="openTip('rights')" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="bottom_item" @click.stop="onTip(vIndex)">
|
||||
<view class="bottom_item_lock">{{ item.lockAmount || 0 }}</view>
|
||||
<view class="bottom_item_title bottom_item_title_right">
|
||||
<text class="title_text">{{ item.categoty === "raffle" ? "不可用次数" : "不可用余额" }}</text>
|
||||
<view class="tips_icon_box" v-if="item.categoty == 'balance' || item.categoty == 'raffle'">
|
||||
<up-image src="/pages/rwa_package/static/tips.png" width="12" height="12" bgColor="#fff" />
|
||||
</view>
|
||||
<up-image v-if="item.categoty == 'balance' || item.categoty == 'raffle'"
|
||||
src="/pages/rwa_package/static/tips.png" width="12" height="12" bgColor="#fff" class="tip_icon" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -99,6 +104,17 @@
|
||||
</view>
|
||||
</view>
|
||||
</up-popup>
|
||||
<!-- 字段解释弹窗 -->
|
||||
<up-popup :show="tipShow" mode="center" :round="16" @close="tipShow = false">
|
||||
<view class="tip_popup_content">
|
||||
<view class="tip_popup_title">字段解释</view>
|
||||
<view class="tip_popup_body">
|
||||
<view class="tip_subtitle">{{ currentTip.subTitle }}</view>
|
||||
<view class="tip_detail">{{ currentTip.detail }}</view>
|
||||
</view>
|
||||
<view class="tip_popup_btn" @click="tipShow = false">我知道了</view>
|
||||
</view>
|
||||
</up-popup>
|
||||
<qiaobao-assistant page-key="pages/mine_package/mine_purse/mine_purse" title="钱包与账户" />
|
||||
</view>
|
||||
</template>
|
||||
@@ -111,6 +127,9 @@ import { getValue } from "@/utils/enumUtils.js";
|
||||
import { formatDate, handleAmount } from "@/utils/index.js";
|
||||
|
||||
export default {
|
||||
options: {
|
||||
styleIsolation: 'shared',
|
||||
},
|
||||
components: { headerComponent: Header },
|
||||
data() {
|
||||
return {
|
||||
@@ -120,6 +139,8 @@ export default {
|
||||
collectShow: false,
|
||||
collectSuccess: false,
|
||||
availableAmount: 0,
|
||||
tipShow: false,
|
||||
tipCategory: "",
|
||||
collectForm: {
|
||||
mobile: "",
|
||||
amount: "",
|
||||
@@ -128,10 +149,38 @@ export default {
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
currentTip() {
|
||||
const map = {
|
||||
expend: {
|
||||
subTitle: "贡献值:",
|
||||
detail: "购买商品确认签收后立即可获得贡献值。按毛利的1:1发放",
|
||||
},
|
||||
raffle: {
|
||||
subTitle: "抽奖次数:",
|
||||
detail: "购买商品可获得抽奖次数,抽奖次数可在抽奖活动中进行使用",
|
||||
},
|
||||
vcoin: {
|
||||
subTitle: "数字积分:",
|
||||
detail:
|
||||
"根据贡献值按照比例进行转换获得1. 商城贡献值10W内的贡献值1:1转换成数字积分2. 商城贡献值10W外的根据数字积分数量和总贡献值及贡献值占比进行获得。",
|
||||
},
|
||||
rights: {
|
||||
subTitle: "消费者权益:",
|
||||
detail: "根据数字积分进行转换,根据消费者权益可获得共享计划权益",
|
||||
},
|
||||
};
|
||||
return map[this.tipCategory] || { subTitle: "", detail: "" };
|
||||
},
|
||||
},
|
||||
onLoad() {
|
||||
this.getAcctBalance();
|
||||
},
|
||||
methods: {
|
||||
openTip(category) {
|
||||
this.tipCategory = category;
|
||||
this.tipShow = true;
|
||||
},
|
||||
getValue,
|
||||
formatDate,
|
||||
handleAmount,
|
||||
@@ -365,6 +414,10 @@ export default {
|
||||
font-weight: bold;
|
||||
font-size: 36rpx;
|
||||
color: #333333;
|
||||
|
||||
&.bottom_item_amount_center {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.bottom_item_lock {
|
||||
@@ -379,6 +432,7 @@ export default {
|
||||
font-size: 20rpx;
|
||||
color: #999999;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
white-space: nowrap;
|
||||
|
||||
@@ -386,23 +440,34 @@ export default {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.title_text {
|
||||
white-space: nowrap;
|
||||
&.bottom_item_title_center {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.tips_icon_box {
|
||||
margin-left: 8rpx;
|
||||
flex-shrink: 0;
|
||||
.title_text {
|
||||
white-space: nowrap;
|
||||
font-size: 20rpx;
|
||||
color: #999999;
|
||||
line-height: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
::v-deep(.bottom_item_tip_title) {
|
||||
.u-image__image {
|
||||
margin-top: 8rpx;
|
||||
margin-left: 8rpx;
|
||||
}
|
||||
::v-deep(.tip_icon),
|
||||
.tip_icon {
|
||||
margin-left: 8rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.u-image,
|
||||
.u-image__image,
|
||||
image {
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
justify-content: center !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -553,5 +618,52 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tip_popup_content {
|
||||
background: #ffffff;
|
||||
width: 600rpx;
|
||||
border-radius: 24rpx;
|
||||
padding: 44rpx 36rpx;
|
||||
box-sizing: border-box;
|
||||
|
||||
.tip_popup_title {
|
||||
font-weight: 600;
|
||||
font-size: 34rpx;
|
||||
color: #333333;
|
||||
text-align: center;
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.tip_popup_body {
|
||||
margin-bottom: 48rpx;
|
||||
|
||||
.tip_subtitle {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
font-weight: 500;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.tip_detail {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
line-height: 1.6;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
}
|
||||
|
||||
.tip_popup_btn {
|
||||
width: 100%;
|
||||
height: 84rpx;
|
||||
background: #707070;
|
||||
border-radius: 42rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 30rpx;
|
||||
color: #ffffff;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -218,6 +218,8 @@
|
||||
<image v-if="item.type == 'alipay'" src="https://static.tbmall.xin/static/new/zfb.png"></image>
|
||||
<image v-if="item.type == 'balance'" src="https://static.tbmall.xin/static/new/bank.png"></image>
|
||||
<image v-if="item.type == 'redpacket'" src="https://static.tbmall.xin/static/new/jf.png"></image>
|
||||
<image v-if="item.type == 'douyin'" src="https://static.tbmall.xin/static/new/jf.png"></image>
|
||||
|
||||
<text v-if="item.type == 'wechat' || item.type == 'alipay'" class="text-32 text-zu"
|
||||
style="margin-left: 20rpx">{{ item.name }}</text>
|
||||
<text v-else style="margin-left: 20rpx" class="text-32 text-zu">{{ item.name }}
|
||||
@@ -338,6 +340,7 @@ import { getUserInfo } from "@/api/auth.js";
|
||||
import {
|
||||
appWxpayFun,
|
||||
zfbPayFun,
|
||||
douyinPayFun,
|
||||
jumpWayOk,
|
||||
jumpWayError,
|
||||
} from "@/utils/payUtils.js";
|
||||
@@ -597,9 +600,9 @@ export default {
|
||||
}
|
||||
// #endif
|
||||
// #ifndef MP-WEIXIN
|
||||
parmas["types"] = "1,2,3";
|
||||
parmas["types"] = "1,2,3,6";
|
||||
if (this.isCoupon) {
|
||||
parmas["types"] = "1,2,3,5";
|
||||
parmas["types"] = "1,2,3,5,6";
|
||||
parmas.isDeduction = true;
|
||||
}
|
||||
// #endif
|
||||
@@ -1052,6 +1055,7 @@ export default {
|
||||
if (this.selectedCoupon) {
|
||||
params["couponUserId"] = this.getCouponUserId(this.selectedCoupon);
|
||||
}
|
||||
console.log("秦星星----2", params);
|
||||
resp = await settle(params);
|
||||
}
|
||||
|
||||
@@ -1073,6 +1077,10 @@ export default {
|
||||
item.alipay
|
||||
) {
|
||||
this.zfbPay(item.alipay, item.orderId, item.orderNum);
|
||||
} else if (item.douyin &&
|
||||
Object.keys(item.douyin).length !== 0 &&
|
||||
item.douyin) {
|
||||
this.appDouying(item.douyin, item.orderId, item.orderNum);
|
||||
} else {
|
||||
this.$refs.uToastRef.show({
|
||||
type: "error",
|
||||
@@ -1086,6 +1094,19 @@ export default {
|
||||
this.getOrder();
|
||||
}
|
||||
},
|
||||
|
||||
// app 抖音支付
|
||||
async appDouying(douyin, orderId, orderNum) {
|
||||
try {
|
||||
const result = await douyinPayFun(douyin, orderId, orderNum);
|
||||
console.log("抖音支付发起成功", result);
|
||||
// 处理支付发起成功后的逻辑
|
||||
} catch (error) {
|
||||
console.error("抖音支付失败", error);
|
||||
// 处理支付失败后的逻辑
|
||||
}
|
||||
},
|
||||
|
||||
// app 微信支付
|
||||
async appWxpay(alipay, orderId, orderNum) {
|
||||
try {
|
||||
|
||||
@@ -0,0 +1,597 @@
|
||||
<template>
|
||||
<view class="test_page">
|
||||
<!-- 顶部导航 -->
|
||||
<NavHeader leftTitle="抖音支付测试" leftPathType="navigateTo" />
|
||||
|
||||
<view class="test_container">
|
||||
<!-- 状态与设备信息卡片 -->
|
||||
<view class="card_box">
|
||||
<view class="card_title">
|
||||
<text class="title_text">📱 设备与环境信息</text>
|
||||
<view class="tag_badge" :class="isApp ? 'badge_app' : 'badge_h5'">
|
||||
{{ envText }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="info_grid">
|
||||
<view class="info_row">
|
||||
<text class="info_label">运行平台:</text>
|
||||
<text class="info_val">{{ platformText }}</text>
|
||||
</view>
|
||||
<view class="info_row">
|
||||
<text class="info_label">抖音安装状态:</text>
|
||||
<text class="info_val" :style="{ color: isDyInstalled ? '#00B578' : '#FA5151' }">
|
||||
{{ dyInstallStatusText }}
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="btn_row" style="margin-top: 20rpx;">
|
||||
<button class="mini_btn check_btn" @click="checkDouyinInstalled">
|
||||
🔍 检测是否安装抖音
|
||||
</button>
|
||||
<button class="mini_btn open_btn" @click="testDirectOpenDouyin">
|
||||
🚀 直接打开抖音客户端
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 支付测试参数配置 -->
|
||||
<view class="card_box">
|
||||
<view class="card_title">
|
||||
<text class="title_text">⚙️ 支付测试参数</text>
|
||||
</view>
|
||||
|
||||
<!-- 快捷预设模版 -->
|
||||
<view class="preset_section">
|
||||
<text class="section_label">快速填充测试数据:</text>
|
||||
<view class="preset_btn_group">
|
||||
<view class="preset_chip" @click="applyPreset('scheme')">普通App唤起 Scheme</view>
|
||||
<view class="preset_chip" @click="applyPreset('cashier')">模拟收银台 Scheme</view>
|
||||
<view class="preset_chip" @click="applyPreset('h5')">H5收银台链接</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="tip_box">
|
||||
<text class="tip_text">💡 提示:普通的 "snssdk1128://open" 仅能拉起抖音 App 首页。如需弹出【抖音收银台支付窗口】,orderStr 必须包含后端从字节/抖音开放平台获取的真实 pay_token 或收银台参数(如 snssdk1128://pay?pay_token=xxx 或 https://cashier.douyin.com/pay?token=xxx)。</text>
|
||||
</view>
|
||||
|
||||
<view class="form_item">
|
||||
<text class="form_label">支付类型 (type)</text>
|
||||
<radio-group class="radio_group" @change="onTypeChange">
|
||||
<label class="radio_item">
|
||||
<radio value="app" :checked="payType === 'app'" color="#7934F6" style="transform: scale(0.8);" />
|
||||
<text>app</text>
|
||||
</label>
|
||||
<label class="radio_item">
|
||||
<radio value="h5" :checked="payType === 'h5'" color="#7934F6" style="transform: scale(0.8);" />
|
||||
<text>h5</text>
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
|
||||
<view class="form_item">
|
||||
<text class="form_label">支付串 / Scheme / URL (orderStr)</text>
|
||||
<textarea
|
||||
class="form_textarea"
|
||||
v-model="orderStr"
|
||||
placeholder="请输入或粘贴抖音支付链接 / Scheme(如 snssdk1128://... 或 https://...)"
|
||||
></textarea>
|
||||
</view>
|
||||
|
||||
<view class="form_row">
|
||||
<view class="form_item half">
|
||||
<text class="form_label">订单ID (orderId)</text>
|
||||
<input class="form_input" type="number" v-model="orderId" placeholder="例如: 10001" />
|
||||
</view>
|
||||
<view class="form_item half">
|
||||
<text class="form_label">订单编号 (orderNum)</text>
|
||||
<input class="form_input" v-model="orderNum" placeholder="例如: ORD20260905001" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 支付操作区域 -->
|
||||
<view class="action_section">
|
||||
<button class="main_pay_btn" :loading="loading" @click="handleTestPay">
|
||||
⚡ 调用 douyinPayFun 测试支付
|
||||
</button>
|
||||
</view>
|
||||
|
||||
<!-- 运行日志与调试面板 -->
|
||||
<view class="card_box">
|
||||
<view class="card_title">
|
||||
<text class="title_text">📋 运行日志与回调</text>
|
||||
<text class="clear_link" @click="clearLogs">清空日志</text>
|
||||
</view>
|
||||
<scroll-view scroll-y="true" class="log_console">
|
||||
<view v-if="logs.length === 0" class="empty_log">暂无测试日志,点击上方按钮开始测试</view>
|
||||
<view v-for="(log, idx) in logs" :key="idx" class="log_item" :class="'log_' + log.level">
|
||||
<text class="log_time">[{{ log.time }}]</text>
|
||||
<text class="log_content">{{ log.msg }}</text>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import NavHeader from "@/components/header.vue";
|
||||
import { douyinPayFun, jumpWayOk, jumpWayError } from "@/utils/payUtils.js";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
NavHeader,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
payType: "app",
|
||||
orderStr: "snssdk1128://open", // 默认测试 scheme
|
||||
orderId: 99999,
|
||||
orderNum: "TEST_ORDER_" + Date.now(),
|
||||
loading: false,
|
||||
isApp: false,
|
||||
platformText: "未知",
|
||||
envText: "H5 / 网页",
|
||||
dyInstallStatusText: "待检测",
|
||||
isDyInstalled: false,
|
||||
logs: [],
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
this.initPlatformInfo();
|
||||
this.addLog("页面初始化完成", "info");
|
||||
},
|
||||
methods: {
|
||||
initPlatformInfo() {
|
||||
// #ifdef APP-PLUS
|
||||
this.isApp = true;
|
||||
this.envText = "App 端 (App-Plus)";
|
||||
const platform = uni.getSystemInfoSync().platform;
|
||||
this.platformText = platform === "ios" ? "iOS App" : "Android App";
|
||||
this.checkDouyinInstalled();
|
||||
// #endif
|
||||
|
||||
// #ifdef H5
|
||||
this.isApp = false;
|
||||
this.envText = "H5 浏览器";
|
||||
this.platformText = "Web / H5";
|
||||
this.dyInstallStatusText = "Web端不支持检测安装";
|
||||
// #endif
|
||||
},
|
||||
addLog(msg, level = "info") {
|
||||
const now = new Date();
|
||||
const timeStr = `${String(now.getHours()).padStart(2, "0")}:${String(now.getMinutes()).padStart(2, "0")}:${String(now.getSeconds()).padStart(2, "0")}`;
|
||||
const formattedMsg = typeof msg === "object" ? JSON.stringify(msg, null, 2) : String(msg);
|
||||
this.logs.unshift({
|
||||
time: timeStr,
|
||||
msg: formattedMsg,
|
||||
level: level,
|
||||
});
|
||||
},
|
||||
clearLogs() {
|
||||
this.logs = [];
|
||||
},
|
||||
onTypeChange(e) {
|
||||
this.payType = e.detail.value;
|
||||
this.addLog(`切换支付类型为: ${this.payType}`, "info");
|
||||
},
|
||||
applyPreset(presetType) {
|
||||
if (presetType === "scheme") {
|
||||
this.payType = "app";
|
||||
this.orderStr = "snssdk1128://open";
|
||||
this.addLog("已加载基础唤起 Scheme: snssdk1128://open (仅打开App首页)", "info");
|
||||
} else if (presetType === "cashier") {
|
||||
this.payType = "app";
|
||||
this.orderStr = "snssdk1128://pay?pay_token=DEMO_PAY_TOKEN_123456&order_id=TEST_ORDER_001";
|
||||
this.addLog("已加载模拟收银台 Scheme 结构 (真实支付需要后端接口返回的合法 pay_token)", "info");
|
||||
} else if (presetType === "h5") {
|
||||
this.payType = "h5";
|
||||
this.orderStr = "https://cashier.douyin.com/pay?token=DEMO_PAY_TOKEN_123456";
|
||||
this.addLog("已加载 H5 收银台链接预设", "info");
|
||||
}
|
||||
},
|
||||
// 检测抖音是否已安装 (iOS & Android)
|
||||
checkDouyinInstalled() {
|
||||
// #ifdef APP-PLUS
|
||||
const platform = uni.getSystemInfoSync().platform;
|
||||
let installed = false;
|
||||
let foundPkg = "";
|
||||
try {
|
||||
if (platform === "android") {
|
||||
const androidPkgs = [
|
||||
{ name: "抖音", pname: "com.ss.android.ugc.aweme" },
|
||||
{ name: "抖音极速版", pname: "com.ss.android.ugc.aweme.lite" },
|
||||
{ name: "抖音火山版", pname: "com.ss.android.ugc.live" },
|
||||
];
|
||||
for (const pkg of androidPkgs) {
|
||||
if (plus.runtime.isApplicationExist({ pname: pkg.pname })) {
|
||||
installed = true;
|
||||
foundPkg = pkg.name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (platform === "ios") {
|
||||
const iosSchemes = [
|
||||
{ name: "抖音", action: "snssdk1128://" },
|
||||
{ name: "抖音(douyin)", action: "douyin://" },
|
||||
{ name: "抖音极速版", action: "snssdk141://" },
|
||||
];
|
||||
for (const sch of iosSchemes) {
|
||||
if (plus.runtime.isApplicationExist({ action: sch.action })) {
|
||||
installed = true;
|
||||
foundPkg = sch.name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.isDyInstalled = installed;
|
||||
this.dyInstallStatusText = installed ? `已检测到 (${foundPkg}) ✅` : "未检测到 ❌";
|
||||
this.addLog(`检测抖音客户端安装状态: ${this.dyInstallStatusText}`, installed ? "success" : "warn");
|
||||
if (!installed && platform === "ios") {
|
||||
this.addLog("说明: iOS检测需要将 Scheme 加入 LSApplicationQueriesSchemes。若在【标准基座】中调试,因标准基座无此配置会返回未检测到,需使用【自定义基座】运行", "info");
|
||||
}
|
||||
} catch (e) {
|
||||
this.dyInstallStatusText = "检测异常";
|
||||
this.addLog(`检测安装状态发生异常: ${e.message}`, "error");
|
||||
}
|
||||
// #endif
|
||||
|
||||
// #ifndef APP-PLUS
|
||||
this.addLog("当前环境为非 App 环境,无法直接调用 5+ isApplicationExist", "warn");
|
||||
// #endif
|
||||
},
|
||||
// 直接测试打开抖音客户端
|
||||
testDirectOpenDouyin() {
|
||||
this.addLog(`尝试打开抖音: ${this.orderStr || 'snssdk1128://open'}`, "info");
|
||||
const targetUrl = this.orderStr || "snssdk1128://open";
|
||||
// #ifdef APP-PLUS
|
||||
let opened = false;
|
||||
if (plus.os.name === "iOS") {
|
||||
try {
|
||||
const UIApplication = plus.ios.importClass("UIApplication");
|
||||
const NSURL = plus.ios.importClass("NSURL");
|
||||
const app = UIApplication.sharedApplication();
|
||||
const nsUrl = NSURL.URLWithString(targetUrl);
|
||||
if (app && nsUrl) {
|
||||
if (app.openURL(nsUrl)) {
|
||||
opened = true;
|
||||
this.addLog("iOS 原生 Native.js 成功拉起客户端", "success");
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn(e);
|
||||
}
|
||||
} else if (plus.os.name === "Android") {
|
||||
try {
|
||||
const Intent = plus.android.importClass("android.content.Intent");
|
||||
const Uri = plus.android.importClass("android.net.Uri");
|
||||
const main = plus.android.runtimeMainActivity();
|
||||
const intent = new Intent(Intent.ACTION_VIEW, Uri.parse(targetUrl));
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
main.startActivity(intent);
|
||||
opened = true;
|
||||
this.addLog("Android 原生 Native.js Intent 成功拉起客户端", "success");
|
||||
} catch (e) {
|
||||
console.warn(e);
|
||||
}
|
||||
}
|
||||
if (!opened) {
|
||||
plus.runtime.openURL(
|
||||
targetUrl,
|
||||
(err) => {
|
||||
this.addLog(`打开抖音失败: ${JSON.stringify(err)}`, "error");
|
||||
const isSim = plus.navigator && plus.navigator.isSimulator ? plus.navigator.isSimulator() : false;
|
||||
if (isSim) {
|
||||
this.addLog("提示: iOS模拟器未安装抖音客户端,无法响应 snssdk1128:// Scheme,请使用安装了抖音的真机测试", "warn");
|
||||
} else if (err && err.code === -3) {
|
||||
this.addLog("提示: 错误 code -3 说明设备上未检测到抖音应用或Scheme未添加白名单,请确认真机上已安装抖音", "warn");
|
||||
}
|
||||
uni.showToast({
|
||||
title: isSim ? "模拟器不支持打开Scheme,请在真机测试" : "拉起失败,请确认是否已安装抖音",
|
||||
icon: "none",
|
||||
duration: 3000,
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
window.location.href = targetUrl;
|
||||
this.addLog("已在 H5 环境尝试跳转: " + targetUrl, "info");
|
||||
// #endif
|
||||
},
|
||||
// 调用 payUtils.js 中的 douyinPayFun
|
||||
async handleTestPay() {
|
||||
if (!this.orderStr) {
|
||||
uni.showToast({
|
||||
title: "请先输入支付串或链接",
|
||||
icon: "none",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const payParams = {
|
||||
type: this.payType,
|
||||
orderStr: this.orderStr,
|
||||
};
|
||||
|
||||
this.loading = true;
|
||||
this.addLog(`开始调用 douyinPayFun,入参: ${JSON.stringify(payParams)}`, "info");
|
||||
|
||||
try {
|
||||
const result = await douyinPayFun(payParams, this.orderId, this.orderNum);
|
||||
this.addLog(`douyinPayFun 调用完成返回: ${JSON.stringify(result)}`, "success");
|
||||
} catch (err) {
|
||||
this.addLog(`douyinPayFun 抛出错误: ${JSON.stringify(err)}`, "error");
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.test_page {
|
||||
min-height: 100vh;
|
||||
background-color: #F6F7FB;
|
||||
padding-bottom: 60rpx;
|
||||
}
|
||||
|
||||
.test_container {
|
||||
padding: 24rpx;
|
||||
}
|
||||
|
||||
.card_box {
|
||||
background: #FFFFFF;
|
||||
border-radius: 20rpx;
|
||||
padding: 28rpx;
|
||||
margin-bottom: 24rpx;
|
||||
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.04);
|
||||
|
||||
.card_title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 20rpx;
|
||||
|
||||
.title_text {
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
color: #1F2937;
|
||||
}
|
||||
|
||||
.tag_badge {
|
||||
font-size: 22rpx;
|
||||
padding: 4rpx 14rpx;
|
||||
border-radius: 20rpx;
|
||||
font-weight: 500;
|
||||
|
||||
&.badge_app {
|
||||
background-color: #EDE9FE;
|
||||
color: #7934F6;
|
||||
}
|
||||
|
||||
&.badge_h5 {
|
||||
background-color: #E0F2FE;
|
||||
color: #0284C7;
|
||||
}
|
||||
}
|
||||
|
||||
.clear_link {
|
||||
font-size: 24rpx;
|
||||
color: #7934F6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.info_grid {
|
||||
background: #F9FAFB;
|
||||
border-radius: 12rpx;
|
||||
padding: 16rpx 20rpx;
|
||||
|
||||
.info_row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 26rpx;
|
||||
margin-bottom: 8rpx;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.info_label {
|
||||
color: #6B7280;
|
||||
}
|
||||
|
||||
.info_val {
|
||||
font-weight: 500;
|
||||
color: #111827;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn_row {
|
||||
display: flex;
|
||||
gap: 16rpx;
|
||||
|
||||
.mini_btn {
|
||||
flex: 1;
|
||||
font-size: 24rpx;
|
||||
border-radius: 12rpx;
|
||||
line-height: 2.2;
|
||||
margin: 0;
|
||||
border: none;
|
||||
|
||||
&.check_btn {
|
||||
background: #F3F4F6;
|
||||
color: #374151;
|
||||
}
|
||||
|
||||
&.open_btn {
|
||||
background: #EDE9FE;
|
||||
color: #7934F6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.preset_section {
|
||||
margin-bottom: 20rpx;
|
||||
|
||||
.section_label {
|
||||
font-size: 24rpx;
|
||||
color: #6B7280;
|
||||
display: block;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.preset_btn_group {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 12rpx;
|
||||
|
||||
.preset_chip {
|
||||
font-size: 24rpx;
|
||||
color: #7934F6;
|
||||
background: #F4EFFF;
|
||||
border: 1rpx solid #E4D4FF;
|
||||
border-radius: 30rpx;
|
||||
padding: 8rpx 22rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tip_box {
|
||||
background: #FFFBEB;
|
||||
border: 1rpx solid #FDE68A;
|
||||
border-radius: 12rpx;
|
||||
padding: 16rpx 20rpx;
|
||||
margin-bottom: 24rpx;
|
||||
|
||||
.tip_text {
|
||||
font-size: 24rpx;
|
||||
color: #B45309;
|
||||
line-height: 1.5;
|
||||
}
|
||||
}
|
||||
|
||||
.form_item {
|
||||
margin-bottom: 20rpx;
|
||||
|
||||
.form_label {
|
||||
font-size: 26rpx;
|
||||
color: #374151;
|
||||
font-weight: 500;
|
||||
display: block;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.form_input {
|
||||
background: #F9FAFB;
|
||||
border: 1rpx solid #E5E7EB;
|
||||
border-radius: 12rpx;
|
||||
height: 72rpx;
|
||||
padding: 0 20rpx;
|
||||
font-size: 26rpx;
|
||||
color: #111827;
|
||||
}
|
||||
|
||||
.form_textarea {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
background: #F9FAFB;
|
||||
border: 1rpx solid #E5E7EB;
|
||||
border-radius: 12rpx;
|
||||
padding: 16rpx 20rpx;
|
||||
font-size: 26rpx;
|
||||
color: #111827;
|
||||
height: 140rpx;
|
||||
}
|
||||
|
||||
.radio_group {
|
||||
display: flex;
|
||||
gap: 30rpx;
|
||||
|
||||
.radio_item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 26rpx;
|
||||
color: #374151;
|
||||
}
|
||||
}
|
||||
|
||||
&.half {
|
||||
flex: 1;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.form_row {
|
||||
display: flex;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.action_section {
|
||||
margin-bottom: 24rpx;
|
||||
|
||||
.main_pay_btn {
|
||||
background: linear-gradient(135deg, #8B5CF6 0%, #7934F6 100%);
|
||||
color: #FFFFFF;
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
height: 88rpx;
|
||||
line-height: 88rpx;
|
||||
border-radius: 44rpx;
|
||||
box-shadow: 0 8rpx 20rpx rgba(121, 52, 246, 0.3);
|
||||
border: none;
|
||||
|
||||
&:active {
|
||||
opacity: 0.9;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.log_console {
|
||||
background: #1E1E2E;
|
||||
border-radius: 16rpx;
|
||||
padding: 20rpx;
|
||||
height: 380rpx;
|
||||
box-sizing: border-box;
|
||||
|
||||
.empty_log {
|
||||
color: #6C7086;
|
||||
font-size: 24rpx;
|
||||
text-align: center;
|
||||
padding: 60rpx 0;
|
||||
}
|
||||
|
||||
.log_item {
|
||||
font-size: 24rpx;
|
||||
font-family: monospace;
|
||||
line-height: 1.6;
|
||||
margin-bottom: 10rpx;
|
||||
word-break: break-all;
|
||||
|
||||
.log_time {
|
||||
color: #A6ADC8;
|
||||
margin-right: 12rpx;
|
||||
}
|
||||
|
||||
&.log_info .log_content {
|
||||
color: #CDD6F4;
|
||||
}
|
||||
|
||||
&.log_success .log_content {
|
||||
color: #A6E3A1;
|
||||
}
|
||||
|
||||
&.log_warn .log_content {
|
||||
color: #F9E2AF;
|
||||
}
|
||||
|
||||
&.log_error .log_content {
|
||||
color: #F38BA8;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,354 +1,633 @@
|
||||
<template>
|
||||
<view class="invite_friends_warp">
|
||||
<view class="invite_img">
|
||||
<image :src="inviteImage" class="invite_imgage" v-if="inviteImage"></image>
|
||||
<view class="loading" v-else>
|
||||
<text>加载分享图片中...</text>
|
||||
<!-- 1. 顶部导航 (固定) -->
|
||||
<Header leftTitle="邀请好友" />
|
||||
|
||||
<!-- 2. 头部 Banner 区域 (固定) -->
|
||||
<view class="banner_header">
|
||||
<view class="banner_left">
|
||||
<view class="title_row">
|
||||
<text class="title_black">旧朋带新伴</text>
|
||||
</view>
|
||||
<view class="title_row">
|
||||
<text class="title_black">邀约</text>
|
||||
<text class="title_purple">享福利</text>
|
||||
</view>
|
||||
<view class="sub_title">
|
||||
<text>累计邀请达标,可解锁更多券礼</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="banner_right">
|
||||
<up-image src="https://static.tbmall.xin/static/mine/invite_friends_img.png" width="130" height="115"
|
||||
bgColor="#f1f6ff00"></up-image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="invite_but">
|
||||
<button
|
||||
class="share-btn"
|
||||
@click="openSharePopup"
|
||||
>
|
||||
分享好友
|
||||
</button>
|
||||
</view>
|
||||
|
||||
<!-- 分享弹窗 -->
|
||||
<SharePopup
|
||||
ref="share"
|
||||
v-if="shareOpen"
|
||||
:show="shareShow"
|
||||
@close="onClose"
|
||||
@wxShare="onWxShare"
|
||||
@share="onShare"
|
||||
:id="posterId"
|
||||
text="我的推广海报"
|
||||
:tu="inviteImage || shareImg"
|
||||
></SharePopup>
|
||||
<!-- 3. 卡片容器 (填充中间区域,内部固定标题) -->
|
||||
<view class="card_container">
|
||||
<view class="card_title">我的邀请</view>
|
||||
|
||||
<up-toast ref="uToastRef"></up-toast>
|
||||
<qiaobao-assistant page-key="pages/other_package/invite_friends/invite_friends" title="我的推广" />
|
||||
<!-- 无数据状态 (图一) -->
|
||||
<view class="empty_box" v-if="!loading && list.length === 0">
|
||||
<up-image src="https://static.tbmall.xin/static/mine/invite_friends_empty.png" width="120" height="120"
|
||||
bgColor="#f1f6ff00"></up-image>
|
||||
<text class="empty_text">暂无邀请好友</text>
|
||||
</view>
|
||||
|
||||
<!-- 有数据状态 (图二) -->
|
||||
<view class="table_box" v-else-if="list.length > 0">
|
||||
<!-- 固定表头 (用户ID | 手机号 | 注册时间) -->
|
||||
<view class="table_header">
|
||||
<view class="th th_border">用户ID</view>
|
||||
<view class="th th_border">手机号</view>
|
||||
<view class="th">注册时间</view>
|
||||
</view>
|
||||
|
||||
<!-- 仅在此 scroll-view 区域内(表格数据行)可滚动 -->
|
||||
<scroll-view scroll-y class="table_body_scroll" style="height: 100%;" @scrolltolower="onReachBottom"
|
||||
refresher-enabled :refresher-triggered="refreshing" @refresherrefresh="onRefresh">
|
||||
<view class="table_body">
|
||||
<view class="table_row" v-for="(item, index) in list" :key="index">
|
||||
<view class="td td_border">{{ item.userId || '-' }}</view>
|
||||
<view class="td td_border">{{ item.mobile || '-' }}</view>
|
||||
<view class="td">{{ item.registTime || '-' }}</view>
|
||||
</view>
|
||||
|
||||
<!-- 加载完成提示 -->
|
||||
<view class="load_more_tip" v-if="finished && list.length > 0">
|
||||
<text class="no_more">已加载全部</text>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
|
||||
<!-- 初次加载动画 -->
|
||||
<view class="loading_box" v-if="loading && list.length === 0">
|
||||
<up-loading-icon show color="#7934F6"></up-loading-icon>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 4. 底部固定分享按钮 -->
|
||||
<view class="bottom_action">
|
||||
<button class="share_btn" @click="openSharePopup">
|
||||
分享好友
|
||||
</button>
|
||||
</view>
|
||||
|
||||
<!-- 分享弹窗组件 -->
|
||||
<view v-if="shareOpen">
|
||||
<SharePopup ref="share" :show="shareShow" @close="onClose" @wxShare="onWxShare" @share="onShare"
|
||||
:id="posterId" text="我的推广海报" :tu="inviteImage || shareImg"></SharePopup>
|
||||
</view>
|
||||
|
||||
<up-toast ref="uToastRef"></up-toast>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getSharePoster, generateSharePoster } from "@/api/common.js";
|
||||
import SharePopup from "@/pages/other_package/components/share-popup.vue";
|
||||
|
||||
export default {
|
||||
|
||||
<script>
|
||||
import Header from "@/components/header.vue";
|
||||
import { getSharePoster, generateSharePoster } from "@/api/common.js";
|
||||
import { getDirectReferrals } from "@/api/auth.js";
|
||||
import SharePopup from "@/pages/other_package/components/share-popup.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
SharePopup
|
||||
Header,
|
||||
SharePopup
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
inviteImage: null,
|
||||
imageLoading: false,
|
||||
shareImg: '',
|
||||
shareShow: false,
|
||||
shareOpen: true,
|
||||
posterId: ''
|
||||
};
|
||||
return {
|
||||
inviteImage: null,
|
||||
imageLoading: false,
|
||||
shareImg: '',
|
||||
shareShow: false,
|
||||
shareOpen: true,
|
||||
posterId: '',
|
||||
// 邀请列表相关数据
|
||||
list: [],
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
totalPage: 1,
|
||||
loading: false,
|
||||
refreshing: false,
|
||||
finished: false
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.getSharePoster();
|
||||
this.getSharePoster();
|
||||
this.getReferralList(true);
|
||||
},
|
||||
onShareAppMessage() {
|
||||
return {
|
||||
title: "邀请您体验信任桥TB商城",
|
||||
path: "/pages/home/home",
|
||||
imageUrl: this.inviteImage || this.shareImg,
|
||||
};
|
||||
return {
|
||||
title: "邀请您体验信任桥TB商城",
|
||||
path: "/pages/home/home",
|
||||
imageUrl: this.inviteImage || this.shareImg,
|
||||
};
|
||||
},
|
||||
onShareTimeline() {
|
||||
return {
|
||||
title: "邀请您体验信任桥TB商城",
|
||||
query: "",
|
||||
imageUrl: this.inviteImage || this.shareImg,
|
||||
};
|
||||
return {
|
||||
title: "邀请您体验信任桥TB商城",
|
||||
query: "",
|
||||
imageUrl: this.inviteImage || this.shareImg,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 打开分享弹窗 / 微信小程序下直接触发朋友圈(图片分享菜单)效果
|
||||
openSharePopup() {
|
||||
if (!this.inviteImage && !this.shareImg) {
|
||||
this.$refs.uToastRef.show({
|
||||
type: 'warning',
|
||||
message: "分享图正在加载,请稍后重试",
|
||||
});
|
||||
return;
|
||||
}
|
||||
// #ifdef MP-WEIXIN
|
||||
this.onWxShare(1);
|
||||
return;
|
||||
// #endif
|
||||
|
||||
this.shareShow = true;
|
||||
},
|
||||
|
||||
// 关闭分享弹窗
|
||||
onClose() {
|
||||
this.shareShow = false;
|
||||
},
|
||||
|
||||
// 微信小程序环境分享
|
||||
onWxShare(index) {
|
||||
console.log('小程序分享', index);
|
||||
if (index === 0) {
|
||||
// 微信好友: 已通过 button open-type="share" 触发,关闭弹窗即可
|
||||
this.onClose();
|
||||
} else if (index === 1) {
|
||||
// 朋友圈: 唤起小程序原生分享菜单或系统提示
|
||||
// #ifdef MP-WEIXIN
|
||||
if (typeof wx !== 'undefined' && wx.showShareImageMenu && this.shareImg) {
|
||||
wx.showShareImageMenu({
|
||||
path: this.shareImg,
|
||||
fail: () => {
|
||||
uni.showShareMenu({
|
||||
withShareTicket: true,
|
||||
menus: ["shareTimeline"]
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
uni.showShareMenu({
|
||||
withShareTicket: true,
|
||||
menus: ["shareTimeline"]
|
||||
});
|
||||
}
|
||||
// #endif
|
||||
this.onClose();
|
||||
}
|
||||
},
|
||||
|
||||
// App 及 H5 环境分享
|
||||
onShare(index) {
|
||||
console.log('App/H5分享', index);
|
||||
if (index === 0) {
|
||||
// 微信好友
|
||||
// #ifdef APP-PLUS
|
||||
uni.share({
|
||||
provider: 'weixin',
|
||||
scene: 'WXSceneSession',
|
||||
type: 2,
|
||||
imageUrl: this.shareImg || this.inviteImage,
|
||||
success: () => {
|
||||
this.$refs.uToastRef.show({ type: 'success', message: '分享成功' });
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('App分享好友失败:', err);
|
||||
this.savePosterToAlbum();
|
||||
// 获取邀请好友列表
|
||||
async getReferralList(isRefresh = false) {
|
||||
if (this.loading) return;
|
||||
if (isRefresh) {
|
||||
this.page = 1;
|
||||
this.finished = false;
|
||||
}
|
||||
});
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
uni.previewImage({ urls: [this.shareImg || this.inviteImage] });
|
||||
this.$refs.uToastRef.show({ type: 'info', message: '请长按图片发送给好友' });
|
||||
// #endif
|
||||
this.onClose();
|
||||
} else if (index === 1) {
|
||||
// 微信朋友圈
|
||||
// #ifdef APP-PLUS
|
||||
uni.share({
|
||||
provider: 'weixin',
|
||||
scene: 'WXSceneTimeline',
|
||||
type: 2,
|
||||
imageUrl: this.shareImg || this.inviteImage,
|
||||
success: () => {
|
||||
this.$refs.uToastRef.show({ type: 'success', message: '分享成功' });
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('App分享朋友圈失败:', err);
|
||||
this.savePosterToAlbum();
|
||||
}
|
||||
});
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
uni.previewImage({ urls: [this.shareImg || this.inviteImage] });
|
||||
this.$refs.uToastRef.show({ type: 'info', message: '请长按图片分享到朋友圈' });
|
||||
// #endif
|
||||
this.onClose();
|
||||
} else if (index === 2) {
|
||||
// 复制链接
|
||||
uni.setClipboardData({
|
||||
data: 'https://m.tbmall.xin/#/pages/home/home',
|
||||
success: () => {
|
||||
this.$refs.uToastRef.show({ type: 'success', message: '链接已复制到剪贴板' });
|
||||
}
|
||||
});
|
||||
this.onClose();
|
||||
} else if (index === 3) {
|
||||
// 保存图片
|
||||
this.savePosterToAlbum();
|
||||
this.onClose();
|
||||
} else if (index === 4) {
|
||||
// QQ
|
||||
this.$refs.uToastRef.show({ type: 'warning', message: '暂未开放' });
|
||||
this.onClose();
|
||||
}
|
||||
},
|
||||
|
||||
// 保存海报至相册
|
||||
savePosterToAlbum() {
|
||||
const imgPath = this.shareImg || this.inviteImage;
|
||||
if (!imgPath) {
|
||||
this.$refs.uToastRef.show({ type: 'warning', message: '海报图片生成中,请稍后重试' });
|
||||
return;
|
||||
}
|
||||
|
||||
// #ifdef APP-PLUS || MP-WEIXIN
|
||||
uni.saveImageToPhotosAlbum({
|
||||
filePath: imgPath,
|
||||
success: () => {
|
||||
this.$refs.uToastRef.show({ type: 'success', message: '海报已保存至手机相册' });
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('保存至相册失败:', err);
|
||||
if (err && err.errMsg && err.errMsg.includes('auth')) {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '需要保存图片到相册权限,请在设置中开启相册权限',
|
||||
success: (res) => {
|
||||
if (res.confirm) uni.openSetting();
|
||||
this.loading = true;
|
||||
try {
|
||||
const params = {
|
||||
page: this.page,
|
||||
pageSize: this.pageSize
|
||||
};
|
||||
const resp = await getDirectReferrals(params);
|
||||
if (resp && (resp.bizcode === 100 || resp.bizcode === 0)) {
|
||||
const data = resp.data || {};
|
||||
const newEntities = data.entitys || data.entities || [];
|
||||
if (isRefresh) {
|
||||
this.list = newEntities;
|
||||
} else {
|
||||
this.list = [...this.list, ...newEntities];
|
||||
}
|
||||
this.totalPage = data.totalPage || 1;
|
||||
if (this.page >= this.totalPage || newEntities.length < this.pageSize) {
|
||||
this.finished = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
uni.previewImage({ urls: [imgPath] });
|
||||
} catch (error) {
|
||||
console.error("获取邀请列表失败:", error);
|
||||
} finally {
|
||||
this.loading = false;
|
||||
this.refreshing = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
// #endif
|
||||
},
|
||||
|
||||
// #ifdef H5
|
||||
uni.previewImage({ urls: [imgPath] });
|
||||
this.$refs.uToastRef.show({ type: 'info', message: '请长按图片保存到手机相册' });
|
||||
// #endif
|
||||
},
|
||||
// 下拉刷新
|
||||
async onRefresh() {
|
||||
this.refreshing = true;
|
||||
await this.getReferralList(true);
|
||||
},
|
||||
|
||||
// 将base64转换为本地临时文件
|
||||
base64ToTempFile(base64Data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!base64Data) {
|
||||
return reject(new Error('Base64数据为空'));
|
||||
}
|
||||
// 触底加载更多
|
||||
onReachBottom() {
|
||||
if (!this.finished && !this.loading) {
|
||||
this.page++;
|
||||
this.getReferralList(false);
|
||||
}
|
||||
},
|
||||
|
||||
// #ifdef APP-PLUS
|
||||
try {
|
||||
const bitmap = new plus.nativeObj.Bitmap('poster_' + Date.now());
|
||||
bitmap.loadBase64Data(
|
||||
base64Data,
|
||||
() => {
|
||||
const tempPath = `_doc/share_${Date.now()}.png`;
|
||||
bitmap.save(
|
||||
tempPath,
|
||||
{ overwrite: true, format: 'png', quality: 100 },
|
||||
(e) => {
|
||||
bitmap.clear();
|
||||
resolve(e.target);
|
||||
},
|
||||
(err) => {
|
||||
bitmap.clear();
|
||||
// 打开分享弹窗 / 微信小程序下直接触发朋友圈/分享
|
||||
openSharePopup() {
|
||||
if (!this.inviteImage && !this.shareImg) {
|
||||
this.$refs.uToastRef.show({
|
||||
type: 'warning',
|
||||
message: "分享图正在加载,请稍后重试",
|
||||
});
|
||||
return;
|
||||
}
|
||||
// #ifdef MP-WEIXIN
|
||||
this.onWxShare(1);
|
||||
return;
|
||||
// #endif
|
||||
|
||||
this.shareShow = true;
|
||||
},
|
||||
|
||||
// 关闭分享弹窗
|
||||
onClose() {
|
||||
this.shareShow = false;
|
||||
},
|
||||
|
||||
// 微信小程序环境分享
|
||||
onWxShare(index) {
|
||||
console.log('小程序分享', index);
|
||||
if (index === 0) {
|
||||
this.onClose();
|
||||
} else if (index === 1) {
|
||||
// #ifdef MP-WEIXIN
|
||||
if (typeof wx !== 'undefined' && wx.showShareImageMenu && this.shareImg) {
|
||||
wx.showShareImageMenu({
|
||||
path: this.shareImg,
|
||||
fail: () => {
|
||||
uni.showShareMenu({
|
||||
withShareTicket: true,
|
||||
menus: ["shareTimeline"]
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
uni.showShareMenu({
|
||||
withShareTicket: true,
|
||||
menus: ["shareTimeline"]
|
||||
});
|
||||
}
|
||||
// #endif
|
||||
this.onClose();
|
||||
}
|
||||
},
|
||||
|
||||
// App 及 H5 环境分享
|
||||
onShare(index) {
|
||||
console.log('App/H5分享', index);
|
||||
if (index === 0) {
|
||||
// 微信好友
|
||||
// #ifdef APP-PLUS
|
||||
uni.share({
|
||||
provider: 'weixin',
|
||||
scene: 'WXSceneSession',
|
||||
type: 2,
|
||||
imageUrl: this.shareImg || this.inviteImage,
|
||||
success: () => {
|
||||
this.$refs.uToastRef.show({ type: 'success', message: '分享成功' });
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('App分享好友失败:', err);
|
||||
this.savePosterToAlbum();
|
||||
}
|
||||
});
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
uni.previewImage({ urls: [this.shareImg || this.inviteImage] });
|
||||
this.$refs.uToastRef.show({ type: 'info', message: '请长按图片发送给好友' });
|
||||
// #endif
|
||||
this.onClose();
|
||||
} else if (index === 1) {
|
||||
// 微信朋友圈
|
||||
// #ifdef APP-PLUS
|
||||
uni.share({
|
||||
provider: 'weixin',
|
||||
scene: 'WXSceneTimeline',
|
||||
type: 2,
|
||||
imageUrl: this.shareImg || this.inviteImage,
|
||||
success: () => {
|
||||
this.$refs.uToastRef.show({ type: 'success', message: '分享成功' });
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('App分享朋友圈失败:', err);
|
||||
this.savePosterToAlbum();
|
||||
}
|
||||
});
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
uni.previewImage({ urls: [this.shareImg || this.inviteImage] });
|
||||
this.$refs.uToastRef.show({ type: 'info', message: '请长按图片分享到朋友圈' });
|
||||
// #endif
|
||||
this.onClose();
|
||||
} else if (index === 2) {
|
||||
// 复制链接
|
||||
uni.setClipboardData({
|
||||
data: 'https://m.tbmall.xin/#/pages/home/home',
|
||||
success: () => {
|
||||
this.$refs.uToastRef.show({ type: 'success', message: '链接已复制到剪贴板' });
|
||||
}
|
||||
});
|
||||
this.onClose();
|
||||
} else if (index === 3) {
|
||||
// 保存图片
|
||||
this.savePosterToAlbum();
|
||||
this.onClose();
|
||||
} else if (index === 4) {
|
||||
// QQ
|
||||
this.$refs.uToastRef.show({ type: 'warning', message: '暂未开放' });
|
||||
this.onClose();
|
||||
}
|
||||
},
|
||||
|
||||
// 保存海报至相册
|
||||
savePosterToAlbum() {
|
||||
const imgPath = this.shareImg || this.inviteImage;
|
||||
if (!imgPath) {
|
||||
this.$refs.uToastRef.show({ type: 'warning', message: '海报图片生成中,请稍后重试' });
|
||||
return;
|
||||
}
|
||||
|
||||
// #ifdef APP-PLUS || MP-WEIXIN
|
||||
uni.saveImageToPhotosAlbum({
|
||||
filePath: imgPath,
|
||||
success: () => {
|
||||
this.$refs.uToastRef.show({ type: 'success', message: '海报已保存至手机相册' });
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('保存至相册失败:', err);
|
||||
if (err && err.errMsg && err.errMsg.includes('auth')) {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '需要保存图片到相册权限,请在设置中开启相册权限',
|
||||
success: (res) => {
|
||||
if (res.confirm) uni.openSetting();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
uni.previewImage({ urls: [imgPath] });
|
||||
}
|
||||
}
|
||||
});
|
||||
// #endif
|
||||
|
||||
// #ifdef H5
|
||||
uni.previewImage({ urls: [imgPath] });
|
||||
this.$refs.uToastRef.show({ type: 'info', message: '请长按图片保存到手机相册' });
|
||||
// #endif
|
||||
},
|
||||
|
||||
// 将base64转换为本地临时文件
|
||||
base64ToTempFile(base64Data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!base64Data) {
|
||||
return reject(new Error('Base64数据为空'));
|
||||
}
|
||||
|
||||
// #ifdef APP-PLUS
|
||||
try {
|
||||
const bitmap = new plus.nativeObj.Bitmap('poster_' + Date.now());
|
||||
bitmap.loadBase64Data(
|
||||
base64Data,
|
||||
() => {
|
||||
const tempPath = `_doc/share_${Date.now()}.png`;
|
||||
bitmap.save(
|
||||
tempPath,
|
||||
{ overwrite: true, format: 'png', quality: 100 },
|
||||
(e) => {
|
||||
bitmap.clear();
|
||||
resolve(e.target);
|
||||
},
|
||||
(err) => {
|
||||
bitmap.clear();
|
||||
reject(err);
|
||||
}
|
||||
);
|
||||
},
|
||||
(err) => {
|
||||
bitmap.clear();
|
||||
reject(err);
|
||||
}
|
||||
);
|
||||
} catch (err) {
|
||||
reject(err);
|
||||
}
|
||||
);
|
||||
},
|
||||
(err) => {
|
||||
bitmap.clear();
|
||||
reject(err);
|
||||
}
|
||||
);
|
||||
} catch (err) {
|
||||
reject(err);
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
// #endif
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
try {
|
||||
const base64 = base64Data.replace(/^data:image\/\w+;base64,/, '');
|
||||
const arrayBuffer = uni.base64ToArrayBuffer(base64);
|
||||
const fs = typeof wx !== 'undefined' && wx.getFileSystemManager ? wx.getFileSystemManager() : uni.getFileSystemManager();
|
||||
const tempFilePath = `${wx.env.USER_DATA_PATH}/share_${Date.now()}.png`;
|
||||
fs.writeFileSync(tempFilePath, arrayBuffer, 'binary');
|
||||
resolve(tempFilePath);
|
||||
} catch (err) {
|
||||
reject(err);
|
||||
}
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN
|
||||
try {
|
||||
const base64 = base64Data.replace(/^data:image\/\w+;base64,/, '');
|
||||
const arrayBuffer = uni.base64ToArrayBuffer(base64);
|
||||
const fs = typeof wx !== 'undefined' && wx.getFileSystemManager ? wx.getFileSystemManager() : uni.getFileSystemManager();
|
||||
const tempFilePath = `${wx.env.USER_DATA_PATH}/share_${Date.now()}.png`;
|
||||
fs.writeFileSync(tempFilePath, arrayBuffer, 'binary');
|
||||
resolve(tempFilePath);
|
||||
} catch (err) {
|
||||
reject(err);
|
||||
}
|
||||
// #endif
|
||||
|
||||
// #ifdef H5
|
||||
resolve(base64Data);
|
||||
// #endif
|
||||
});
|
||||
},
|
||||
// #ifdef H5
|
||||
resolve(base64Data);
|
||||
// #endif
|
||||
});
|
||||
},
|
||||
|
||||
// 查询分享模版
|
||||
async getSharePoster() {
|
||||
this.imageLoading = true;
|
||||
try {
|
||||
const resp = await getSharePoster();
|
||||
if (resp && resp.bizcode === 100) {
|
||||
const data = resp.data[0];
|
||||
if (data) this.posterId = data.id || '';
|
||||
// 生成分享图
|
||||
const generateResp = await generateSharePoster({ id: data.id });
|
||||
if (generateResp && generateResp.bizcode === 100) {
|
||||
this.inviteImage = generateResp.data;
|
||||
// 将base64转换为本地临时文件并存储到shareImg
|
||||
this.shareImg = await this.base64ToTempFile(generateResp.data);
|
||||
console.log('图片转换成功:', this.shareImg);
|
||||
// 查询分享模版
|
||||
async getSharePoster() {
|
||||
this.imageLoading = true;
|
||||
try {
|
||||
const resp = await getSharePoster();
|
||||
if (resp && resp.bizcode === 100) {
|
||||
const data = resp.data[0];
|
||||
if (data) this.posterId = data.id || '';
|
||||
const generateResp = await generateSharePoster({ id: data.id });
|
||||
if (generateResp && generateResp.bizcode === 100) {
|
||||
this.inviteImage = generateResp.data;
|
||||
this.shareImg = await this.base64ToTempFile(generateResp.data);
|
||||
console.log('图片转换成功:', this.shareImg);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("获取分享图失败:", error);
|
||||
} finally {
|
||||
this.imageLoading = false;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("获取分享图失败:", error);
|
||||
} finally {
|
||||
this.imageLoading = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.invite_friends_warp {
|
||||
height: calc(100vh - 80rpx);
|
||||
padding: 10rpx 40rpx 40rpx;
|
||||
}
|
||||
|
||||
.invite_img {
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.invite_friends_warp {
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: linear-gradient(180deg, #F3ECFF 0%, #F6F3FE 300rpx, #F5F2FC 600rpx, #F5F2FC 100%);
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 头部 Banner 区域 (固定不滑动) */
|
||||
.banner_header {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
padding: 20rpx 20rpx 10rpx 40rpx;
|
||||
position: relative;
|
||||
|
||||
.banner_left {
|
||||
flex: 1;
|
||||
padding-top: 16rpx;
|
||||
|
||||
.title_row {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
font-size: 40rpx;
|
||||
font-weight: 800;
|
||||
line-height: 1.25;
|
||||
color: #1D1D1F;
|
||||
|
||||
.title_black {
|
||||
color: #1D1D1F;
|
||||
}
|
||||
|
||||
.title_purple {
|
||||
color: #8C48FF;
|
||||
margin-left: 6rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.sub_title {
|
||||
font-size: 22rpx;
|
||||
color: #949497;
|
||||
margin-top: 16rpx;
|
||||
letter-spacing: 0.5rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.banner_right {
|
||||
width: 260rpx;
|
||||
height: 230rpx;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: flex-start;
|
||||
}
|
||||
}
|
||||
|
||||
/* 白框卡片:填充中间区域 */
|
||||
.card_container {
|
||||
flex: 1;
|
||||
height: 0;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: #FFFFFF;
|
||||
border-radius: 24rpx;
|
||||
margin: 0 24rpx 20rpx;
|
||||
padding: 32rpx 24rpx;
|
||||
box-shadow: 0 4rpx 20rpx rgba(121, 52, 246, 0.03);
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
|
||||
.card_title {
|
||||
flex-shrink: 0;
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #1D1D1F;
|
||||
margin-bottom: 28rpx;
|
||||
}
|
||||
}
|
||||
|
||||
/* 无数据空状态 */
|
||||
.empty_box {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.empty_text {
|
||||
font-size: 26rpx;
|
||||
color: #8A8A8E;
|
||||
margin-top: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
/* 初次加载动画居中 */
|
||||
.loading_box {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 920rpx;
|
||||
}
|
||||
|
||||
.invite_imgage {
|
||||
width: 100%;
|
||||
height: 920rpx;
|
||||
}
|
||||
|
||||
.loading {
|
||||
text-align: center;
|
||||
color: #999;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.invite_but {
|
||||
padding: 20rpx 50rpx;
|
||||
margin-top: 52rpx;
|
||||
}
|
||||
|
||||
.share-btn {
|
||||
width: 100%;
|
||||
background: $app-bt-bj;
|
||||
border-radius: 45rpx;
|
||||
color: #FFFFFF;
|
||||
font-weight: 500;
|
||||
font-size: 32rpx;
|
||||
// 清除默认按钮样式
|
||||
border: none;
|
||||
outline: none;
|
||||
&:active {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
/* 有数据表格状态 */
|
||||
.table_box {
|
||||
flex: 1;
|
||||
height: 0;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border: 1rpx solid #F0EBF8;
|
||||
border-radius: 16rpx;
|
||||
overflow: hidden;
|
||||
|
||||
/* 固定表头 */
|
||||
.table_header {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
background-color: #FAF7FF;
|
||||
border-bottom: 1rpx solid #F0EBF8;
|
||||
|
||||
.th {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
padding: 22rpx 8rpx;
|
||||
font-size: 26rpx;
|
||||
font-weight: 500;
|
||||
color: #666666;
|
||||
|
||||
&.th_border {
|
||||
border-right: 1rpx solid #F0EBF8;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
/* 仅此处表格列表可垂直滑动,支持 App / 微信小程序 / H5 三端兼容 */
|
||||
.table_body_scroll {
|
||||
flex: 1;
|
||||
height: 0;
|
||||
min-height: 0;
|
||||
box-sizing: border-box;
|
||||
|
||||
/* #ifdef H5 || APP-PLUS */
|
||||
::v-deep uni-scroll-view,
|
||||
::v-deep .uni-scroll-view {
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
/* #endif */
|
||||
|
||||
.table_body {
|
||||
.table_row {
|
||||
display: flex;
|
||||
border-bottom: 1rpx solid #F0EBF8;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.td {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
padding: 24rpx 8rpx;
|
||||
font-size: 26rpx;
|
||||
color: #333333;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
word-break: break-all;
|
||||
|
||||
&.td_border {
|
||||
border-right: 1rpx solid #F0EBF8;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.load_more_tip {
|
||||
text-align: center;
|
||||
padding: 24rpx 0;
|
||||
font-size: 22rpx;
|
||||
color: #B0B0B0;
|
||||
}
|
||||
|
||||
/* 底部固定分享按钮 */
|
||||
.bottom_action {
|
||||
flex-shrink: 0;
|
||||
background: #FFFFFF;
|
||||
padding: 20rpx 32rpx calc(24rpx + env(safe-area-inset-bottom));
|
||||
box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.04);
|
||||
box-sizing: border-box;
|
||||
|
||||
.share_btn {
|
||||
width: 100%;
|
||||
height: 88rpx;
|
||||
line-height: 88rpx;
|
||||
background: linear-gradient(135deg, #9553FF 0%, #7934F6 100%);
|
||||
border-radius: 44rpx;
|
||||
color: #FFFFFF;
|
||||
font-weight: bold;
|
||||
font-size: 32rpx;
|
||||
border: none;
|
||||
outline: none;
|
||||
text-align: center;
|
||||
|
||||
&:active {
|
||||
opacity: 0.9;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user